00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifdef HAVE_CONFIG_H
00011 # include <simgear/compiler.h>
00012 #endif
00013
00014
00015
00016 #include <simgear/structure/exception.hxx>
00017
00018 #include "props.hxx"
00019 #include "condition.hxx"
00020
00021 SG_USING_STD(istream);
00022 SG_USING_STD(ostream);
00023
00024
00025
00026
00028
00030
00031 SGCondition::SGCondition ()
00032 {
00033 }
00034
00035 SGCondition::~SGCondition ()
00036 {
00037 }
00038
00039
00040
00042
00044
00045 SGPropertyCondition::SGPropertyCondition ( SGPropertyNode *prop_root,
00046 const char *propname )
00047 : _node( prop_root->getNode(propname, true) )
00048 {
00049 }
00050
00051 SGPropertyCondition::~SGPropertyCondition ()
00052 {
00053 }
00054
00055
00056
00058
00060
00061 SGNotCondition::SGNotCondition (SGCondition * condition)
00062 : _condition(condition)
00063 {
00064 }
00065
00066 SGNotCondition::~SGNotCondition ()
00067 {
00068 delete _condition;
00069 }
00070
00071 bool
00072 SGNotCondition::test () const
00073 {
00074 return !(_condition->test());
00075 }
00076
00077
00078
00080
00082
00083 SGAndCondition::SGAndCondition ()
00084 {
00085 }
00086
00087 SGAndCondition::~SGAndCondition ()
00088 {
00089 for (unsigned int i = 0; i < _conditions.size(); i++)
00090 delete _conditions[i];
00091 }
00092
00093 bool
00094 SGAndCondition::test () const
00095 {
00096 int nConditions = _conditions.size();
00097 for (int i = 0; i < nConditions; i++) {
00098 if (!_conditions[i]->test())
00099 return false;
00100 }
00101 return true;
00102 }
00103
00104 void
00105 SGAndCondition::addCondition (SGCondition * condition)
00106 {
00107 _conditions.push_back(condition);
00108 }
00109
00110
00111
00113
00115
00116 SGOrCondition::SGOrCondition ()
00117 {
00118 }
00119
00120 SGOrCondition::~SGOrCondition ()
00121 {
00122 for (unsigned int i = 0; i < _conditions.size(); i++)
00123 delete _conditions[i];
00124 }
00125
00126 bool
00127 SGOrCondition::test () const
00128 {
00129 int nConditions = _conditions.size();
00130 for (int i = 0; i < nConditions; i++) {
00131 if (_conditions[i]->test())
00132 return true;
00133 }
00134 return false;
00135 }
00136
00137 void
00138 SGOrCondition::addCondition (SGCondition * condition)
00139 {
00140 _conditions.push_back(condition);
00141 }
00142
00143
00144
00146
00148
00149 static int
00150 doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
00151 {
00152 switch (left->getType()) {
00153 case SGPropertyNode::BOOL: {
00154 bool v1 = left->getBoolValue();
00155 bool v2 = right->getBoolValue();
00156 if (v1 < v2)
00157 return SGComparisonCondition::LESS_THAN;
00158 else if (v1 > v2)
00159 return SGComparisonCondition::GREATER_THAN;
00160 else
00161 return SGComparisonCondition::EQUALS;
00162 break;
00163 }
00164 case SGPropertyNode::INT: {
00165 int v1 = left->getIntValue();
00166 int v2 = right->getIntValue();
00167 if (v1 < v2)
00168 return SGComparisonCondition::LESS_THAN;
00169 else if (v1 > v2)
00170 return SGComparisonCondition::GREATER_THAN;
00171 else
00172 return SGComparisonCondition::EQUALS;
00173 break;
00174 }
00175 case SGPropertyNode::LONG: {
00176 long v1 = left->getLongValue();
00177 long v2 = right->getLongValue();
00178 if (v1 < v2)
00179 return SGComparisonCondition::LESS_THAN;
00180 else if (v1 > v2)
00181 return SGComparisonCondition::GREATER_THAN;
00182 else
00183 return SGComparisonCondition::EQUALS;
00184 break;
00185 }
00186 case SGPropertyNode::FLOAT: {
00187 float v1 = left->getFloatValue();
00188 float v2 = right->getFloatValue();
00189 if (v1 < v2)
00190 return SGComparisonCondition::LESS_THAN;
00191 else if (v1 > v2)
00192 return SGComparisonCondition::GREATER_THAN;
00193 else
00194 return SGComparisonCondition::EQUALS;
00195 break;
00196 }
00197 case SGPropertyNode::DOUBLE: {
00198 double v1 = left->getDoubleValue();
00199 double v2 = right->getDoubleValue();
00200 if (v1 < v2)
00201 return SGComparisonCondition::LESS_THAN;
00202 else if (v1 > v2)
00203 return SGComparisonCondition::GREATER_THAN;
00204 else
00205 return SGComparisonCondition::EQUALS;
00206 break;
00207 }
00208 case SGPropertyNode::STRING:
00209 case SGPropertyNode::NONE:
00210 case SGPropertyNode::UNSPECIFIED: {
00211 string v1 = left->getStringValue();
00212 string v2 = right->getStringValue();
00213 if (v1 < v2)
00214 return SGComparisonCondition::LESS_THAN;
00215 else if (v1 > v2)
00216 return SGComparisonCondition::GREATER_THAN;
00217 else
00218 return SGComparisonCondition::EQUALS;
00219 break;
00220 }
00221 }
00222 throw sg_exception("condition: unrecognized node type in comparison");
00223 return 0;
00224 }
00225
00226
00227 SGComparisonCondition::SGComparisonCondition (Type type, bool reverse)
00228 : _type(type),
00229 _reverse(reverse),
00230 _left_property(0),
00231 _right_property(0),
00232 _right_value(0)
00233 {
00234 }
00235
00236 SGComparisonCondition::~SGComparisonCondition ()
00237 {
00238 }
00239
00240 bool
00241 SGComparisonCondition::test () const
00242 {
00243
00244 if (_left_property == 0 ||
00245 (_right_property == 0 && _right_value == 0))
00246 return false;
00247
00248
00249 int cmp =
00250 doComparison(_left_property,
00251 (_right_property != 0 ? _right_property : _right_value));
00252 if (!_reverse)
00253 return (cmp == _type);
00254 else
00255 return (cmp != _type);
00256 }
00257
00258 void
00259 SGComparisonCondition::setLeftProperty( SGPropertyNode *prop_root,
00260 const char * propname )
00261 {
00262 _left_property = prop_root->getNode(propname, true);
00263 }
00264
00265 void
00266 SGComparisonCondition::setRightProperty( SGPropertyNode *prop_root,
00267 const char * propname )
00268 {
00269 _right_value = 0;
00270 _right_property = prop_root->getNode(propname, true);
00271 }
00272
00273 void
00274 SGComparisonCondition::setRightValue (const SGPropertyNode *node)
00275 {
00276 _right_property = 0;
00277 _right_value = new SGPropertyNode(*node);
00278 }
00279
00280
00281
00283
00285
00286
00287 static SGCondition * readCondition( SGPropertyNode *prop_root,
00288 const SGPropertyNode *node );
00289
00290 static SGCondition *
00291 readPropertyCondition( SGPropertyNode *prop_root,
00292 const SGPropertyNode *node )
00293 {
00294 return new SGPropertyCondition( prop_root, node->getStringValue() );
00295 }
00296
00297 static SGCondition *
00298 readNotCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
00299 {
00300 int nChildren = node->nChildren();
00301 for (int i = 0; i < nChildren; i++) {
00302 const SGPropertyNode * child = node->getChild(i);
00303 SGCondition * condition = readCondition(prop_root, child);
00304 if (condition != 0)
00305 return new SGNotCondition(condition);
00306 }
00307 SG_LOG(SG_COCKPIT, SG_ALERT, "empty 'not' condition");
00308 return 0;
00309 }
00310
00311 static SGCondition *
00312 readAndConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
00313 {
00314 SGAndCondition * andCondition = new SGAndCondition;
00315 int nChildren = node->nChildren();
00316 for (int i = 0; i < nChildren; i++) {
00317 const SGPropertyNode * child = node->getChild(i);
00318 SGCondition * condition = readCondition(prop_root, child);
00319 if (condition != 0)
00320 andCondition->addCondition(condition);
00321 }
00322 return andCondition;
00323 }
00324
00325 static SGCondition *
00326 readOrConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
00327 {
00328 SGOrCondition * orCondition = new SGOrCondition;
00329 int nChildren = node->nChildren();
00330 for (int i = 0; i < nChildren; i++) {
00331 const SGPropertyNode * child = node->getChild(i);
00332 SGCondition * condition = readCondition(prop_root, child);
00333 if (condition != 0)
00334 orCondition->addCondition(condition);
00335 }
00336 return orCondition;
00337 }
00338
00339 static SGCondition *
00340 readComparison( SGPropertyNode *prop_root,
00341 const SGPropertyNode *node,
00342 SGComparisonCondition::Type type,
00343 bool reverse)
00344 {
00345 SGComparisonCondition * condition = new SGComparisonCondition(type, reverse);
00346 condition->setLeftProperty(prop_root, node->getStringValue("property[0]"));
00347 if (node->hasValue("property[1]"))
00348 condition->setRightProperty(prop_root, node->getStringValue("property[1]"));
00349 else if (node->hasValue("value"))
00350 condition->setRightValue(node->getChild("value", 0));
00351 else
00352 throw sg_exception("condition: comparison without property[1] or value");
00353
00354 return condition;
00355 }
00356
00357 static SGCondition *
00358 readCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
00359 {
00360 const string &name = node->getName();
00361 if (name == "property")
00362 return readPropertyCondition(prop_root, node);
00363 else if (name == "not")
00364 return readNotCondition(prop_root, node);
00365 else if (name == "and")
00366 return readAndConditions(prop_root, node);
00367 else if (name == "or")
00368 return readOrConditions(prop_root, node);
00369 else if (name == "less-than")
00370 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
00371 false);
00372 else if (name == "less-than-equals")
00373 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
00374 true);
00375 else if (name == "greater-than")
00376 return readComparison(prop_root, node, SGComparisonCondition::GREATER_THAN,
00377 false);
00378 else if (name == "greater-than-equals")
00379 return readComparison(prop_root, node, SGComparisonCondition::LESS_THAN,
00380 true);
00381 else if (name == "equals")
00382 return readComparison(prop_root, node, SGComparisonCondition::EQUALS,
00383 false);
00384 else if (name == "not-equals")
00385 return readComparison(prop_root, node, SGComparisonCondition::EQUALS, true);
00386 else
00387 return 0;
00388 }
00389
00390
00391
00393
00395
00396 SGConditional::SGConditional ()
00397 : _condition (0)
00398 {
00399 }
00400
00401 SGConditional::~SGConditional ()
00402 {
00403 delete _condition;
00404 }
00405
00406 void
00407 SGConditional::setCondition (SGCondition * condition)
00408 {
00409 delete _condition;
00410 _condition = condition;
00411 }
00412
00413 bool
00414 SGConditional::test () const
00415 {
00416 return ((_condition == 0) || _condition->test());
00417 }
00418
00419
00420
00421
00422 SGCondition *
00423 sgReadCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
00424 {
00425 return readAndConditions(prop_root, node);
00426 }
00427
00428
00429