1 // condition.cxx - Declarations and inline methods for property conditions.
3 // Written by David Megginson, started 2000.
4 // CLO May 2003 - Split out condition specific code.
6 // This file is in the Public Domain, and comes with no warranty.
11 # include <simgear/compiler.h>
14 // #include <iostream>
16 #include <simgear/structure/exception.hxx>
19 #include "condition.hxx"
27 ////////////////////////////////////////////////////////////////////////
28 // Implementation of SGCondition.
29 ////////////////////////////////////////////////////////////////////////
31 SGCondition::SGCondition ()
35 SGCondition::~SGCondition ()
41 ////////////////////////////////////////////////////////////////////////
42 // Implementation of SGPropertyCondition.
43 ////////////////////////////////////////////////////////////////////////
45 SGPropertyCondition::SGPropertyCondition ( SGPropertyNode *prop_root,
46 const char *propname )
47 : _node( prop_root->getNode(propname, true) )
51 SGPropertyCondition::~SGPropertyCondition ()
57 ////////////////////////////////////////////////////////////////////////
58 // Implementation of SGNotCondition.
59 ////////////////////////////////////////////////////////////////////////
61 SGNotCondition::SGNotCondition (SGCondition * condition)
62 : _condition(condition)
66 SGNotCondition::~SGNotCondition ()
71 SGNotCondition::test () const
73 return !(_condition->test());
78 ////////////////////////////////////////////////////////////////////////
79 // Implementation of SGAndCondition.
80 ////////////////////////////////////////////////////////////////////////
82 SGAndCondition::SGAndCondition ()
86 SGAndCondition::~SGAndCondition ()
91 SGAndCondition::test () const
93 int nConditions = _conditions.size();
94 for (int i = 0; i < nConditions; i++) {
95 if (!_conditions[i]->test())
102 SGAndCondition::addCondition (SGCondition * condition)
104 _conditions.push_back(condition);
109 ////////////////////////////////////////////////////////////////////////
110 // Implementation of SGOrCondition.
111 ////////////////////////////////////////////////////////////////////////
113 SGOrCondition::SGOrCondition ()
117 SGOrCondition::~SGOrCondition ()
122 SGOrCondition::test () const
124 int nConditions = _conditions.size();
125 for (int i = 0; i < nConditions; i++) {
126 if (_conditions[i]->test())
133 SGOrCondition::addCondition (SGCondition * condition)
135 _conditions.push_back(condition);
140 ////////////////////////////////////////////////////////////////////////
141 // Implementation of SGComparisonCondition.
142 ////////////////////////////////////////////////////////////////////////
145 doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
147 using namespace simgear::props;
148 switch (left->getType()) {
150 bool v1 = left->getBoolValue();
151 bool v2 = right->getBoolValue();
153 return SGComparisonCondition::LESS_THAN;
155 return SGComparisonCondition::GREATER_THAN;
157 return SGComparisonCondition::EQUALS;
161 int v1 = left->getIntValue();
162 int v2 = right->getIntValue();
164 return SGComparisonCondition::LESS_THAN;
166 return SGComparisonCondition::GREATER_THAN;
168 return SGComparisonCondition::EQUALS;
172 long v1 = left->getLongValue();
173 long v2 = right->getLongValue();
175 return SGComparisonCondition::LESS_THAN;
177 return SGComparisonCondition::GREATER_THAN;
179 return SGComparisonCondition::EQUALS;
183 float v1 = left->getFloatValue();
184 float v2 = right->getFloatValue();
186 return SGComparisonCondition::LESS_THAN;
188 return SGComparisonCondition::GREATER_THAN;
190 return SGComparisonCondition::EQUALS;
194 double v1 = left->getDoubleValue();
195 double v2 = right->getDoubleValue();
197 return SGComparisonCondition::LESS_THAN;
199 return SGComparisonCondition::GREATER_THAN;
201 return SGComparisonCondition::EQUALS;
207 string v1 = left->getStringValue();
208 string v2 = right->getStringValue();
210 return SGComparisonCondition::LESS_THAN;
212 return SGComparisonCondition::GREATER_THAN;
214 return SGComparisonCondition::EQUALS;
218 throw sg_exception("condition: unrecognized node type in comparison");
225 SGComparisonCondition::SGComparisonCondition (Type type, bool reverse)
234 SGComparisonCondition::~SGComparisonCondition ()
239 SGComparisonCondition::test () const
241 // Always fail if incompletely specified
242 if (_left_property == 0 ||
243 (_right_property == 0 && _right_value == 0))
246 // Get LESS_THAN, EQUALS, or GREATER_THAN
248 doComparison(_left_property,
249 (_right_property != 0 ? _right_property : _right_value));
251 return (cmp == _type);
253 return (cmp != _type);
257 SGComparisonCondition::setLeftProperty( SGPropertyNode *prop_root,
258 const char * propname )
260 _left_property = prop_root->getNode(propname, true);
264 SGComparisonCondition::setRightProperty( SGPropertyNode *prop_root,
265 const char * propname )
268 _right_property = prop_root->getNode(propname, true);
272 SGComparisonCondition::setRightValue (const SGPropertyNode *node)
275 _right_value = new SGPropertyNode(*node);
280 ////////////////////////////////////////////////////////////////////////
281 // Read a condition and use it if necessary.
282 ////////////////////////////////////////////////////////////////////////
284 // Forward declaration
285 static SGCondition * readCondition( SGPropertyNode *prop_root,
286 const SGPropertyNode *node );
289 readPropertyCondition( SGPropertyNode *prop_root,
290 const SGPropertyNode *node )
292 return new SGPropertyCondition( prop_root, node->getStringValue() );
296 readNotCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
298 int nChildren = node->nChildren();
299 for (int i = 0; i < nChildren; i++) {
300 const SGPropertyNode * child = node->getChild(i);
301 SGCondition * condition = readCondition(prop_root, child);
303 return new SGNotCondition(condition);
305 SG_LOG(SG_COCKPIT, SG_ALERT, "empty 'not' condition");
310 readAndConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
312 SGAndCondition * andCondition = new SGAndCondition;
313 int nChildren = node->nChildren();
314 for (int i = 0; i < nChildren; i++) {
315 const SGPropertyNode * child = node->getChild(i);
316 SGCondition * condition = readCondition(prop_root, child);
318 andCondition->addCondition(condition);
324 readOrConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
326 SGOrCondition * orCondition = new SGOrCondition;
327 int nChildren = node->nChildren();
328 for (int i = 0; i < nChildren; i++) {
329 const SGPropertyNode * child = node->getChild(i);
330 SGCondition * condition = readCondition(prop_root, child);
332 orCondition->addCondition(condition);
338 readComparison( SGPropertyNode *prop_root,
339 const SGPropertyNode *node,
340 SGComparisonCondition::Type type,
343 SGComparisonCondition * condition = new SGComparisonCondition(type, reverse);
344 condition->setLeftProperty(prop_root, node->getStringValue("property[0]"));
345 if (node->hasValue("property[1]"))
346 condition->setRightProperty(prop_root, node->getStringValue("property[1]"));
347 else if (node->hasValue("value"))
348 condition->setRightValue(node->getChild("value", 0));
350 throw sg_exception("condition: comparison without property[1] or value");
356 readCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
358 const string &name = node->getName();
359 if (name == "property")
360 return readPropertyCondition(prop_root, node);
361 else if (name == "not")
362 return readNotCondition(prop_root, node);
363 else if (name == "and")
364 return readAndConditions(prop_root, node);
365 else if (name == "or")
366 return readOrConditions(prop_root, node);
367 else if (name == "less-than")
368 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
370 else if (name == "less-than-equals")
371 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
373 else if (name == "greater-than")
374 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
376 else if (name == "greater-than-equals")
377 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
379 else if (name == "equals")
380 return readComparison(prop_root, node, SGComparisonCondition::EQUALS,
382 else if (name == "not-equals")
383 return readComparison(prop_root, node, SGComparisonCondition::EQUALS, true);
390 ////////////////////////////////////////////////////////////////////////
391 // Implementation of SGConditional.
392 ////////////////////////////////////////////////////////////////////////
394 SGConditional::SGConditional ()
399 SGConditional::~SGConditional ()
404 SGConditional::setCondition (SGCondition * condition)
406 _condition = condition;
410 SGConditional::test () const
412 return ((_condition == 0) || _condition->test());
417 // The top-level is always an implicit 'and' group
419 sgReadCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
421 return readAndConditions(prop_root, node);
425 // end of condition.cxx