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 ()
241 SGComparisonCondition::test () const
243 // Always fail if incompletely specified
244 if (_left_property == 0 ||
245 (_right_property == 0 && _right_value == 0))
248 // Get LESS_THAN, EQUALS, or GREATER_THAN
250 doComparison(_left_property,
251 (_right_property != 0 ? _right_property : _right_value));
253 return (cmp == _type);
255 return (cmp != _type);
259 SGComparisonCondition::setLeftProperty( SGPropertyNode *prop_root,
260 const char * propname )
262 _left_property = prop_root->getNode(propname, true);
266 SGComparisonCondition::setRightProperty( SGPropertyNode *prop_root,
267 const char * propname )
270 _right_property = prop_root->getNode(propname, true);
274 SGComparisonCondition::setRightValue (const SGPropertyNode *node)
277 _right_value = new SGPropertyNode(*node);
282 ////////////////////////////////////////////////////////////////////////
283 // Read a condition and use it if necessary.
284 ////////////////////////////////////////////////////////////////////////
286 // Forward declaration
287 static SGCondition * readCondition( SGPropertyNode *prop_root,
288 const SGPropertyNode *node );
291 readPropertyCondition( SGPropertyNode *prop_root,
292 const SGPropertyNode *node )
294 return new SGPropertyCondition( prop_root, node->getStringValue() );
298 readNotCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
300 int nChildren = node->nChildren();
301 for (int i = 0; i < nChildren; i++) {
302 const SGPropertyNode * child = node->getChild(i);
303 SGCondition * condition = readCondition(prop_root, child);
305 return new SGNotCondition(condition);
307 SG_LOG(SG_COCKPIT, SG_ALERT, "Panel: empty 'not' condition");
312 readAndConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
314 SGAndCondition * andCondition = new SGAndCondition;
315 int nChildren = node->nChildren();
316 for (int i = 0; i < nChildren; i++) {
317 const SGPropertyNode * child = node->getChild(i);
318 SGCondition * condition = readCondition(prop_root, child);
320 andCondition->addCondition(condition);
326 readOrConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
328 SGOrCondition * orCondition = new SGOrCondition;
329 int nChildren = node->nChildren();
330 for (int i = 0; i < nChildren; i++) {
331 const SGPropertyNode * child = node->getChild(i);
332 SGCondition * condition = readCondition(prop_root, child);
334 orCondition->addCondition(condition);
340 readComparison( SGPropertyNode *prop_root,
341 const SGPropertyNode *node,
342 SGComparisonCondition::Type type,
345 SGComparisonCondition * condition = new SGComparisonCondition(type, reverse);
346 condition->setLeftProperty(prop_root, node->getStringValue("property[0]"));
347 if (node->hasValue("property[1]"))
348 condition->setRightProperty(prop_root, node->getStringValue("property[1]"));
350 condition->setRightValue(node->getChild("value", 0));
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 ()
405 SGConditional::setCondition (SGCondition * condition)
408 _condition = condition;
412 SGConditional::test () const
414 return ((_condition == 0) || _condition->test());
419 // The top-level is always an implicit 'and' group
421 sgReadCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
423 return readAndConditions(prop_root, node);
427 // end of condition.cxx