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/structure/exception.hxx>
19 #include "condition.hxx"
21 SG_USING_STD(istream);
22 SG_USING_STD(ostream);
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 ()
72 SGNotCondition::test () const
74 return !(_condition->test());
79 ////////////////////////////////////////////////////////////////////////
80 // Implementation of SGAndCondition.
81 ////////////////////////////////////////////////////////////////////////
83 SGAndCondition::SGAndCondition ()
87 SGAndCondition::~SGAndCondition ()
89 for (unsigned int i = 0; i < _conditions.size(); i++)
90 delete _conditions[i];
94 SGAndCondition::test () const
96 int nConditions = _conditions.size();
97 for (int i = 0; i < nConditions; i++) {
98 if (!_conditions[i]->test())
105 SGAndCondition::addCondition (SGCondition * condition)
107 _conditions.push_back(condition);
112 ////////////////////////////////////////////////////////////////////////
113 // Implementation of SGOrCondition.
114 ////////////////////////////////////////////////////////////////////////
116 SGOrCondition::SGOrCondition ()
120 SGOrCondition::~SGOrCondition ()
122 for (unsigned int i = 0; i < _conditions.size(); i++)
123 delete _conditions[i];
127 SGOrCondition::test () const
129 int nConditions = _conditions.size();
130 for (int i = 0; i < nConditions; i++) {
131 if (_conditions[i]->test())
138 SGOrCondition::addCondition (SGCondition * condition)
140 _conditions.push_back(condition);
145 ////////////////////////////////////////////////////////////////////////
146 // Implementation of SGComparisonCondition.
147 ////////////////////////////////////////////////////////////////////////
150 doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
152 switch (left->getType()) {
153 case SGPropertyNode::BOOL: {
154 bool v1 = left->getBoolValue();
155 bool v2 = right->getBoolValue();
157 return SGComparisonCondition::LESS_THAN;
159 return SGComparisonCondition::GREATER_THAN;
161 return SGComparisonCondition::EQUALS;
164 case SGPropertyNode::INT: {
165 int v1 = left->getIntValue();
166 int v2 = right->getIntValue();
168 return SGComparisonCondition::LESS_THAN;
170 return SGComparisonCondition::GREATER_THAN;
172 return SGComparisonCondition::EQUALS;
175 case SGPropertyNode::LONG: {
176 long v1 = left->getLongValue();
177 long v2 = right->getLongValue();
179 return SGComparisonCondition::LESS_THAN;
181 return SGComparisonCondition::GREATER_THAN;
183 return SGComparisonCondition::EQUALS;
186 case SGPropertyNode::FLOAT: {
187 float v1 = left->getFloatValue();
188 float v2 = right->getFloatValue();
190 return SGComparisonCondition::LESS_THAN;
192 return SGComparisonCondition::GREATER_THAN;
194 return SGComparisonCondition::EQUALS;
197 case SGPropertyNode::DOUBLE: {
198 double v1 = left->getDoubleValue();
199 double v2 = right->getDoubleValue();
201 return SGComparisonCondition::LESS_THAN;
203 return SGComparisonCondition::GREATER_THAN;
205 return SGComparisonCondition::EQUALS;
208 case SGPropertyNode::STRING:
209 case SGPropertyNode::NONE:
210 case SGPropertyNode::UNSPECIFIED: {
211 string v1 = left->getStringValue();
212 string v2 = right->getStringValue();
214 return SGComparisonCondition::LESS_THAN;
216 return SGComparisonCondition::GREATER_THAN;
218 return SGComparisonCondition::EQUALS;
222 throw sg_exception("Unrecognized node type");
227 SGComparisonCondition::SGComparisonCondition (Type type, bool reverse)
236 SGComparisonCondition::~SGComparisonCondition ()
242 SGComparisonCondition::test () const
244 // Always fail if incompletely specified
245 if (_left_property == 0 ||
246 (_right_property == 0 && _right_value == 0))
249 // Get LESS_THAN, EQUALS, or GREATER_THAN
251 doComparison(_left_property,
252 (_right_property != 0 ? _right_property : _right_value));
254 return (cmp == _type);
256 return (cmp != _type);
260 SGComparisonCondition::setLeftProperty( SGPropertyNode *prop_root,
261 const char * propname )
263 _left_property = prop_root->getNode(propname, true);
267 SGComparisonCondition::setRightProperty( SGPropertyNode *prop_root,
268 const char * propname )
272 _right_property = prop_root->getNode(propname, true);
276 SGComparisonCondition::setRightValue (const SGPropertyNode *node)
280 _right_value = new SGPropertyNode(*node);
285 ////////////////////////////////////////////////////////////////////////
286 // Read a condition and use it if necessary.
287 ////////////////////////////////////////////////////////////////////////
289 // Forward declaration
290 static SGCondition * readCondition( SGPropertyNode *prop_root,
291 const SGPropertyNode *node );
294 readPropertyCondition( SGPropertyNode *prop_root,
295 const SGPropertyNode *node )
297 return new SGPropertyCondition( prop_root, node->getStringValue() );
301 readNotCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
303 int nChildren = node->nChildren();
304 for (int i = 0; i < nChildren; i++) {
305 const SGPropertyNode * child = node->getChild(i);
306 SGCondition * condition = readCondition(prop_root, child);
308 return new SGNotCondition(condition);
310 SG_LOG(SG_COCKPIT, SG_ALERT, "Panel: empty 'not' condition");
315 readAndConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
317 SGAndCondition * andCondition = new SGAndCondition;
318 int nChildren = node->nChildren();
319 for (int i = 0; i < nChildren; i++) {
320 const SGPropertyNode * child = node->getChild(i);
321 SGCondition * condition = readCondition(prop_root, child);
323 andCondition->addCondition(condition);
329 readOrConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
331 SGOrCondition * orCondition = new SGOrCondition;
332 int nChildren = node->nChildren();
333 for (int i = 0; i < nChildren; i++) {
334 const SGPropertyNode * child = node->getChild(i);
335 SGCondition * condition = readCondition(prop_root, child);
337 orCondition->addCondition(condition);
343 readComparison( SGPropertyNode *prop_root,
344 const SGPropertyNode *node,
345 SGComparisonCondition::Type type,
348 SGComparisonCondition * condition = new SGComparisonCondition(type, reverse);
349 condition->setLeftProperty(prop_root, node->getStringValue("property[0]"));
350 if (node->hasValue("property[1]"))
351 condition->setRightProperty(prop_root, node->getStringValue("property[1]"));
353 condition->setRightValue(node->getChild("value", 0));
359 readCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
361 const string &name = node->getName();
362 if (name == "property")
363 return readPropertyCondition(prop_root, node);
364 else if (name == "not")
365 return readNotCondition(prop_root, node);
366 else if (name == "and")
367 return readAndConditions(prop_root, node);
368 else if (name == "or")
369 return readOrConditions(prop_root, node);
370 else if (name == "less-than")
371 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
373 else if (name == "less-than-equals")
374 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
376 else if (name == "greater-than")
377 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
379 else if (name == "greater-than-equals")
380 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
382 else if (name == "equals")
383 return readComparison(prop_root, node, SGComparisonCondition::EQUALS,
385 else if (name == "not-equals")
386 return readComparison(prop_root, node, SGComparisonCondition::EQUALS, true);
393 ////////////////////////////////////////////////////////////////////////
394 // Implementation of SGConditional.
395 ////////////////////////////////////////////////////////////////////////
397 SGConditional::SGConditional ()
402 SGConditional::~SGConditional ()
408 SGConditional::setCondition (SGCondition * condition)
411 _condition = condition;
415 SGConditional::test () const
417 return ((_condition == 0) || _condition->test());
422 // The top-level is always an implicit 'and' group
424 sgReadCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
426 return readAndConditions(prop_root, node);
430 // end of condition.cxx