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
22namespace State
23{
24using BinaryOperator = ossia::expressions::binary_operator;
25
26enum class UnaryOperator
27{
28 Not
29};
30
31struct SCORE_LIB_STATE_EXPORT ExprData
32 : public score::VariantBasedNode<Relation, Pulse, BinaryOperator, UnaryOperator>
33{
34 // SCORE_SERIALIZE_FRIENDS
35
36 ExprData() = default;
37 ExprData(const ExprData&) = default;
38 ExprData(ExprData&&) = default;
39 ExprData& operator=(const ExprData&) = default;
40 ExprData& operator=(ExprData&&) = default;
41 ExprData(Relation data)
42 : VariantBasedNode{std::move(data)}
43 {
44 }
45
46 ExprData(Pulse data)
47 : VariantBasedNode{std::move(data)}
48 {
49 }
50
51 ExprData(BinaryOperator data)
52 : VariantBasedNode{std::move(data)}
53 {
54 }
55
56 ExprData(UnaryOperator data)
57 : VariantBasedNode{std::move(data)}
58 {
59 }
60
62 : VariantBasedNode{std::move(data)}
63 {
64 }
65
66 friend bool operator==(const ExprData& lhs, const ExprData& rhs)
67 {
68 return lhs.m_data == rhs.m_data;
69 }
70
71 QString toString() const;
72};
73}
74
84template <>
85class SCORE_LIB_STATE_EXPORT TreeNode<State::ExprData> final : public State::ExprData
86{
87 // friend struct TSerializer<DataStream, TreeNode<State::ExprData>>;
88 // friend struct TSerializer<JSONObject, void, TreeNode<State::ExprData>>;
89
90 SCORE_LIB_STATE_EXPORT
91 friend bool
92 operator!=(const TreeNode<State::ExprData>& lhs, const TreeNode<State::ExprData>& rhs);
93
94 SCORE_LIB_STATE_EXPORT
95 friend bool
96 operator==(const TreeNode<State::ExprData>& lhs, const TreeNode<State::ExprData>& rhs);
97
98public:
99 QString toString() const;
100 QString toPrettyString() const;
101
102 using iterator = typename std::list<TreeNode>::iterator;
103 using const_iterator = typename std::list<TreeNode>::const_iterator;
104
105 iterator begin();
106 const_iterator begin() const;
107 const_iterator cbegin() const;
109
110 iterator end();
111 const_iterator end() const;
112 const_iterator cend() const;
114
115 TreeNode();
116
117 // The parent has to be set afterwards.
122
123 TreeNode(State::ExprData data, TreeNode* parent)
124 : State::ExprData(std::move(data))
125 {
126 setParent(parent);
127 }
128
129 // Clone
130 explicit TreeNode(TreeNode source, TreeNode* parent);
131 void push_back(const TreeNode& child);
132 void push_back(TreeNode&& child);
133
134 // OPTIMIZEME : the last arg will be this. Is it possible to optimize that ?
135 template <typename... Args>
136 auto& emplace_back(Args&&... args)
137 {
138 m_children.emplace_back(std::forward<Args>(args)...);
139
140 auto& cld = m_children.back();
141 cld.setParent(this);
142 return cld;
143 }
144
145 template <typename... Args>
146 auto& emplace(Args&&... args)
147 {
148 auto& n = *m_children.emplace(std::forward<Args>(args)...);
149 n.setParent(this);
150 return n;
151 }
152
153 TreeNode* parent() const;
154 bool hasChild(std::size_t index) const;
155 TreeNode& childAt(int index);
156 const TreeNode& childAt(int index) const;
157
158 // returns -1 if not found
159 int indexOfChild(const TreeNode* child) const;
160 int childCount() const;
161 bool hasChildren() const;
162
163 std::list<TreeNode>& children();
164 const std::list<TreeNode>& children() const;
165
166 // Won't delete the child!
167 void removeChild(const_iterator it);
168 void setParent(TreeNode* parent);
169
170protected:
171 TreeNode<State::ExprData>* m_parent{};
172 std::list<TreeNode> m_children;
173};
174
175SCORE_LIB_STATE_EXPORT
176bool operator<(const State::ExprData& lhs, const State::ExprData& rhs);
177
178namespace State
179{
180using Expression = TreeNode<ExprData>;
181
182SCORE_LIB_STATE_EXPORT std::optional<State::Expression>
183parseExpression(const QString& str);
184SCORE_LIB_STATE_EXPORT std::optional<State::Expression>
185parseExpression(const std::string& str);
186SCORE_LIB_STATE_EXPORT State::Expression defaultTrueExpression();
187SCORE_LIB_STATE_EXPORT State::Expression defaultFalseExpression();
188
190SCORE_LIB_STATE_EXPORT bool isTrueExpression(const QString&);
191SCORE_LIB_STATE_EXPORT bool isEmptyExpression(const QString&);
192
193SCORE_LIB_STATE_EXPORT
194bool findAddressInExpression(const State::Expression& expr, const State::Address& addr);
195SCORE_LIB_STATE_EXPORT
196void replaceAddress(
197 State::Expression& expr, const State::Address& oldAddr,
198 const State::Address& newAddr);
199}
200
201JSON_METADATA(State::Address, "Address")
202JSON_METADATA(State::AddressAccessor, "AddressAccessor")
203JSON_METADATA(State::Relation, "Relation")
204JSON_METADATA(State::Pulse, "Pulse")
205JSON_METADATA(State::UnaryOperator, "UnOp")
206JSON_METADATA(State::BinaryOperator, "BinOp")
207
208SCORE_SERIALIZE_DATASTREAM_DECLARE(SCORE_LIB_STATE_EXPORT, State::Expression)
209Q_DECLARE_METATYPE(State::Expression)
210W_REGISTER_ARGTYPE(State::Expression)
Definition VisitorInterface.hpp:53
Definition VisitorInterface.hpp:61
Definition TreeNode.hpp:52
The VariantBasedNode class.
Definition VariantBasedNode.hpp:23
Utilities for OSSIA data structures.
Definition DeviceInterface.hpp:33
SCORE_LIB_STATE_EXPORT bool isTrueExpression(const QString &)
True if the expression is "true" (the default case)
Definition Expression.cpp:288
The Address struct.
Definition Address.hpp:58
Definition Expression.hpp:33
Definition Relation.hpp:71
Definition Relation.hpp:19