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