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 STL_IOSTREAM
16 #include <simgear/misc/exception.hxx>
20 #include "condition.hxx"
22 SG_USING_STD(istream);
23 SG_USING_STD(ostream);
28 ////////////////////////////////////////////////////////////////////////
29 // Implementation of SGCondition.
30 ////////////////////////////////////////////////////////////////////////
32 SGCondition::SGCondition ()
36 SGCondition::~SGCondition ()
42 ////////////////////////////////////////////////////////////////////////
43 // Implementation of SGPropertyCondition.
44 ////////////////////////////////////////////////////////////////////////
46 SGPropertyCondition::SGPropertyCondition ( SGPropertyNode *prop_root,
47 const char *propname )
48 : _node( prop_root->getNode(propname, true) )
52 SGPropertyCondition::~SGPropertyCondition ()
58 ////////////////////////////////////////////////////////////////////////
59 // Implementation of SGNotCondition.
60 ////////////////////////////////////////////////////////////////////////
62 SGNotCondition::SGNotCondition (SGCondition * condition)
63 : _condition(condition)
67 SGNotCondition::~SGNotCondition ()
73 SGNotCondition::test () const
75 return !(_condition->test());
80 ////////////////////////////////////////////////////////////////////////
81 // Implementation of SGAndCondition.
82 ////////////////////////////////////////////////////////////////////////
84 SGAndCondition::SGAndCondition ()
88 SGAndCondition::~SGAndCondition ()
90 for (unsigned int i = 0; i < _conditions.size(); i++)
91 delete _conditions[i];
95 SGAndCondition::test () const
97 int nConditions = _conditions.size();
98 for (int i = 0; i < nConditions; i++) {
99 if (!_conditions[i]->test())
106 SGAndCondition::addCondition (SGCondition * condition)
108 _conditions.push_back(condition);
113 ////////////////////////////////////////////////////////////////////////
114 // Implementation of SGOrCondition.
115 ////////////////////////////////////////////////////////////////////////
117 SGOrCondition::SGOrCondition ()
121 SGOrCondition::~SGOrCondition ()
123 for (unsigned int i = 0; i < _conditions.size(); i++)
124 delete _conditions[i];
128 SGOrCondition::test () const
130 int nConditions = _conditions.size();
131 for (int i = 0; i < nConditions; i++) {
132 if (_conditions[i]->test())
139 SGOrCondition::addCondition (SGCondition * condition)
141 _conditions.push_back(condition);
146 ////////////////////////////////////////////////////////////////////////
147 // Implementation of SGComparisonCondition.
148 ////////////////////////////////////////////////////////////////////////
151 doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
153 switch (left->getType()) {
154 case SGPropertyNode::BOOL: {
155 bool v1 = left->getBoolValue();
156 bool v2 = right->getBoolValue();
158 return SGComparisonCondition::LESS_THAN;
160 return SGComparisonCondition::GREATER_THAN;
162 return SGComparisonCondition::EQUALS;
165 case SGPropertyNode::INT: {
166 int v1 = left->getIntValue();
167 int v2 = right->getIntValue();
169 return SGComparisonCondition::LESS_THAN;
171 return SGComparisonCondition::GREATER_THAN;
173 return SGComparisonCondition::EQUALS;
176 case SGPropertyNode::LONG: {
177 long v1 = left->getLongValue();
178 long v2 = right->getLongValue();
180 return SGComparisonCondition::LESS_THAN;
182 return SGComparisonCondition::GREATER_THAN;
184 return SGComparisonCondition::EQUALS;
187 case SGPropertyNode::FLOAT: {
188 float v1 = left->getFloatValue();
189 float v2 = right->getFloatValue();
191 return SGComparisonCondition::LESS_THAN;
193 return SGComparisonCondition::GREATER_THAN;
195 return SGComparisonCondition::EQUALS;
198 case SGPropertyNode::DOUBLE: {
199 double v1 = left->getDoubleValue();
200 double v2 = right->getDoubleValue();
202 return SGComparisonCondition::LESS_THAN;
204 return SGComparisonCondition::GREATER_THAN;
206 return SGComparisonCondition::EQUALS;
209 case SGPropertyNode::STRING:
210 case SGPropertyNode::NONE:
211 case SGPropertyNode::UNSPECIFIED: {
212 string v1 = left->getStringValue();
213 string v2 = right->getStringValue();
215 return SGComparisonCondition::LESS_THAN;
217 return SGComparisonCondition::GREATER_THAN;
219 return SGComparisonCondition::EQUALS;
223 throw sg_exception("Unrecognized node type");
228 SGComparisonCondition::SGComparisonCondition (Type type, bool reverse)
237 SGComparisonCondition::~SGComparisonCondition ()
243 SGComparisonCondition::test () const
245 // Always fail if incompletely specified
246 if (_left_property == 0 ||
247 (_right_property == 0 && _right_value == 0))
250 // Get LESS_THAN, EQUALS, or GREATER_THAN
252 doComparison(_left_property,
253 (_right_property != 0 ? _right_property : _right_value));
255 return (cmp == _type);
257 return (cmp != _type);
261 SGComparisonCondition::setLeftProperty( SGPropertyNode *prop_root,
262 const char * propname )
264 _left_property = prop_root->getNode(propname, true);
268 SGComparisonCondition::setRightProperty( SGPropertyNode *prop_root,
269 const char * propname )
273 _right_property = prop_root->getNode(propname, true);
277 SGComparisonCondition::setRightValue (const SGPropertyNode *node)
281 _right_value = new SGPropertyNode(*node);
286 ////////////////////////////////////////////////////////////////////////
287 // Read a condition and use it if necessary.
288 ////////////////////////////////////////////////////////////////////////
290 // Forward declaration
291 static SGCondition * readCondition( SGPropertyNode *prop_root,
292 const SGPropertyNode *node );
295 readPropertyCondition( SGPropertyNode *prop_root,
296 const SGPropertyNode *node )
298 return new SGPropertyCondition( prop_root, node->getStringValue() );
302 readNotCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
304 int nChildren = node->nChildren();
305 for (int i = 0; i < nChildren; i++) {
306 const SGPropertyNode * child = node->getChild(i);
307 SGCondition * condition = readCondition(prop_root, child);
309 return new SGNotCondition(condition);
311 SG_LOG(SG_COCKPIT, SG_ALERT, "Panel: empty 'not' condition");
316 readAndConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
318 SGAndCondition * andCondition = new SGAndCondition;
319 int nChildren = node->nChildren();
320 for (int i = 0; i < nChildren; i++) {
321 const SGPropertyNode * child = node->getChild(i);
322 SGCondition * condition = readCondition(prop_root, child);
324 andCondition->addCondition(condition);
330 readOrConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
332 SGOrCondition * orCondition = new SGOrCondition;
333 int nChildren = node->nChildren();
334 for (int i = 0; i < nChildren; i++) {
335 const SGPropertyNode * child = node->getChild(i);
336 SGCondition * condition = readCondition(prop_root, child);
338 orCondition->addCondition(condition);
344 readComparison( SGPropertyNode *prop_root,
345 const SGPropertyNode *node,
346 SGComparisonCondition::Type type,
349 SGComparisonCondition * condition = new SGComparisonCondition(type, reverse);
350 condition->setLeftProperty(prop_root, node->getStringValue("property[0]"));
351 if (node->hasValue("property[1]"))
352 condition->setRightProperty(prop_root, node->getStringValue("property[1]"));
354 condition->setRightValue(node->getChild("value", 0));
360 readCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
362 const string &name = node->getName();
363 if (name == "property")
364 return readPropertyCondition(prop_root, node);
365 else if (name == "not")
366 return readNotCondition(prop_root, node);
367 else if (name == "and")
368 return readAndConditions(prop_root, node);
369 else if (name == "or")
370 return readOrConditions(prop_root, node);
371 else if (name == "less-than")
372 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
374 else if (name == "less-than-equals")
375 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
377 else if (name == "greater-than")
378 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
380 else if (name == "greater-than-equals")
381 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
383 else if (name == "equals")
384 return readComparison(prop_root, node, SGComparisonCondition::EQUALS,
386 else if (name == "not-equals")
387 return readComparison(prop_root, node, SGComparisonCondition::EQUALS, true);
394 ////////////////////////////////////////////////////////////////////////
395 // Implementation of SGConditional.
396 ////////////////////////////////////////////////////////////////////////
398 SGConditional::SGConditional ()
403 SGConditional::~SGConditional ()
409 SGConditional::setCondition (SGCondition * condition)
412 _condition = condition;
416 SGConditional::test () const
418 return ((_condition == 0) || _condition->test());
423 // The top-level is always an implicit 'and' group
425 sgReadCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
427 return readAndConditions(prop_root, node);
431 // end of condition.cxx