JSBSim Flight Dynamics Model  1.0 (02 March 2017)
An Open Source Flight Dynamics and Control Software Library in C++
FGPropertyManager.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Header: FGPropertyManager.cpp
4  Author: Tony Peden
5  Based on work originally by David Megginson
6  Date: 2/2002
7 
8  ------------- Copyright (C) 2002 -------------
9 
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU Lesser General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14 
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18  details.
19 
20  You should have received a copy of the GNU Lesser General Public License along with
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22  Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24  Further information about the GNU Lesser General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26 
27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28 INCLUDES
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
30 
31 #include "FGPropertyManager.h"
32 
33 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 DEFINITIONS
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
36 
37 
38 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 FORWARD DECLARATIONS
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41 
42 using namespace std;
43 
44 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
45 COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
46 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 */
48 
49 namespace JSBSim {
50 
51 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 
53 void FGPropertyManager::Unbind(void)
54 {
55  vector<SGPropertyNode_ptr>::iterator it;
56 
57  for (it = tied_properties.begin();it < tied_properties.end();it++)
58  (*it)->untie();
59 
60  tied_properties.clear();
61 }
62 
63 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 
65 string FGPropertyManager::mkPropertyName(string name, bool lowercase) {
66 
67  /* do this two pass to avoid problems with characters getting skipped
68  because the index changed */
69  unsigned i;
70  for(i=0;i<name.length();i++) {
71  if( lowercase && isupper(name[i]) )
72  name[i]=tolower(name[i]);
73  else if( isspace(name[i]) )
74  name[i]='-';
75  }
76 
77  return name;
78 }
79 
80 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 
83 FGPropertyNode::GetNode (const string &path, bool create)
84 {
85  SGPropertyNode* node = getNode(path.c_str(), create);
86  if (node == 0) {
87  cerr << "FGPropertyManager::GetNode() No node found for " << path << endl;
88  }
89  return (FGPropertyNode*)node;
90 }
91 
92 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93 
95 FGPropertyNode::GetNode (const string &relpath, int index, bool create)
96 {
97  SGPropertyNode* node = getNode(relpath.c_str(), index, create);
98  if (node == 0) {
99  cerr << "FGPropertyManager::GetNode() No node found for " << relpath
100  << "[" << index << "]" << endl;
101  }
102  return (FGPropertyNode*)node;
103 }
104 
105 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 
107 bool FGPropertyNode::HasNode (const string &path)
108 {
109  const SGPropertyNode* node = getNode(path.c_str(), false);
110  return (node != 0);
111 }
112 
113 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 
115 string FGPropertyNode::GetName( void ) const
116 {
117  return string( getName() );
118 }
119 
120 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 
122 string FGPropertyNode::GetPrintableName( void ) const
123 {
124  string temp_string(getName());
125  size_t initial_location=0;
126  size_t found_location;
127 
128  found_location = temp_string.rfind("/");
129  if (found_location != string::npos)
130  temp_string = temp_string.substr(found_location);
131 
132  found_location = temp_string.find('_',initial_location);
133  while (found_location != string::npos) {
134  temp_string.replace(found_location,1," ");
135  initial_location = found_location+1;
136  found_location = temp_string.find('_',initial_location);
137  }
138  return temp_string;
139 }
140 
141 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142 
143 string FGPropertyNode::GetFullyQualifiedName(void) const
144 {
145  vector<string> stack;
146  stack.push_back( getDisplayName(true) );
147  const SGPropertyNode* tmpn=getParent();
148  bool atroot=false;
149  while( !atroot ) {
150  stack.push_back( tmpn->getDisplayName(true) );
151  if( !tmpn->getParent() )
152  atroot=true;
153  else
154  tmpn=tmpn->getParent();
155  }
156 
157  string fqname="";
158  for(size_t i=stack.size()-1;i>0;i--) {
159  fqname+= stack[i];
160  fqname+= "/";
161  }
162  fqname+= stack[0];
163  return fqname;
164 
165 }
166 
167 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
168 
169 string FGPropertyNode::GetRelativeName( const string &path ) const
170 {
171  string temp_string = GetFullyQualifiedName();
172  size_t len = path.length();
173  if ( (len > 0) && (temp_string.substr(0,len) == path) ) {
174  temp_string = temp_string.erase(0,len);
175  }
176  return temp_string;
177 }
178 
179 
180 
181 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 
183 bool FGPropertyNode::GetBool (const string &name, bool defaultValue) const
184 {
185  return getBoolValue(name.c_str(), defaultValue);
186 }
187 
188 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189 
190 int FGPropertyNode::GetInt (const string &name, int defaultValue ) const
191 {
192  return getIntValue(name.c_str(), defaultValue);
193 }
194 
195 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
196 
197 int FGPropertyNode::GetLong (const string &name, long defaultValue ) const
198 {
199  return getLongValue(name.c_str(), defaultValue);
200 }
201 
202 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 
204 float FGPropertyNode::GetFloat (const string &name, float defaultValue ) const
205 {
206  return getFloatValue(name.c_str(), defaultValue);
207 }
208 
209 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 
211 double FGPropertyNode::GetDouble (const string &name, double defaultValue ) const
212 {
213  return getDoubleValue(name.c_str(), defaultValue);
214 }
215 
216 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217 
218 string FGPropertyNode::GetString (const string &name, string defaultValue ) const
219 {
220  return string(getStringValue(name.c_str(), defaultValue.c_str()));
221 }
222 
223 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224 
225 bool FGPropertyNode::SetBool (const string &name, bool val)
226 {
227  return setBoolValue(name.c_str(), val);
228 }
229 
230 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231 
232 bool FGPropertyNode::SetInt (const string &name, int val)
233 {
234  return setIntValue(name.c_str(), val);
235 }
236 
237 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238 
239 bool FGPropertyNode::SetLong (const string &name, long val)
240 {
241  return setLongValue(name.c_str(), val);
242 }
243 
244 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245 
246 bool FGPropertyNode::SetFloat (const string &name, float val)
247 {
248  return setFloatValue(name.c_str(), val);
249 }
250 
251 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 
253 bool FGPropertyNode::SetDouble (const string &name, double val)
254 {
255  return setDoubleValue(name.c_str(), val);
256 }
257 
258 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
259 
260 bool FGPropertyNode::SetString (const string &name, const string &val)
261 {
262  return setStringValue(name.c_str(), val.c_str());
263 }
264 
265 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 
267 void FGPropertyNode::SetArchivable (const string &name, bool state )
268 {
269  SGPropertyNode * node = getNode(name.c_str());
270  if (node == 0)
271  cerr <<
272  "Attempt to set archive flag for non-existent property "
273  << name << endl;
274  else
275  node->setAttribute(SGPropertyNode::ARCHIVE, state);
276 }
277 
278 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279 
280 void FGPropertyNode::SetReadable (const string &name, bool state )
281 {
282  SGPropertyNode * node = getNode(name.c_str());
283  if (node == 0)
284  cerr <<
285  "Attempt to set read flag for non-existant property "
286  << name << endl;
287  else
288  node->setAttribute(SGPropertyNode::READ, state);
289 }
290 
291 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292 
293 void FGPropertyNode::SetWritable (const string &name, bool state )
294 {
295  SGPropertyNode * node = getNode(name.c_str());
296  if (node == 0)
297  cerr <<
298  "Attempt to set write flag for non-existant property "
299  << name << endl;
300  else
301  node->setAttribute(SGPropertyNode::WRITE, state);
302 }
303 
304 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 
306 void FGPropertyManager::Untie (const string &name)
307 {
308  SGPropertyNode* property = root->getNode(name.c_str());
309  if (!property) {
310  cerr << "Attempt to untie a non-existant property." << name << endl;
311  return;
312  }
313 
314  vector <SGPropertyNode_ptr>::iterator it;
315  for (it = tied_properties.begin(); it != tied_properties.end(); ++it) {
316  if (*it == property) {
317  property->untie();
318  tied_properties.erase(it);
319  if (FGJSBBase::debug_lvl & 0x20) cout << "Untied " << name << endl;
320  return;
321  }
322  }
323 
324  cerr << "Failed to untie property " << name << endl
325  << "JSBSim is not the owner of this property." << endl;
326 }
327 
328 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329 
330 void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
331 {
332  SGPropertyNode* property = root->getNode(name.c_str(), true);
333  if (!property) {
334  cerr << "Could not get or create property " << name << endl;
335  return;
336  }
337 
338  if (!property->tie(SGRawValuePointer<bool>(pointer), useDefault))
339  cerr << "Failed to tie property " << name << " to a pointer" << endl;
340  else {
341  tied_properties.push_back(property);
342  if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
343  }
344 }
345 
346 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 
348 void FGPropertyManager::Tie (const string &name, int *pointer,
349  bool useDefault )
350 {
351  SGPropertyNode* property = root->getNode(name.c_str(), true);
352  if (!property) {
353  cerr << "Could not get or create property " << name << endl;
354  return;
355  }
356 
357  if (!property->tie(SGRawValuePointer<int>(pointer), useDefault))
358  cerr << "Failed to tie property " << name << " to a pointer" << endl;
359  else {
360  tied_properties.push_back(property);
361  if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
362  }
363 }
364 
365 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366 
367 void FGPropertyManager::Tie (const string &name, long *pointer,
368  bool useDefault )
369 {
370  SGPropertyNode* property = root->getNode(name.c_str(), true);
371  if (!property) {
372  cerr << "Could not get or create property " << name << endl;
373  return;
374  }
375 
376  if (!property->tie(SGRawValuePointer<long>(pointer), useDefault))
377  cerr << "Failed to tie property " << name << " to a pointer" << endl;
378  else {
379  tied_properties.push_back(property);
380  if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
381  }
382 }
383 
384 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385 
386 void FGPropertyManager::Tie (const string &name, float *pointer,
387  bool useDefault )
388 {
389  SGPropertyNode* property = root->getNode(name.c_str(), true);
390  if (!property) {
391  cerr << "Could not get or create property " << name << endl;
392  return;
393  }
394 
395  if (!property->tie(SGRawValuePointer<float>(pointer), useDefault))
396  cerr << "Failed to tie property " << name << " to a pointer" << endl;
397  else {
398  tied_properties.push_back(property);
399  if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
400  }
401 }
402 
403 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404 
405 void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault)
406 {
407  SGPropertyNode* property = root->getNode(name.c_str(), true);
408  if (!property) {
409  cerr << "Could not get or create property " << name << endl;
410  return;
411  }
412 
413  if (!property->tie(SGRawValuePointer<double>(pointer), useDefault))
414  cerr << "Failed to tie property " << name << " to a pointer" << endl;
415  else {
416  tied_properties.push_back(property);
417  if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
418  }
419 }
420 
421 } // namespace JSBSim
Class wrapper for property handling.
STL namespace.