]> git.mxchange.org Git - flightgear.git/commitdiff
- added FGCondition class and subclasses
authorcurt <curt>
Fri, 3 Aug 2001 00:19:41 +0000 (00:19 +0000)
committercurt <curt>
Fri, 3 Aug 2001 00:19:41 +0000 (00:19 +0000)
- implemented FGConditional abstract base class
- added fgReadCondition global function

src/Main/fg_props.cxx

index e2fd5fc9f64d8fe944af7b932359c6828bc65e5a..396aa66e205b69032e7056f85e0edfe7e1d2d86b 100644 (file)
@@ -1132,4 +1132,398 @@ fgLoadFlight (istream &input)
   return true;
 }
 
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGCondition.
+////////////////////////////////////////////////////////////////////////
+
+FGCondition::FGCondition ()
+{
+}
+
+FGCondition::~FGCondition ()
+{
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGPropertyCondition.
+////////////////////////////////////////////////////////////////////////
+
+FGPropertyCondition::FGPropertyCondition (const string &propname)
+  : _node(fgGetNode(propname, true))
+{
+}
+
+FGPropertyCondition::~FGPropertyCondition ()
+{
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGNotCondition.
+////////////////////////////////////////////////////////////////////////
+
+FGNotCondition::FGNotCondition (FGCondition * condition)
+  : _condition(condition)
+{
+}
+
+FGNotCondition::~FGNotCondition ()
+{
+  delete _condition;
+}
+
+bool
+FGNotCondition::test () const
+{
+  return !(_condition->test());
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGAndCondition.
+////////////////////////////////////////////////////////////////////////
+
+FGAndCondition::FGAndCondition ()
+{
+}
+
+FGAndCondition::~FGAndCondition ()
+{
+  for (int i = 0; i < _conditions.size(); i++)
+    delete _conditions[i];
+}
+
+bool
+FGAndCondition::test () const
+{
+  int nConditions = _conditions.size();
+  for (int i = 0; i < nConditions; i++) {
+    if (!_conditions[i]->test())
+      return false;
+  }
+  return true;
+}
+
+void
+FGAndCondition::addCondition (FGCondition * condition)
+{
+  _conditions.push_back(condition);
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGOrCondition.
+////////////////////////////////////////////////////////////////////////
+
+FGOrCondition::FGOrCondition ()
+{
+}
+
+FGOrCondition::~FGOrCondition ()
+{
+  for (int i = 0; i < _conditions.size(); i++)
+    delete _conditions[i];
+}
+
+bool
+FGOrCondition::test () const
+{
+  int nConditions = _conditions.size();
+  for (int i = 0; i < nConditions; i++) {
+    if (_conditions[i]->test())
+      return true;
+  }
+  return false;
+}
+
+void
+FGOrCondition::addCondition (FGCondition * condition)
+{
+  _conditions.push_back(condition);
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGComparisonCondition.
+////////////////////////////////////////////////////////////////////////
+
+static int
+doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
+{
+  switch (left->getType()) {
+  case SGPropertyNode::BOOL: {
+    bool v1 = left->getBoolValue();
+    bool v2 = right->getBoolValue();
+    if (v1 < v2)
+      return FGComparisonCondition::LESS_THAN;
+    else if (v1 > v2)
+      return FGComparisonCondition::GREATER_THAN;
+    else
+      return FGComparisonCondition::EQUALS;
+    break;
+  }
+  case SGPropertyNode::INT: {
+    int v1 = left->getIntValue();
+    int v2 = right->getIntValue();
+    if (v1 < v2)
+      return FGComparisonCondition::LESS_THAN;
+    else if (v1 > v2)
+      return FGComparisonCondition::GREATER_THAN;
+    else
+      return FGComparisonCondition::EQUALS;
+    break;
+  }
+  case SGPropertyNode::LONG: {
+    long v1 = left->getLongValue();
+    long v2 = right->getLongValue();
+    if (v1 < v2)
+      return FGComparisonCondition::LESS_THAN;
+    else if (v1 > v2)
+      return FGComparisonCondition::GREATER_THAN;
+    else
+      return FGComparisonCondition::EQUALS;
+    break;
+  }
+  case SGPropertyNode::FLOAT: {
+    float v1 = left->getFloatValue();
+    float v2 = right->getFloatValue();
+    if (v1 < v2)
+      return FGComparisonCondition::LESS_THAN;
+    else if (v1 > v2)
+      return FGComparisonCondition::GREATER_THAN;
+    else
+      return FGComparisonCondition::EQUALS;
+    break;
+  }
+  case SGPropertyNode::DOUBLE: {
+    double v1 = left->getDoubleValue();
+    double v2 = right->getDoubleValue();
+    if (v1 < v2)
+      return FGComparisonCondition::LESS_THAN;
+    else if (v1 > v2)
+      return FGComparisonCondition::GREATER_THAN;
+    else
+      return FGComparisonCondition::EQUALS;
+    break;
+  }
+  case SGPropertyNode::STRING: 
+  case SGPropertyNode::NONE:
+  case SGPropertyNode::UNSPECIFIED: {
+    string v1 = left->getStringValue();
+    string v2 = right->getStringValue();
+    if (v1 < v2)
+      return FGComparisonCondition::LESS_THAN;
+    else if (v1 > v2)
+      return FGComparisonCondition::GREATER_THAN;
+    else
+      return FGComparisonCondition::EQUALS;
+    break;
+  }
+  }
+  throw sg_exception("Unrecognized node type");
+  return 0;
+}
+
+
+FGComparisonCondition::FGComparisonCondition (Type type, bool reverse)
+  : _type(type),
+    _reverse(reverse),
+    _left_property(0),
+    _right_property(0),
+    _right_value(0)
+{
+}
+
+FGComparisonCondition::~FGComparisonCondition ()
+{
+  delete _right_value;
+}
+
+bool
+FGComparisonCondition::test () const
+{
+                               // Always fail if incompletely specified
+  if (_left_property == 0 ||
+      (_right_property == 0 && _right_value == 0))
+    return false;
+
+                               // Get LESS_THAN, EQUALS, or GREATER_THAN
+  int cmp =
+    doComparison(_left_property,
+                (_right_property != 0 ? _right_property : _right_value));
+  if (!_reverse)
+    return (cmp == _type);
+  else
+    return (cmp != _type);
+}
+
+void
+FGComparisonCondition::setLeftProperty (const string &propname)
+{
+  _left_property = fgGetNode(propname, true);
+}
+
+void
+FGComparisonCondition::setRightProperty (const string &propname)
+{
+  delete _right_value;
+  _right_value = 0;
+  _right_property = fgGetNode(propname, true);
+}
+
+void
+FGComparisonCondition::setRightValue (const SGPropertyNode *node)
+{
+  _right_property = 0;
+  delete _right_value;
+  _right_value = new SGPropertyNode(*node);
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Read a condition and use it if necessary.
+////////////////////////////////////////////////////////////////////////
+
+                                // Forward declaration
+static FGCondition * readCondition (const SGPropertyNode * node);
+
+static FGCondition *
+readPropertyCondition (const SGPropertyNode * node)
+{
+  return new FGPropertyCondition(node->getStringValue());
+}
+
+static FGCondition *
+readNotCondition (const SGPropertyNode * node)
+{
+  int nChildren = node->nChildren();
+  for (int i = 0; i < nChildren; i++) {
+    const SGPropertyNode * child = node->getChild(i);
+    FGCondition * condition = readCondition(child);
+    if (condition != 0)
+      return new FGNotCondition(condition);
+  }
+  SG_LOG(SG_COCKPIT, SG_ALERT, "Panel: empty 'not' condition");
+  return 0;
+}
+
+static FGCondition *
+readAndConditions (const SGPropertyNode * node)
+{
+  FGAndCondition * andCondition = new FGAndCondition;
+  int nChildren = node->nChildren();
+  for (int i = 0; i < nChildren; i++) {
+    const SGPropertyNode * child = node->getChild(i);
+    FGCondition * condition = readCondition(child);
+    if (condition != 0)
+      andCondition->addCondition(condition);
+  }
+  return andCondition;
+}
+
+static FGCondition *
+readOrConditions (const SGPropertyNode * node)
+{
+  FGOrCondition * orCondition = new FGOrCondition;
+  int nChildren = node->nChildren();
+  for (int i = 0; i < nChildren; i++) {
+    const SGPropertyNode * child = node->getChild(i);
+    FGCondition * condition = readCondition(child);
+    if (condition != 0)
+      orCondition->addCondition(condition);
+  }
+  return orCondition;
+}
+
+static FGCondition *
+readComparison (const SGPropertyNode * node,
+               FGComparisonCondition::Type type,
+               bool reverse)
+{
+  FGComparisonCondition * condition = new FGComparisonCondition(type, reverse);
+  condition->setLeftProperty(node->getStringValue("property[0]"));
+  if (node->hasValue("property[1]"))
+    condition->setRightProperty(node->getStringValue("property[1]"));
+  else
+    condition->setRightValue(node->getChild("value", 0));
+
+  return condition;
+}
+
+static FGCondition *
+readCondition (const SGPropertyNode * node)
+{
+  const string &name = node->getName();
+  if (name == "property")
+    return readPropertyCondition(node);
+  else if (name == "not")
+    return readNotCondition(node);
+  else if (name == "and")
+    return readAndConditions(node);
+  else if (name == "or")
+    return readOrConditions(node);
+  else if (name == "less-than")
+    return readComparison(node, FGComparisonCondition::LESS_THAN, false);
+  else if (name == "less-than-equals")
+    return readComparison(node, FGComparisonCondition::GREATER_THAN, true);
+  else if (name == "greater-than")
+    return readComparison(node, FGComparisonCondition::GREATER_THAN, false);
+  else if (name == "greater-than-equals")
+    return readComparison(node, FGComparisonCondition::LESS_THAN, true);
+  else if (name == "equals")
+    return readComparison(node, FGComparisonCondition::EQUALS, false);
+  else if (name == "not-equals")
+    return readComparison(node, FGComparisonCondition::EQUALS, true);
+  else
+    return 0;
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGConditional.
+////////////////////////////////////////////////////////////////////////
+
+FGConditional::FGConditional ()
+  : _condition (0)
+{
+}
+
+FGConditional::~FGConditional ()
+{
+  delete _condition;
+}
+
+void
+FGConditional::setCondition (FGCondition * condition)
+{
+  delete _condition;
+  _condition = condition;
+}
+
+bool
+FGConditional::test () const
+{
+  return ((_condition == 0) || _condition->test());
+}
+
+
+\f
+// The top-level is always an implicit 'and' group
+FGCondition *
+fgReadCondition (const SGPropertyNode * node)
+{
+  return readAndConditions(node);
+}
+
+
 // end of fg_props.cxx