]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/filtersjb/FGSwitch.cpp
Make yasim accept the launchbar and hook properties. They are not tied to anything...
[flightgear.git] / src / FDM / JSBSim / filtersjb / FGSwitch.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGSwitch.cpp
4  Author:       Jon S. Berndt
5  Date started: 4/2000
6
7  ------------- Copyright (C) 2000 -------------
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  details.
18
19  You should have received a copy of the GNU General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22
23  Further information about the GNU General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 FUNCTIONAL DESCRIPTION
27 --------------------------------------------------------------------------------
28
29 HISTORY
30 --------------------------------------------------------------------------------
31
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 COMMENTS, REFERENCES,  and NOTES
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35
36 The SWITCH component is defined as follows (see the API documentation for more
37 information):
38
39 <COMPONENT NAME="switch1" TYPE="SWITCH">
40   <TEST LOGIC="{AND|OR|DEFAULT}" OUTPUT="{property|value}">
41     {property} {conditional} {property|value}
42     <CONDITION_GROUP LOGIC="{AND|OR}">
43       {property} {conditional} {property|value}
44       ...
45     </CONDITION_GROUP>
46     ...
47   </TEST>
48   <TEST LOGIC="{AND|OR}" OUTPUT="{property|value}">
49     {property} {conditional} {property|value}
50     ...
51   </TEST>
52   ...
53 </COMPONENT>
54
55 Also, see the header file (FGSwitch.h) for further details.
56
57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58 INCLUDES
59 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
60
61 #include "FGSwitch.h"
62
63 namespace JSBSim {
64
65 static const char *IdSrc = "$Id$";
66 static const char *IdHdr = ID_SWITCH;
67
68 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69 CLASS IMPLEMENTATION
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
71
72
73 FGSwitch::FGSwitch(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
74                                                        AC_cfg(AC_cfg)
75 {
76   string token, value;
77   struct test *current_test;
78   string sOutputIdx;
79
80   Type = AC_cfg->GetValue("TYPE");
81   Name = AC_cfg->GetValue("NAME");
82
83   AC_cfg->GetNextConfigLine();
84   while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
85
86     // See the above documentation, or the API docs, for information on what
87     // the SWITCH component is supposed to look like in the configuration file.
88     // Below, the switch component is read in.
89
90     if (token == "TEST") {
91       tests.push_back(test());
92       current_test = &tests.back();
93
94       if (AC_cfg->GetValue("LOGIC") == "OR") {
95         current_test->Logic = eOR;
96       } else if (AC_cfg->GetValue("LOGIC") == "AND") {
97         current_test->Logic = eAND;
98       } else if (AC_cfg->GetValue("LOGIC") == "DEFAULT") {
99         current_test->Logic = eDefault;
100       } else { // error
101         cerr << "Unrecognized LOGIC token  in switch component: " << Name << endl;
102       }
103
104       value = AC_cfg->GetValue("VALUE");
105       if (value.empty()) {
106         cerr << "No VALUE supplied for switch component: " << Name << endl;
107       } else {
108         if (value.find_first_not_of("-.0123456789eE") == string::npos) {
109           // if true (and execution falls into this block), "value" is a number.
110           current_test->OutputVal = atof(value.c_str());
111         } else {
112           // "value" must be a property if execution passes to here.
113           if (value[0] == '-') {
114             current_test->sign = -1.0;
115             value.erase(0,1);
116           } else {
117             current_test->sign = 1.0;
118           }
119           current_test->OutputProp = PropertyManager->GetNode(value);
120         }
121       }
122
123       AC_cfg->GetNextConfigLine();
124       while (AC_cfg->GetValue() != string("/TEST")) {
125         current_test->conditions.push_back(FGCondition(AC_cfg, PropertyManager));
126       }
127       AC_cfg->GetNextConfigLine();
128     } else if (token == "OUTPUT") {
129       IsOutput = true;
130       *AC_cfg >> sOutputIdx;
131       *AC_cfg >> sOutputIdx;
132       OutputNode = PropertyManager->GetNode( sOutputIdx, true );
133     }
134   }
135
136   FGFCSComponent::bind();
137
138   Debug(0);
139 }
140
141 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142
143 FGSwitch::~FGSwitch()
144 {
145   Debug(1);
146 }
147
148 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149
150 bool FGSwitch::Run(void )
151 {
152   vector <test>::iterator iTests = tests.begin();
153   vector <FGCondition>::iterator iConditions;
154   bool pass = false;
155
156   FGFCSComponent::Run(); // call the base class for initialization of Input
157
158   while (iTests < tests.end()) {
159     iConditions = iTests->conditions.begin();
160
161     if (iTests->Logic == eDefault) {
162       Output = iTests->GetValue();
163     } else if (iTests->Logic == eAND) {
164       pass = true;
165       while (iConditions < iTests->conditions.end()) {
166         if (!iConditions->Evaluate()) pass = false;
167         *iConditions++;
168       }
169     } else if (iTests->Logic == eOR) {
170       pass = false;
171       while (iConditions < iTests->conditions.end()) {
172         if (iConditions->Evaluate()) pass = true;
173         *iConditions++;
174       }
175     } else {
176       cerr << "Invalid logic test" << endl;
177     }
178
179     if (pass) {
180       Output = iTests->GetValue();
181       break;
182     }
183     *iTests++;
184   }
185
186   if (IsOutput) SetOutput();
187
188   return true;
189 }
190
191 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192 //    The bitmasked value choices are as follows:
193 //    unset: In this case (the default) JSBSim would only print
194 //       out the normally expected messages, essentially echoing
195 //       the config files as they are read. If the environment
196 //       variable is not set, debug_lvl is set to 1 internally
197 //    0: This requests JSBSim not to output any messages
198 //       whatsoever.
199 //    1: This value explicity requests the normal JSBSim
200 //       startup messages
201 //    2: This value asks for a message to be printed out when
202 //       a class is instantiated
203 //    4: When this value is set, a message is displayed when a
204 //       FGModel object executes its Run() method
205 //    8: When this value is set, various runtime state variables
206 //       are printed out periodically
207 //    16: When set various parameters are sanity checked and
208 //       a message is printed out when they go out of bounds
209
210 void FGSwitch::Debug(int from)
211 {
212   vector <test>::iterator iTests = tests.begin();
213   vector <FGCondition>::iterator iConditions;
214   string comp, scratch;
215   string indent = "        ";
216   bool first = false;
217
218   if (debug_lvl <= 0) return;
219
220   if (debug_lvl & 1) { // Standard console startup message output
221     if (from == 0) { // Constructor
222       while (iTests < tests.end()) {
223
224         scratch = " if ";
225
226         switch(iTests->Logic) {
227         case (elUndef):
228           comp = " UNSET ";
229           cerr << "Unset logic for test condition" << endl;
230           break;
231         case (eAND):
232           comp = " AND ";
233           break;
234         case (eOR):
235           comp=" OR ";
236           break;
237         case (eDefault):
238           scratch = " by default.";
239           break;
240         default:
241           comp = " UNKNOWN ";
242           cerr << "Unknown logic for test condition" << endl;
243         }
244
245         if (iTests->OutputProp != 0L)
246           if (iTests->sign < 0)
247             cout << indent << "Switch VALUE is - " << iTests->OutputProp->GetName() << scratch << endl;
248           else
249             cout << indent << "Switch VALUE is " << iTests->OutputProp->GetName() << scratch << endl;
250         else
251           cout << indent << "Switch VALUE is " << iTests->OutputVal << scratch << endl;
252
253         iConditions = iTests->conditions.begin();
254         first = true;
255         while (iConditions < iTests->conditions.end()) {
256           if (!first) cout << indent << comp << " ";
257           else cout << indent << " ";
258           first = false;
259           iConditions->PrintCondition();
260           cout << endl;
261           *iConditions++;
262         }
263         cout << endl;
264         *iTests++;
265       }
266       if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
267     }
268   }
269   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
270     if (from == 0) cout << "Instantiated: FGSwitch" << endl;
271     if (from == 1) cout << "Destroyed:    FGSwitch" << endl;
272   }
273   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
274   }
275   if (debug_lvl & 8 ) { // Runtime state variables
276   }
277   if (debug_lvl & 16) { // Sanity checking
278   }
279   if (debug_lvl & 64) {
280     if (from == 0) { // Constructor
281       cout << IdSrc << endl;
282       cout << IdHdr << endl;
283     }
284   }
285 }
286
287 } //namespace JSBSim
288