KSeExpr 6.0.0.0
ControlSpec.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2// SPDX-License-Identifier: LicenseRef-Apache-2.0
3// SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6#include <KSeExpr/ExprNode.h>
8#include <sstream>
9
10#include "ControlSpec.h"
11#include "Utils.h"
12
13namespace KSeExpr
14{
16{
17 for (auto &i : _specList)
18 delete i;
19}
20
22{
24 _specList.push_back(s_spec);
25 return false;
27 _specList.push_back(v_spec);
28 return false;
30 _specList.push_back(c_spec);
31 return false;
33 _specList.push_back(cc_spec);
34 return false;
35 } else if (const ExprStrSpec *str_spec = ExprStrSpec::match(examinee)) {
36 _specList.push_back(str_spec);
37 return false;
38 };
39
40 return true;
41}
42
43inline std::vector<const ControlSpec *>::const_iterator SpecExaminer::begin() const
44{
45 return _specList.begin();
46}
47
48inline std::vector<const ControlSpec *>::const_iterator SpecExaminer::end() const
49{
50 return _specList.end();
51}
52
54inline bool isWS(const char *source, int start, int end)
55{
56 for (int i = start; i < end; ++i)
57 if (source[i] != '\n')
58 return false;
59 return true;
60}
61
63inline std::string findComment(const ExprNode &node)
64{
65 const Expression &expr = *node.expr();
66 using Comments = std::vector<std::pair<int, int>>;
67 const Comments &comments = expr.getComments();
68 const std::string &s = expr.getExpr();
69
70 // TODO: user lower_bound to make this O(lg n) instead of O(n)
71 for (const auto &i : comments) {
72 if (i.first >= node.endPos() && isWS(s.c_str(), node.endPos(), i.first))
73 return s.substr(i.first, i.second - i.first + 1);
74 }
75 return "";
76}
77
80 , _min(0)
81 , _max(1)
82 , _val(dynamic_cast<const ExprNumNode *>(node.child(0))->value())
83{
84 _name = node.name();
85 std::string comment = findComment(node);
86 if (comment.find('.') != std::string::npos || comment.find('e') != std::string::npos) {
87 float fmin = NAN;
88 float fmax = NAN;
90 _min = fmin;
91 _max = fmax;
92 return;
93 }
94 } else {
95 int32_t imin = 0;
96 int32_t imax = 0;
98 _min = imin;
99 _max = imax;
100 } else {
101 _min = 0;
102 _max = 1;
103 }
104 }
105}
106
108{
109 std::stringstream ss;
110
111 ss << _name << ": " << value() << " in [" << _min << "," << _max << "]" << std::endl;
112
113 return ss.str();
114}
115
117{
119 return new ExprScalarAssignSpec(*assign);
120
121 return nullptr;
122}
123
126 , _min(0)
127 , _max(1)
128 , _val(Vec3d(dynamic_cast<const ExprNumNode *>(node.child(0)->child(0))->value(), dynamic_cast<const ExprNumNode *>(node.child(0)->child(1))->value(), dynamic_cast<const ExprNumNode *>(node.child(0)->child(2))->value()))
129{
130 _name = node.name();
131 std::string comment = findComment(node);
132 if (comment.find('.') != std::string::npos || comment.find('e') != std::string::npos) {
133 float fmin = NAN;
134 float fmax = NAN;
136 _min = fmin;
137 _max = fmax;
138 return;
139 }
140 }
141 _min = 0;
142 _max = 1;
143}
144
146{
147 std::stringstream ss;
148
149 ss << _name << ": " << value() << " in [" << _min << "," << _max << "]" << std::endl;
150 ;
151
152 return ss.str();
153}
154
155template<class T>
158 , _vec()
159{
160 _name = node.name();
161 const auto *cnode = dynamic_cast<const ExprFuncNode *>(node.child(0));
162 _lookupText = cnode->child(0)->toString();
163 int num = cnode->numChildren();
164 for (int i = 1; i < num - 2; i += 3) {
165 // Someone at disney forgot that doubles cannot go straight to enums... -amyspark
166 auto x = static_cast<typename Curve<T>::InterpType>((int)(dynamic_cast<const ExprNumNode *>(cnode->child(i + 2))->value()));
167 _vec.push_back(typename Curve<T>::CV(
168 dynamic_cast<const ExprNumNode *>(cnode->child(i))->value(),
169 dynamic_cast<const ExprNumNode *>(cnode->child(i + 1))->value(),
170 x));
171 }
172}
173
175{
177 return new ExprVectorAssignSpec(*assign);
178 }
179
180 return nullptr;
181}
182
183template<class T> std::string ExprCurveAssignSpec<T>::toString() const
184{
185 std::stringstream ss;
186
187 ss << _name << ": "
188 << "curve(" << _lookupText;
189 int num = _vec.size();
190 for (int i = 0; i < num; ++i)
191 ss << _vec[i]._pos << _vec[i]._val << (int)_vec[i]._interp;
192 ss << ");";
193
194 return ss.str();
195}
196
198{
200 return new ExprCurveAssignSpec(*assign);
201
202 return 0;
203}
204
205#if 0
206
207ExprCcurveAssignSpec::
208ExprCcurveAssignSpec(const ExprAssignNode& node)
209 : ControlSpec(node),
210 _vec()
211{
212 _name=node.name();
213 const ExprFuncNode* cnode(static_cast<const ExprFuncNode*>(node.child(0)));
214 _lookupText=cnode->child(0)->toString();
215 int num = cnode->numChildren();
216 for(int i = 1; i < num - 2; i += 3)
217 if(dynamic_cast<const ExprNumNode*>(cnode->child(i+1)))
218 _vec.push_back(Curve<Vec3d>::CV(
219 static_cast<const ExprNumNode*>(cnode->child(i))->value(),
220 static_cast<const ExprNumNode*>(cnode->child(i+1))->value(),
221 (Curve<Vec3d>::InterpType) static_cast<const ExprNumNode*>(cnode->child(i+2))->value()));
222}
223
224std::string
225ExprCcurveAssignSpec::toString() const
226{
227 std::stringstream ss;
228
229 ss << _name
230 << " = "
231 << "ccurve("
232 << _lookupText;
233 int num = _vec.size();
234 for(int i = 0; i < num; ++i)
235 ss << ", "
236 << _vec[i]._pos
237 << ", "
238 << _vec[i]._val
239 << ", "
240 << (int)_vec[i]._interp;
241 ss << ");";
242
243 return ss.str();
244}
245
246const ExprCcurveAssignSpec*
247ExprCcurveAssignSpec::match(const ExprNode* node)
248{
249 if(const ExprAssignNode* assign = isCcurveAssign(node))
250 return new ExprCcurveAssignSpec(*assign);
251
252
253 return 0;
254}
255
256#endif
257
258std::string ExprStrSpec::toString() const
259{
260 std::stringstream ss;
261 ss << _name << ": \"" + _str + "\" ";
262 switch (_type) {
263 case STRING:
264 ss << "STRING";
265 break;
266 case FILE:
267 ss << "FILE";
268 break;
269 case DIRECTORY:
270 ss << "DIRECTORY";
271 break;
272 default:
273 ss << "INVALID";
274 break;
275 }
276 return ss.str();
277}
278
280{
281 if (const ExprStrNode *strnode = isString(node)) {
282 std::string comment = findComment(*node);
283 std::string name {};
284 std::string type {};
286
287 if (parsed) {
288 if (type == "string")
289 return new ExprStrSpec(*strnode, name.c_str(), STRING);
290 else if (type == "file")
291 return new ExprStrSpec(*strnode, name.c_str(), FILE);
292 else if (type == "directory")
293 return new ExprStrSpec(*strnode, name.c_str(), DIRECTORY);
294 }
295 }
296 return nullptr;
297}
298} // namespace KSeExpr
Generic Expression control specification.
Definition ControlSpec.h:20
std::string _name
Name of control.
Definition ControlSpec.h:36
InterpType
Supported interpolation types.
Definition Curve.h:32
Node that compute a local variable assignment.
Definition ExprNode.h:414
Curve assignment expression. Assignment of curve to a variable.
Definition ControlSpec.h:83
std::string toString() const override
Generates a replacement string based on changes to the spec.
static const ExprCurveAssignSpec * match(const ExprNode *node)
std::string _lookupText
Lookup subexpression text.
Definition ControlSpec.h:91
std::vector< typename Curve< T >::CV > _vec
Control points of curve spline.
Definition ControlSpec.h:93
ExprCurveAssignSpec(const ExprAssignNode &node)
Node that calls a function.
Definition ExprNode.h:654
Node that stores a numeric constant.
Definition ExprNode.h:610
double value() const
Definition ExprNode.h:621
Variable equals scalar control specification.
Definition ControlSpec.h:45
static const ExprScalarAssignSpec * match(const ExprNode *node)
ExprScalarAssignSpec(const ExprAssignNode &node)
double _min
Range of values.
Definition ControlSpec.h:57
std::string toString() const override
Generates a replacement string based on changes to the spec.
Node that stores a string.
Definition ExprNode.h:632
static const ExprStrSpec * match(const ExprNode *node)
std::string toString() const override
Generates a replacement string based on changes to the spec.
Variable equals vector control specification.
Definition ControlSpec.h:64
std::string toString() const override
Generates a replacement string based on changes to the spec.
static const ExprVectorAssignSpec * match(const ExprNode *node)
double _min
Range of values.
Definition ControlSpec.h:76
const Vec3d & value() const
Definition ControlSpec.h:68
ExprVectorAssignSpec(const ExprAssignNode &node)
main expression class
Definition Expression.h:67
const std::string & getExpr() const
Get the string that this expression is currently set to evaluate.
Definition Expression.h:116
const std::vector< std::pair< int, int > > & getComments() const
Definition Expression.h:149
std::vector< constControlSpec * >::const_iterator begin() const
bool examine(const ExprNode *examinee) override
std::vector< constControlSpec * >::const_iterator end() const
std::vector< const ControlSpec * > _specList
Vec()
Empty constructor (this is invalid for a reference type)
Definition Vec.h:57
bool parseRangeComment(const std::string &comment, double &from, double &to)
Definition Utils.cpp:7
bool parseTypeNameComment(const std::string &comment, std::string &type, std::string &name)
Definition Utils.cpp:99
const ExprAssignNode * isVectorAssign(const ExprNode *testee)
bool isWS(const char *source, int start, int end)
Returns true if no newline separates comment and node.
const ExprStrNode * isString(const ExprNode *testee)
const ExprAssignNode * isScalarAssign(const ExprNode *testee)
const ExprAssignNode * isCcurveAssign(const ExprNode *testee)
const ExprAssignNode * isCurveAssign(const ExprNode *testee)
std::string findComment(const ExprNode &node)
Checks if there is whitespace in the range specified in the string.