SeExpr
ControlSpec.cpp
Go to the documentation of this file.
1/*
2 Copyright Disney Enterprises, Inc. All rights reserved.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License
6 and the following modification to it: Section 6 Trademarks.
7 deleted and replaced with:
8
9 6. Trademarks. This License does not grant permission to use the
10 trade names, trademarks, service marks, or product names of the
11 Licensor and its affiliates, except as required for reproducing
12 the content of the NOTICE file.
13
14 You may obtain a copy of the License at
15 http://www.apache.org/licenses/LICENSE-2.0
16*/
17
18#ifndef MAKEDEPEND
19#include <string.h>
20#include <string>
21#include <vector>
22#endif
23
24#include <sstream>
25
26#include <SeExpr2/ExprNode.h>
28#include "ControlSpec.h"
29
30namespace SeExpr2 {
31
33 std::vector<const ControlSpec*>::iterator i = _specList.begin();
34 std::vector<const ControlSpec*>::iterator const e = _specList.end();
35 for (; i != e; ++i) delete *i;
36};
37
38bool SpecExaminer::examine(const ExprNode* examinee) {
39 if (const ExprScalarAssignSpec* s_spec = ExprScalarAssignSpec::match(examinee)) {
40 _specList.push_back(s_spec);
41 return false;
42 } else if (const ExprVectorAssignSpec* v_spec = ExprVectorAssignSpec::match(examinee)) {
43 _specList.push_back(v_spec);
44 return false;
45 } else if (const ExprCurveAssignSpec<double>* c_spec = ExprCurveAssignSpec<double>::match(examinee)) {
46 _specList.push_back(c_spec);
47 return false;
48 } else if (const ExprCurveAssignSpec<Vec3d>* cc_spec = ExprCurveAssignSpec<Vec3d>::match(examinee)) {
49 _specList.push_back(cc_spec);
50 return false;
51 } else if (const ExprStrSpec* str_spec = ExprStrSpec::match(examinee)) {
52 _specList.push_back(str_spec);
53 return false;
54 };
55
56 return true;
57};
58
59inline std::vector<const ControlSpec*>::const_iterator SpecExaminer::begin() const {
60 return _specList.begin();
61};
62
63inline std::vector<const ControlSpec*>::const_iterator const SpecExaminer::end() const {
64 return _specList.end();
65};
66
68inline bool isWS(const char* source, int start, int end) {
69 for (int i = start; i < end; ++i)
70 if (source[i] != '\n') return false;
71 return true;
72};
73
75inline std::string findComment(const ExprNode& node) {
76 const Expression& expr = *node.expr();
77 typedef std::vector<std::pair<int, int> > Comments;
78 const Comments& comments = expr.getComments();
79 const std::string& s = expr.getExpr();
80
81 // TODO: user lower_bound to make this O(lg n) instead of O(n)
82 for (Comments::const_iterator i = comments.begin(); i != comments.end(); ++i) {
83 if (i->first >= node.endPos() && isWS(s.c_str(), node.endPos(), i->first))
84 return s.substr(i->first, i->second - i->first + 1);
85 }
86 return "";
87}
88
90 : ControlSpec(node), _min(0), _max(1), _val(static_cast<const ExprNumNode*>(node.child(0))->value()) {
91 _name = node.name();
92 std::string comment = findComment(node);
93 // TODO: handle integer case
94 int numParsed = sscanf(comment.c_str(), "#%lf,%lf\n", &_min, &_max);
95 if (numParsed != 2) {
96 _min = 0;
97 _max = 1;
98 }
99}
100
102 std::stringstream ss;
103
104 ss << _name << ": " << value() << " in [" << _min << "," << _max << "]" << std::endl;
105
106 return ss.str();
107}
108
110 if (const ExprAssignNode* assign = isScalarAssign(node)) return new ExprScalarAssignSpec(*assign);
111
112 return 0;
113}
114
116 : ControlSpec(node), _min(0), _max(1),
117 _val(Vec3d(static_cast<const ExprNumNode*>(node.child(0)->child(0))->value(),
118 static_cast<const ExprNumNode*>(node.child(0)->child(1))->value(),
119 static_cast<const ExprNumNode*>(node.child(0)->child(2))->value())) {
120 _name = node.name();
121 std::string comment = findComment(node);
122 int numParsed = sscanf(comment.c_str(), "#%lf,%lf\n", &_min, &_max);
123 if (numParsed != 2) {
124 _min = 0;
125 _max = 1;
126 }
127}
128
130 std::stringstream ss;
131
132 ss << _name << ": " << value() << " in [" << _min << "," << _max << "]" << std::endl;
133 ;
134
135 return ss.str();
136}
137
138template <class T>
140 : ControlSpec(node), _vec() {
141 _name = node.name();
142 const ExprFuncNode* cnode = static_cast<const ExprFuncNode*>(node.child(0));
143 _lookupText = cnode->child(0)->toString();
144 int num = cnode->numChildren();
145 for (int i = 1; i < num - 2; i += 3)
146 _vec.push_back(typename Curve<T>::CV(
147 static_cast<const ExprNumNode*>(cnode->child(i))->value(),
148 static_cast<const ExprNumNode*>(cnode->child(i + 1))->value(),
149 (typename Curve<T>::InterpType) static_cast<const ExprNumNode*>(cnode->child(i + 2))->value()));
150}
151
153 if (const ExprAssignNode* assign = isVectorAssign(node)) {
154 return new ExprVectorAssignSpec(*assign);
155 }
156
157 return 0;
158}
159
160template <class T>
162 std::stringstream ss;
163
164 ss << _name << ": "
165 << "curve(" << _lookupText;
166 int num = _vec.size();
167 for (int i = 0; i < num; ++i) ss << _vec[i]._pos << _vec[i]._val << (int)_vec[i]._interp;
168 ss << ");";
169
170 return ss.str();
171}
172
173template <class T>
175 if (const ExprAssignNode* assign = isCurveAssign(node)) return new ExprCurveAssignSpec(*assign);
176
177 return 0;
178}
179
180#if 0
181
182ExprCcurveAssignSpec::
183ExprCcurveAssignSpec(const ExprAssignNode& node)
184 : ControlSpec(node),
185 _vec()
186{
187 _name=node.name();
188 const ExprFuncNode* cnode(static_cast<const ExprFuncNode*>(node.child(0)));
189 _lookupText=cnode->child(0)->toString();
190 int num = cnode->numChildren();
191 for(int i = 1; i < num - 2; i += 3)
192 if(dynamic_cast<const ExprNumNode*>(cnode->child(i+1)))
193 _vec.push_back(Curve<Vec3d>::CV(
194 static_cast<const ExprNumNode*>(cnode->child(i))->value(),
195 static_cast<const ExprNumNode*>(cnode->child(i+1))->value(),
196 (Curve<Vec3d>::InterpType) static_cast<const ExprNumNode*>(cnode->child(i+2))->value()));
197}
198
199std::string
200ExprCcurveAssignSpec::toString() const
201{
202 std::stringstream ss;
203
204 ss << _name
205 << " = "
206 << "ccurve("
207 << _lookupText;
208 int num = _vec.size();
209 for(int i = 0; i < num; ++i)
210 ss << ", "
211 << _vec[i]._pos
212 << ", "
213 << _vec[i]._val
214 << ", "
215 << (int)_vec[i]._interp;
216 ss << ");";
217
218 return ss.str();
219}
220
221const ExprCcurveAssignSpec*
222ExprCcurveAssignSpec::match(const ExprNode* node)
223{
224 if(const ExprAssignNode* assign = isCcurveAssign(node))
225 return new ExprCcurveAssignSpec(*assign);
226
227
228 return 0;
229}
230
231#endif
232
233std::string ExprStrSpec::toString() const {
234 std::stringstream ss;
235 ss << _name << ": \"" + _str + "\" ";
236 switch (_type) {
237 case STRING:
238 ss << "STRING";
239 break;
240 case FILE:
241 ss << "FILE";
242 break;
243 case DIRECTORY:
244 ss << "DIRECTORY";
245 break;
246 default:
247 ss << "INVALID";
248 break;
249 }
250 return ss.str();
251}
252
254 if (const ExprStrNode* strnode = isString(node)) {
255 std::string comment = findComment(*node);
256 char* name = new char[comment.length() + 1];
257 char* type = new char[comment.length() + 1];
258 int numMatched = sscanf(comment.c_str(), "#%s %s\n", type, name);
259
260 Type newType;
261 if (numMatched == 2) {
262 bool valid = true;
263 if (!strcmp(type, "string"))
264 newType = STRING;
265 else if (!strcmp(type, "file"))
266 newType = FILE;
267 else if (!strcmp(type, "directory"))
268 newType = DIRECTORY;
269 else
270 valid = false;
271 if (valid) return new ExprStrSpec(*strnode, name, newType);
272 }
273 delete[] name;
274 delete[] type;
275 }
276 return 0;
277}
278}
Generic Expression control specification.
Definition: ControlSpec.h:35
std::string _name
Name of control.
Definition: ControlSpec.h:45
InterpType
Supported interpolation types.
Definition: Curve.h:43
Node that compute a local variable assignment.
Definition: ExprNode.h:355
const std::string & name() const
Definition: ExprNode.h:365
Curve assignment expression. Assignment of curve to a variable.
Definition: ControlSpec.h:88
ExprCurveAssignSpec(const ExprAssignNode &node)
std::string _lookupText
Lookup subexpression text.
Definition: ControlSpec.h:97
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
static const ExprCurveAssignSpec * match(const ExprNode *node)
std::vector< typename Curve< T >::CV > _vec
Control points of curve spline.
Definition: ControlSpec.h:99
Node that calls a function.
Definition: ExprNode.h:517
short int endPos() const
Access end position in input string.
Definition: ExprNode.h:159
int numChildren() const
Number of children.
Definition: ExprNode.h:114
const Expression * expr() const
Access expression.
Definition: ExprNode.h:102
const ExprNode * child(size_t i) const
Get 0 indexed child.
Definition: ExprNode.h:117
std::string toString() const
Access to original string representation of current expression.
Definition: ExprNode.h:105
Node that stores a numeric constant.
Definition: ExprNode.h:486
double value() const
Definition: ExprNode.h:493
Variable equals scalar control specification.
Definition: ControlSpec.h:53
ExprScalarAssignSpec(const ExprAssignNode &node)
Definition: ControlSpec.cpp:89
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
double _min
Range of values.
Definition: ControlSpec.h:64
static const ExprScalarAssignSpec * match(const ExprNode *node)
Node that stores a string.
Definition: ExprNode.h:502
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
static const ExprStrSpec * match(const ExprNode *node)
Variable equals vector control specification.
Definition: ControlSpec.h:70
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
double _min
Range of values.
Definition: ControlSpec.h:81
const Vec3d & value() const
Definition: ControlSpec.h:74
static const ExprVectorAssignSpec * match(const ExprNode *node)
ExprVectorAssignSpec(const ExprAssignNode &node)
main expression class
Definition: Expression.h:76
std::vector< const ControlSpec * > _specList
Definition: ControlSpec.h:143
std::vector< constControlSpec * >::const_iterator const end() const
Definition: ControlSpec.cpp:63
std::vector< constControlSpec * >::const_iterator begin() const
Definition: ControlSpec.cpp:59
virtual bool examine(const ExprNode *examinee)
Definition: ControlSpec.cpp:38
const ExprStrNode * isString(const ExprNode *testee)
Definition: ExprPatterns.h:44
std::string findComment(const ExprNode &node)
Checks if there is whitespace in the range specified in the string.
Definition: ControlSpec.cpp:75
const ExprAssignNode * isVectorAssign(const ExprNode *testee)
Definition: ExprPatterns.h:122
const ExprAssignNode * isCcurveAssign(const ExprNode *testee)
Definition: ExprPatterns.h:146
const ExprAssignNode * isScalarAssign(const ExprNode *testee)
Definition: ExprPatterns.h:114
const ExprAssignNode * isCurveAssign(const ExprNode *testee)
Definition: ExprPatterns.h:138
bool isWS(const char *source, int start, int end)
Returns true if no newline separates comment and node.
Definition: ControlSpec.cpp:68
</pre >< h3 > Binding our variable reference</h3 > If we now tried to use the variable would still not be found by our expressions To make it bindable we need to override the resolveVar() function as follows</pre >< h3 > Variable setting</h3 > Next we need to make a way of setting the variable As the controlling code will use the expression it will repeatedly alternate between setting the independent variables that are used and calling evaluate(). What it has to do depends very much on the application. In this case we only need to set the independent variable x as</pre >< h2 > Evaluating expressions</h2 > Evaluating an expression is pretty easy But before we can do that we need to make an instance< pre > GrapherExpr expr("x+x^2")
When x is within< i > range</i > of source
Definition: userdoc.txt:111
For any rgb or hsl value(except for negative s values)