]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/JSBSim/models/flight_control/FGSwitch.cpp
Merge branch 'jsd/atmos' into topic/atmos-merge
[flightgear.git] / src / FDM / JSBSim / models / flight_control / FGSwitch.cpp
index 782cc0eec830dddd270f0cca1b740ad1345993ba..5ed272155b32175cfb68d8c89cac55937fcb642c 100644 (file)
@@ -78,15 +78,17 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
   struct test *current_test;
   Element *test_element, *condition_element;
 
+  FGFCSComponent::bind(); // Bind() this component here in case it is used
+                          // in its own definition for a sample-and-hold
+
   test_element = element->GetElement();
   while (test_element) {
     if (test_element->GetName() == "default") {
-      tests.push_back(test());
-      current_test = &tests.back();
+      current_test = new struct test;
       current_test->Logic = eDefault;
+      tests.push_back(current_test);
     } else if (test_element->GetName() == "test") { // here's a test
-      tests.push_back(test());
-      current_test = &tests.back();
+      current_test = new struct test;
       logic = test_element->GetAttributeValue("logic");
       if (logic == "OR") current_test->Logic = eOR;
       else if (logic == "AND") current_test->Logic = eAND;
@@ -94,24 +96,32 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
       else { // error
         cerr << "Unrecognized LOGIC token " << logic << " in switch component: " << Name << endl;
       }
-      for (unsigned int i=0; i<test_element->GetNumDataLines(); i++)
-        current_test->conditions.push_back(FGCondition(test_element->GetDataLine(i), PropertyManager));
+      for (unsigned int i=0; i<test_element->GetNumDataLines(); i++) {
+        string input_data = test_element->GetDataLine(i);
+        if (input_data.size() <= 1) {
+          // Make sure there are no bad data lines that consist solely of whitespace
+          cerr << fgred << "  Bad data line in switch component: " << Name << reset << endl;
+          continue;
+        }
+        current_test->conditions.push_back(new FGCondition(input_data, PropertyManager));
+      }
 
       condition_element = test_element->GetElement(); // retrieve condition groups
       while (condition_element) {
-        current_test->conditions.push_back(FGCondition(condition_element, PropertyManager));
+        current_test->conditions.push_back(new FGCondition(condition_element, PropertyManager));
         condition_element = test_element->GetNextElement();
       }
 
+      tests.push_back(current_test);
     }
 
-    if (test_element->GetName() != "output") { // this is not an output element
+    if (test_element->GetName() != "output"
+        && test_element->GetName() != "description") { // this is not an output element
       value = test_element->GetAttributeValue("value");
       if (value.empty()) {
         cerr << "No VALUE supplied for switch component: " << Name << endl;
       } else {
-        if (value.find_first_not_of("-.0123456789eE") == string::npos) {
-          // if true (and execution falls into this block), "value" is a number.
+        if (is_number(value)) {
           current_test->OutputVal = atof(value.c_str());
         } else {
           // "value" must be a property if execution passes to here.
@@ -125,12 +135,9 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
         }
       }
     }
-
     test_element = element->GetNextElement();
   }
 
-  FGFCSComponent::bind();
-
   Debug(0);
 }
 
@@ -138,6 +145,11 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
 
 FGSwitch::~FGSwitch()
 {
+  for (unsigned int i=0; i<tests.size(); i++) {
+    for (unsigned int j=0; j<tests[i]->conditions.size(); j++) delete tests[i]->conditions[j];
+    delete tests[i];
+  }
+
   Debug(1);
 }
 
@@ -145,37 +157,33 @@ FGSwitch::~FGSwitch()
 
 bool FGSwitch::Run(void )
 {
-  vector <test>::iterator iTests = tests.begin();
-  vector <FGCondition>::iterator iConditions;
   bool pass = false;
+  double default_output=0.0;
 
-  while (iTests < tests.end()) {
-    iConditions = iTests->conditions.begin();
-
-    if (iTests->Logic == eDefault) {
-      Output = iTests->GetValue();
-    } else if (iTests->Logic == eAND) {
+  for (unsigned int i=0; i<tests.size(); i++) {
+    if (tests[i]->Logic == eDefault) {
+      default_output = tests[i]->GetValue();
+    } else if (tests[i]->Logic == eAND) {
       pass = true;
-      while (iConditions < iTests->conditions.end()) {
-        if (!iConditions->Evaluate()) pass = false;
-        *iConditions++;
+      for (unsigned int j=0; j<tests[i]->conditions.size(); j++) {
+        if (!tests[i]->conditions[j]->Evaluate()) pass = false;
       }
-    } else if (iTests->Logic == eOR) {
+    } else if (tests[i]->Logic == eOR) {
       pass = false;
-      while (iConditions < iTests->conditions.end()) {
-        if (iConditions->Evaluate()) pass = true;
-        *iConditions++;
+      for (unsigned int j=0; j<tests[i]->conditions.size(); j++) {
+        if (tests[i]->conditions[j]->Evaluate()) pass = true;
       }
     } else {
       cerr << "Invalid logic test" << endl;
     }
 
     if (pass) {
-      Output = iTests->GetValue();
+      Output = tests[i]->GetValue();
       break;
     }
-    *iTests++;
   }
+  
+  if (!pass) Output = default_output;
 
   Clip();
   if (IsOutput) SetOutput();
@@ -204,8 +212,6 @@ bool FGSwitch::Run(void )
 
 void FGSwitch::Debug(int from)
 {
-  vector <test>::iterator iTests = tests.begin();
-  vector <FGCondition>::iterator iConditions;
   string comp, scratch;
   string indent = "        ";
   bool first = false;
@@ -214,11 +220,11 @@ void FGSwitch::Debug(int from)
 
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor
-      while (iTests < tests.end()) {
+      for (unsigned int i=0; i<tests.size(); i++) {
 
         scratch = " if ";
 
-        switch(iTests->Logic) {
+        switch(tests[i]->Logic) {
         case (elUndef):
           comp = " UNSET ";
           cerr << "Unset logic for test condition" << endl;
@@ -237,26 +243,23 @@ void FGSwitch::Debug(int from)
           cerr << "Unknown logic for test condition" << endl;
         }
 
-        if (iTests->OutputProp != 0L)
-          if (iTests->sign < 0)
-            cout << indent << "Switch VALUE is - " << iTests->OutputProp->GetName() << scratch << endl;
+        if (tests[i]->OutputProp != 0L)
+          if (tests[i]->sign < 0)
+            cout << indent << "Switch VALUE is - " << tests[i]->OutputProp->GetName() << scratch << endl;
           else
-            cout << indent << "Switch VALUE is " << iTests->OutputProp->GetName() << scratch << endl;
+            cout << indent << "Switch VALUE is " << tests[i]->OutputProp->GetName() << scratch << endl;
         else
-          cout << indent << "Switch VALUE is " << iTests->OutputVal << scratch << endl;
+          cout << indent << "Switch VALUE is " << tests[i]->OutputVal << scratch << endl;
 
-        iConditions = iTests->conditions.begin();
         first = true;
-        while (iConditions < iTests->conditions.end()) {
+        for (unsigned int j=0; j<tests[i]->conditions.size(); j++) {
           if (!first) cout << indent << comp << " ";
           else cout << indent << " ";
           first = false;
-          iConditions->PrintCondition();
+          tests[i]->conditions[j]->PrintCondition();
           cout << endl;
-          *iConditions++;
         }
         cout << endl;
-        *iTests++;
       }
       if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
     }