JSBSim Flight Dynamics Model  1.1.11 (13 Feb 2022)
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 <assert.h>
32 #include "FGPropertyManager.h"
33 
34 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 DEFINITIONS
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
37 
38 
39 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 FORWARD DECLARATIONS
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
42 
43 using namespace std;
44 
45 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46 COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
47 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 */
49 
50 namespace JSBSim {
51 
52 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 
54 void FGPropertyManager::Unbind(void)
55 {
56  for(auto& prop: tied_properties)
57  prop->untie();
58 
59  tied_properties.clear();
60 }
61 
62 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63 
64 string FGPropertyManager::mkPropertyName(string name, bool lowercase) {
65 
66  /* do this two pass to avoid problems with characters getting skipped
67  because the index changed */
68  unsigned i;
69  for(i=0;i<name.length();i++) {
70  if( lowercase && isupper(name[i]) )
71  name[i]=tolower(name[i]);
72  else if( isspace(name[i]) )
73  name[i]='-';
74  }
75 
76  return name;
77 }
78 
79 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80 
82 FGPropertyNode::GetNode (const string &path, bool create)
83 {
84  SGPropertyNode* node = getNode(path.c_str(), create);
85  if (node == 0) {
86  cerr << "FGPropertyManager::GetNode() No node found for " << path << endl;
87  }
88  return (FGPropertyNode*)node;
89 }
90 
91 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92 
94 FGPropertyNode::GetNode (const string &relpath, int index, bool create)
95 {
96  SGPropertyNode* node = getNode(relpath.c_str(), index, create);
97  if (node == 0) {
98  cerr << "FGPropertyManager::GetNode() No node found for " << relpath
99  << "[" << index << "]" << endl;
100  }
101  return (FGPropertyNode*)node;
102 }
103 
104 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
105 
106 bool FGPropertyNode::HasNode (const string &path)
107 {
108  const SGPropertyNode* node = getNode(path.c_str(), false);
109  return (node != 0);
110 }
111 
112 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113 
114 string FGPropertyNode::GetPrintableName( void ) const
115 {
116  string temp_string(getNameString());
117  size_t initial_location=0;
118  size_t found_location;
119 
120  found_location = temp_string.rfind("/");
121  if (found_location != string::npos)
122  temp_string = temp_string.substr(found_location);
123 
124  found_location = temp_string.find('_',initial_location);
125  while (found_location != string::npos) {
126  temp_string.replace(found_location,1," ");
127  initial_location = found_location+1;
128  found_location = temp_string.find('_',initial_location);
129  }
130  return temp_string;
131 }
132 
133 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 
135 string FGPropertyNode::GetFullyQualifiedName(void) const
136 {
137  vector<string> stack;
138  stack.push_back( getDisplayName(true) );
139  const SGPropertyNode* tmpn=getParent();
140  bool atroot=false;
141  while( !atroot ) {
142  stack.push_back( tmpn->getDisplayName(true) );
143  if( !tmpn->getParent() )
144  atroot=true;
145  else
146  tmpn=tmpn->getParent();
147  }
148 
149  string fqname="";
150  for(size_t i=stack.size()-1;i>0;i--) {
151  fqname+= stack[i];
152  fqname+= "/";
153  }
154  fqname+= stack[0];
155  return fqname;
156 
157 }
158 
159 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160 
161 string FGPropertyNode::GetRelativeName( const string &path ) const
162 {
163  string temp_string = GetFullyQualifiedName();
164  size_t len = path.length();
165  if ( (len > 0) && (temp_string.substr(0,len) == path) ) {
166  temp_string = temp_string.erase(0,len);
167  }
168  return temp_string;
169 }
170 
171 
172 
173 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
174 
175 bool FGPropertyNode::GetBool (const string &name, bool defaultValue) const
176 {
177  return getBoolValue(name.c_str(), defaultValue);
178 }
179 
180 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
181 
182 int FGPropertyNode::GetInt (const string &name, int defaultValue ) const
183 {
184  return getIntValue(name.c_str(), defaultValue);
185 }
186 
187 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
188 
189 int FGPropertyNode::GetLong (const string &name, long defaultValue ) const
190 {
191  return getLongValue(name.c_str(), defaultValue);
192 }
193 
194 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195 
196 float FGPropertyNode::GetFloat (const string &name, float defaultValue ) const
197 {
198  return getFloatValue(name.c_str(), defaultValue);
199 }
200 
201 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202 
203 double FGPropertyNode::GetDouble (const string &name, double defaultValue ) const
204 {
205  return getDoubleValue(name.c_str(), defaultValue);
206 }
207 
208 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209 
210 string FGPropertyNode::GetString (const string &name, string defaultValue ) const
211 {
212  return string(getStringValue(name.c_str(), defaultValue.c_str()));
213 }
214 
215 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216 
217 bool FGPropertyNode::SetBool (const string &name, bool val)
218 {
219  return setBoolValue(name.c_str(), val);
220 }
221 
222 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223 
224 bool FGPropertyNode::SetInt (const string &name, int val)
225 {
226  return setIntValue(name.c_str(), val);
227 }
228 
229 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230 
231 bool FGPropertyNode::SetLong (const string &name, long val)
232 {
233  return setLongValue(name.c_str(), val);
234 }
235 
236 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237 
238 bool FGPropertyNode::SetFloat (const string &name, float val)
239 {
240  return setFloatValue(name.c_str(), val);
241 }
242 
243 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244 
245 bool FGPropertyNode::SetDouble (const string &name, double val)
246 {
247  return setDoubleValue(name.c_str(), val);
248 }
249 
250 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251 
252 bool FGPropertyNode::SetString (const string &name, const string &val)
253 {
254  return setStringValue(name.c_str(), val.c_str());
255 }
256 
257 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 
259 void FGPropertyNode::SetArchivable (const string &name, bool state )
260 {
261  SGPropertyNode * node = getNode(name.c_str());
262  if (node == 0)
263  cerr <<
264  "Attempt to set archive flag for non-existent property "
265  << name << endl;
266  else
267  node->setAttribute(SGPropertyNode::ARCHIVE, state);
268 }
269 
270 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271 
272 void FGPropertyNode::SetReadable (const string &name, bool state )
273 {
274  SGPropertyNode * node = getNode(name.c_str());
275  if (node == 0)
276  cerr <<
277  "Attempt to set read flag for non-existant property "
278  << name << endl;
279  else
280  node->setAttribute(SGPropertyNode::READ, state);
281 }
282 
283 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284 
285 void FGPropertyNode::SetWritable (const string &name, bool state )
286 {
287  SGPropertyNode * node = getNode(name.c_str());
288  if (node == 0)
289  cerr <<
290  "Attempt to set write flag for non-existant property "
291  << name << endl;
292  else
293  node->setAttribute(SGPropertyNode::WRITE, state);
294 }
295 
296 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297 
298 void FGPropertyManager::Untie(const string &name)
299 {
300  SGPropertyNode* property = root->getNode(name.c_str());
301  if (!property) {
302  cerr << "Attempt to untie a non-existant property." << name << endl;
303  return;
304  }
305 
306  Untie(property);
307 }
308 
309 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310 
311 void FGPropertyManager::Untie(SGPropertyNode *property)
312 {
313  const string& name = property->getNameString();
314 
315  assert(property->isTied());
316 
317  for (auto it = tied_properties.begin(); it != tied_properties.end(); ++it) {
318  if (*it == property) {
319  property->untie();
320  tied_properties.erase(it);
321  if (FGJSBBase::debug_lvl & 0x20) cout << "Untied " << name << endl;
322  return;
323  }
324  }
325 
326  cerr << "Failed to untie property " << name << endl
327  << "JSBSim is not the owner of this property." << endl;
328 }
329 } // namespace JSBSim
JSBSim::FGPropertyNode
Class wrapper for property handling.
Definition: FGPropertyManager.h:70