41 #include "FGCondition.h"
42 #include "FGPropertyValue.h"
43 #include "input_output/FGXMLElement.h"
44 #include "input_output/FGPropertyManager.h"
45 #include "FGParameterValue.h"
56 FGCondition::FGCondition(Element* element, FGPropertyManager* PropertyManager)
57 : Logic(elUndef), TestParam1(nullptr), TestParam2(nullptr),
60 InitializeConditionals();
62 string logic = element->GetAttributeValue(
"logic");
64 if (logic ==
"OR") Logic = eOR;
65 else if (logic ==
"AND") Logic = eAND;
67 cerr << element->ReadFrom()
68 <<
"Unrecognized LOGIC token " << logic << endl;
69 throw std::invalid_argument(
"FGCondition: unrecognized logic value:'" + logic +
"'");
75 for (
unsigned int i=0; i<element->GetNumDataLines(); i++) {
76 string data = element->GetDataLine(i);
77 conditions.push_back(
new FGCondition(data, PropertyManager, element));
80 Element* condition_element = element->GetElement();
81 const string& elName = element->GetName();
83 while (condition_element) {
84 string tagName = condition_element->GetName();
86 if (tagName != elName) {
87 cerr << condition_element->ReadFrom()
88 <<
"Unrecognized tag <" << tagName <<
"> in the condition statement."
90 throw std::invalid_argument(
"FGCondition: unrecognized tag:'" + tagName +
"'");
93 conditions.push_back(
new FGCondition(condition_element, PropertyManager));
94 condition_element = element->GetNextElement();
104 FGCondition::FGCondition(
const string& test, FGPropertyManager* PropertyManager,
106 : Logic(elUndef), TestParam1(nullptr), TestParam2(nullptr),
109 InitializeConditionals();
111 vector<string> test_strings = split(test,
' ');
113 if (test_strings.size() == 3) {
114 TestParam1 =
new FGPropertyValue(test_strings[0], PropertyManager);
115 conditional = test_strings[1];
116 TestParam2 =
new FGParameterValue(test_strings[2], PropertyManager);
118 cerr << el->ReadFrom()
119 <<
" Conditional test is invalid: \"" << test
120 <<
"\" has " << test_strings.size() <<
" elements in the "
121 <<
"test condition." << endl;
122 throw std::invalid_argument(
"FGCondition: incorrect number of test elements:" + std::to_string(test_strings.size()));
125 Comparison = mComparison[conditional];
126 if (Comparison == ecUndef) {
127 throw std::invalid_argument(
"FGCondition: Comparison operator: \""+conditional
128 +
"\" does not exist. Please check the conditional.");
134 void FGCondition::InitializeConditionals(
void)
136 mComparison[
"EQ"] = eEQ;
137 mComparison[
"NE"] = eNE;
138 mComparison[
"GT"] = eGT;
139 mComparison[
"GE"] = eGE;
140 mComparison[
"LT"] = eLT;
141 mComparison[
"LE"] = eLE;
142 mComparison[
"eq"] = eEQ;
143 mComparison[
"ne"] = eNE;
144 mComparison[
"gt"] = eGT;
145 mComparison[
"ge"] = eGE;
146 mComparison[
"lt"] = eLT;
147 mComparison[
"le"] = eLE;
148 mComparison[
"=="] = eEQ;
149 mComparison[
"!="] = eNE;
150 mComparison[
">"] = eGT;
151 mComparison[
">="] = eGE;
152 mComparison[
"<"] = eLT;
153 mComparison[
"<="] = eLE;
158 FGCondition::~FGCondition(
void)
160 for (
auto cond: conditions)
delete cond;
167 bool FGCondition::Evaluate(
void )
176 for (
auto cond: conditions) {
177 if (!cond->Evaluate()) pass =
false;
183 for (
auto cond: conditions) {
184 if (cond->Evaluate()) pass =
true;
191 double compareValue = TestParam2->GetValue();
193 switch (Comparison) {
195 cerr <<
"Undefined comparison operator." << endl;
198 pass = TestParam1->getDoubleValue() == compareValue;
201 pass = TestParam1->getDoubleValue() != compareValue;
204 pass = TestParam1->getDoubleValue() > compareValue;
207 pass = TestParam1->getDoubleValue() >= compareValue;
210 pass = TestParam1->getDoubleValue() < compareValue;
213 pass = TestParam1->getDoubleValue() <= compareValue;
216 cerr <<
"Unknown comparison operator." << endl;
225 void FGCondition::PrintCondition(
string indent)
229 if (!conditions.empty()) {
234 cerr <<
"unset logic for test condition" << endl;
237 scratch = indent +
"if all of the following are true: {";
240 scratch = indent +
"if any of the following are true: {";
243 scratch =
" UNKNOWN";
244 cerr <<
"Unknown logic for test condition" << endl;
246 cout << scratch << endl;
248 for (
auto cond: conditions) {
249 cond->PrintCondition(indent +
" ");
253 cout << indent <<
"}";
256 cout << indent << TestParam1->GetName() <<
" " << conditional
257 <<
" " << TestParam2->GetName();
280 void FGCondition::Debug(
int from)
282 if (debug_lvl <= 0)
return;
289 if (debug_lvl & 2 ) {
290 if (from == 0) cout <<
"Instantiated: FGCondition" << endl;
291 if (from == 1) cout <<
"Destroyed: FGCondition" << endl;
293 if (debug_lvl & 4 ) {
295 if (debug_lvl & 8 ) {
297 if (debug_lvl & 16) {
299 if (debug_lvl & 64) {