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 switch (left->getType()) {
148 case SGPropertyNode::BOOL: {
149 bool v1 = left->getBoolValue();
150 bool v2 = right->getBoolValue();
152 return SGComparisonCondition::LESS_THAN;
154 return SGComparisonCondition::GREATER_THAN;
156 return SGComparisonCondition::EQUALS;
159 case SGPropertyNode::INT: {
160 int v1 = left->getIntValue();
161 int v2 = right->getIntValue();
163 return SGComparisonCondition::LESS_THAN;
165 return SGComparisonCondition::GREATER_THAN;
167 return SGComparisonCondition::EQUALS;
170 case SGPropertyNode::LONG: {
171 long v1 = left->getLongValue();
172 long v2 = right->getLongValue();
174 return SGComparisonCondition::LESS_THAN;
176 return SGComparisonCondition::GREATER_THAN;
178 return SGComparisonCondition::EQUALS;
181 case SGPropertyNode::FLOAT: {
182 float v1 = left->getFloatValue();
183 float v2 = right->getFloatValue();
185 return SGComparisonCondition::LESS_THAN;
187 return SGComparisonCondition::GREATER_THAN;
189 return SGComparisonCondition::EQUALS;
192 case SGPropertyNode::DOUBLE: {
193 double v1 = left->getDoubleValue();
194 double v2 = right->getDoubleValue();
196 return SGComparisonCondition::LESS_THAN;
198 return SGComparisonCondition::GREATER_THAN;
200 return SGComparisonCondition::EQUALS;
203 case SGPropertyNode::STRING:
204 case SGPropertyNode::NONE:
205 case SGPropertyNode::UNSPECIFIED: {
206 string v1 = left->getStringValue();
207 string v2 = right->getStringValue();
209 return SGComparisonCondition::LESS_THAN;
211 return SGComparisonCondition::GREATER_THAN;
213 return SGComparisonCondition::EQUALS;
217 throw sg_exception("condition: unrecognized node type in comparison");
224 SGComparisonCondition::SGComparisonCondition (Type type, bool reverse)
233 SGComparisonCondition::~SGComparisonCondition ()
238 SGComparisonCondition::test () const
240 // Always fail if incompletely specified
241 if (_left_property == 0 ||
242 (_right_property == 0 && _right_value == 0))
245 // Get LESS_THAN, EQUALS, or GREATER_THAN
247 doComparison(_left_property,
248 (_right_property != 0 ? _right_property : _right_value));
250 return (cmp == _type);
252 return (cmp != _type);
256 SGComparisonCondition::setLeftProperty( SGPropertyNode *prop_root,
257 const char * propname )
259 _left_property = prop_root->getNode(propname, true);
263 SGComparisonCondition::setRightProperty( SGPropertyNode *prop_root,
264 const char * propname )
267 _right_property = prop_root->getNode(propname, true);
271 SGComparisonCondition::setRightValue (const SGPropertyNode *node)
274 _right_value = new SGPropertyNode(*node);
279 ////////////////////////////////////////////////////////////////////////
280 // Read a condition and use it if necessary.
281 ////////////////////////////////////////////////////////////////////////
283 // Forward declaration
284 static SGCondition * readCondition( SGPropertyNode *prop_root,
285 const SGPropertyNode *node );
288 readPropertyCondition( SGPropertyNode *prop_root,
289 const SGPropertyNode *node )
291 return new SGPropertyCondition( prop_root, node->getStringValue() );
295 readNotCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
297 int nChildren = node->nChildren();
298 for (int i = 0; i < nChildren; i++) {
299 const SGPropertyNode * child = node->getChild(i);
300 SGCondition * condition = readCondition(prop_root, child);
302 return new SGNotCondition(condition);
304 SG_LOG(SG_COCKPIT, SG_ALERT, "empty 'not' condition");
309 readAndConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
311 SGAndCondition * andCondition = new SGAndCondition;
312 int nChildren = node->nChildren();
313 for (int i = 0; i < nChildren; i++) {
314 const SGPropertyNode * child = node->getChild(i);
315 SGCondition * condition = readCondition(prop_root, child);
317 andCondition->addCondition(condition);
323 readOrConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
325 SGOrCondition * orCondition = new SGOrCondition;
326 int nChildren = node->nChildren();
327 for (int i = 0; i < nChildren; i++) {
328 const SGPropertyNode * child = node->getChild(i);
329 SGCondition * condition = readCondition(prop_root, child);
331 orCondition->addCondition(condition);
337 readComparison( SGPropertyNode *prop_root,
338 const SGPropertyNode *node,
339 SGComparisonCondition::Type type,
342 SGComparisonCondition * condition = new SGComparisonCondition(type, reverse);
343 condition->setLeftProperty(prop_root, node->getStringValue("property[0]"));
344 if (node->hasValue("property[1]"))
345 condition->setRightProperty(prop_root, node->getStringValue("property[1]"));
346 else if (node->hasValue("value"))
347 condition->setRightValue(node->getChild("value", 0));
349 throw sg_exception("condition: comparison without property[1] or value");
355 readCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
357 const string &name = node->getName();
358 if (name == "property")
359 return readPropertyCondition(prop_root, node);
360 else if (name == "not")
361 return readNotCondition(prop_root, node);
362 else if (name == "and")
363 return readAndConditions(prop_root, node);
364 else if (name == "or")
365 return readOrConditions(prop_root, node);
366 else if (name == "less-than")
367 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
369 else if (name == "less-than-equals")
370 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
372 else if (name == "greater-than")
373 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
375 else if (name == "greater-than-equals")
376 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
378 else if (name == "equals")
379 return readComparison(prop_root, node, SGComparisonCondition::EQUALS,
381 else if (name == "not-equals")
382 return readComparison(prop_root, node, SGComparisonCondition::EQUALS, true);
389 ////////////////////////////////////////////////////////////////////////
390 // Implementation of SGConditional.
391 ////////////////////////////////////////////////////////////////////////
393 SGConditional::SGConditional ()
398 SGConditional::~SGConditional ()
403 SGConditional::setCondition (SGCondition * condition)
405 _condition = condition;
409 SGConditional::test () const
411 return ((_condition == 0) || _condition->test());
416 // The top-level is always an implicit 'and' group
418 sgReadCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
420 return readAndConditions(prop_root, node);
424 // end of condition.cxx