Loading...
Searching...
No Matches
Expression.hpp
1#pragma once
2#include <State/Relation.hpp>
3
4#include <score/model/tree/InvisibleRootNode.hpp>
5#include <score/model/tree/TreeNode.hpp>
6#include <score/model/tree/TreeNodeSerialization.hpp>
7#include <score/model/tree/VariantBasedNode.hpp>
8#include <score/tools/std/Optional.hpp>
9
10#include <ossia/editor/expression/operators.hpp>
11
12#include <QString>
13
14#include <cstddef>
15#include <vector>
16
17class DataStream;
18class JSONObject;
19template <typename DataType>
20class TreeNode;
21
22class JSONReader;
23class JSONWriter;
24namespace State
25{
26using BinaryOperator = ossia::expressions::binary_operator;
27
28enum class UnaryOperator
29{
30 Not
31};
32
33struct SCORE_LIB_STATE_EXPORT ExprData
34 : public score::VariantBasedNode<Relation, Pulse, BinaryOperator, UnaryOperator>
35{
36 // SCORE_SERIALIZE_FRIENDS
37
38 ExprData() = default;
39 ExprData(const ExprData&) = default;
40 ExprData(ExprData&&) = default;
41 ExprData& operator=(const ExprData&) = default;
42 ExprData& operator=(ExprData&&) = default;
43 ExprData(Relation data)
44 : VariantBasedNode{std::move(data)}
45 {
46 }
47
48 ExprData(Pulse data)
49 : VariantBasedNode{std::move(data)}
50 {
51 }
52
53 ExprData(BinaryOperator data)
54 : VariantBasedNode{std::move(data)}
55 {
56 }
57
58 ExprData(UnaryOperator data)
59 : VariantBasedNode{std::move(data)}
60 {
61 }
62
64 : VariantBasedNode{std::move(data)}
65 {
66 }
67
68 friend bool operator==(const ExprData& lhs, const ExprData& rhs)
69 {
70 return lhs.m_data == rhs.m_data;
71 }
72
73 QString toString() const;
74};
75}
76
86template <>
87class SCORE_LIB_STATE_EXPORT TreeNode<State::ExprData> final : public State::ExprData
88{
89 // friend struct TSerializer<DataStream, TreeNode<State::ExprData>>;
90 // friend struct TSerializer<JSONObject, void, TreeNode<State::ExprData>>;
91
92 SCORE_LIB_STATE_EXPORT
93 friend bool
94 operator!=(const TreeNode<State::ExprData>& lhs, const TreeNode<State::ExprData>& rhs);
95
96 SCORE_LIB_STATE_EXPORT
97 friend bool
98 operator==(const TreeNode<State::ExprData>& lhs, const TreeNode<State::ExprData>& rhs);
99
100public:
101 QString toString() const;
102 QString toPrettyString() const;
103
104 using iterator = typename std::list<TreeNode>::iterator;
105 using const_iterator = typename std::list<TreeNode>::const_iterator;
106
107 iterator begin();
108 const_iterator begin() const;
109 const_iterator cbegin() const;
111
112 iterator end();
113 const_iterator end() const;
114 const_iterator cend() const;
116
117 TreeNode();
118
119 // The parent has to be set afterwards.
124
125 TreeNode(State::ExprData data, TreeNode* parent)
126 : State::ExprData(std::move(data))
127 {
128 setParent(parent);
129 }
130
131 // Clone
132 explicit TreeNode(TreeNode source, TreeNode* parent);
133 void push_back(const TreeNode& child);
134 void push_back(TreeNode&& child);
135
136 // OPTIMIZEME : the last arg will be this. Is it possible to optimize that ?
137 template <typename... Args>
138 auto& emplace_back(Args&&... args)
139 {
140 m_children.emplace_back(std::forward<Args>(args)...);
141
142 auto& cld = m_children.back();
143 cld.setParent(this);
144 return cld;
145 }
146
147 template <typename... Args>
148 auto& emplace(Args&&... args)
149 {
150 auto& n = *m_children.emplace(std::forward<Args>(args)...);
151 n.setParent(this);
152 return n;
153 }
154
155 TreeNode* parent() const;
156 bool hasChild(std::size_t index) const;
157 TreeNode& childAt(int index);
158 const TreeNode& childAt(int index) const;
159
160 // returns -1 if not found
161 int indexOfChild(const TreeNode* child) const;
162 int childCount() const;
163 bool hasChildren() const;
164
165 std::list<TreeNode>& children();
166 const std::list<TreeNode>& children() const;
167
168 // Won't delete the child!
169 void removeChild(const_iterator it);
170 void setParent(TreeNode* parent);
171
172protected:
173 TreeNode<State::ExprData>* m_parent{};
174 std::list<TreeNode> m_children;
175};
176
177SCORE_LIB_STATE_EXPORT
178bool operator<(const State::ExprData& lhs, const State::ExprData& rhs);
179
180namespace State
181{
182using Expression = TreeNode<ExprData>;
183
184SCORE_LIB_STATE_EXPORT std::optional<State::Expression>
185parseExpression(const QString& str);
186SCORE_LIB_STATE_EXPORT std::optional<State::Expression>
187parseExpression(const std::string& str);
188SCORE_LIB_STATE_EXPORT State::Expression defaultTrueExpression();
189SCORE_LIB_STATE_EXPORT State::Expression defaultFalseExpression();
190
192SCORE_LIB_STATE_EXPORT bool isTrueExpression(const QString&);
193SCORE_LIB_STATE_EXPORT bool isEmptyExpression(const QString&);
194
195SCORE_LIB_STATE_EXPORT
196bool findAddressInExpression(const State::Expression& expr, const State::Address& addr);
197SCORE_LIB_STATE_EXPORT
198void replaceAddress(
199 State::Expression& expr, const State::Address& oldAddr,
200 const State::Address& newAddr);
202SCORE_LIB_STATE_EXPORT std::vector<std::shared_ptr<const Anchor>>
203anchors(const Expression& e);
205SCORE_LIB_STATE_EXPORT void
206setAnchors(Expression& e, const std::vector<std::shared_ptr<const Anchor>>& a);
208SCORE_LIB_STATE_EXPORT bool identical(const Expression& a, const Expression& b);
209
211SCORE_LIB_STATE_EXPORT void
212saveAnchors(JSONReader& r, const char* key, const Expression& e);
213SCORE_LIB_STATE_EXPORT void loadAnchors(JSONWriter& w, const char* key, Expression& e);
214
215}
216
217JSON_METADATA(State::Address, "Address")
218JSON_METADATA(State::AddressAccessor, "AddressAccessor")
219JSON_METADATA(State::Relation, "Relation")
220JSON_METADATA(State::Pulse, "Pulse")
221JSON_METADATA(State::UnaryOperator, "UnOp")
222JSON_METADATA(State::BinaryOperator, "BinOp")
223
224SCORE_SERIALIZE_DATASTREAM_DECLARE(SCORE_LIB_STATE_EXPORT, State::Expression)
225Q_DECLARE_METATYPE(State::Expression)
226W_REGISTER_ARGTYPE(State::Expression)
Definition VisitorInterface.hpp:53
Definition VisitorInterface.hpp:61
Definition JSONVisitor.hpp:52
Definition JSONVisitor.hpp:423
Definition TreeNode.hpp:52
The VariantBasedNode class.
Definition VariantBasedNode.hpp:23
Utilities for OSSIA data structures.
Definition DeviceInterface.hpp:35
SCORE_LIB_STATE_EXPORT bool isTrueExpression(const QString &)
True if the expression is "true" (the default case)
Definition Expression.cpp:288
void saveAnchors(JSONReader &r, const char *key, const Expression &e)
An expression is serialized as a string, which loses its anchors.
Definition AddressSerialization.cpp:271
std::vector< std::shared_ptr< const Anchor > > anchors(const Expression &e)
Anchors of the addresses in order of appearance, null where there is none.
Definition Expression.cpp:526
void setAnchors(Expression &e, const std::vector< std::shared_ptr< const Anchor > > &a)
Inverse of anchors(); extra entries are ignored.
Definition Expression.cpp:534
bool identical(const Expression &a, const Expression &b)
Equal, with the same anchors.
Definition Expression.cpp:544
The Address struct.
Definition Address.hpp:81
Definition Expression.hpp:35
Definition Relation.hpp:71
Definition Relation.hpp:19