1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 Header: FGPropertyManager.cpp
5 Based on work originally by David Megginson
8 ------------- Copyright (C) 2002 -------------
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
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
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.
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.
27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
31 #include "FGPropertyManager.h"
33 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
38 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
44 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
45 COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
46 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 void FGPropertyManager::Unbind(void)
55 vector<SGPropertyNode_ptr>::iterator it;
57 for (it = tied_properties.begin();it < tied_properties.end();it++)
60 tied_properties.clear();
63 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65 string FGPropertyManager::mkPropertyName(string name, bool lowercase) {
67 /* do this two pass to avoid problems with characters getting skipped
68 because the index changed */
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]) )
80 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 FGPropertyNode::GetNode (const string &path, bool create)
85 SGPropertyNode* node = getNode(path.c_str(), create);
87 cerr << "FGPropertyManager::GetNode() No node found for " << path << endl;
89 return (FGPropertyNode*)node;
92 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
95 FGPropertyNode::GetNode (const string &relpath, int index, bool create)
97 SGPropertyNode* node = getNode(relpath.c_str(), index, create);
99 cerr << "FGPropertyManager::GetNode() No node found for " << relpath
100 << "[" << index << "]" << endl;
102 return (FGPropertyNode*)node;
105 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107 bool FGPropertyNode::HasNode (const string &path)
109 const SGPropertyNode* node = getNode(path.c_str(), false);
113 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
115 string FGPropertyNode::GetName( void ) const
117 return string( getName() );
120 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 string FGPropertyNode::GetPrintableName( void ) const
124 string temp_string(getName());
125 size_t initial_location=0;
126 size_t found_location;
128 found_location = temp_string.rfind("/");
129 if (found_location != string::npos)
130 temp_string = temp_string.substr(found_location);
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);
141 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 string FGPropertyNode::GetFullyQualifiedName(void) const
145 vector<string> stack;
146 stack.push_back( getDisplayName(true) );
147 const SGPropertyNode* tmpn=getParent();
150 stack.push_back( tmpn->getDisplayName(true) );
151 if( !tmpn->getParent() )
154 tmpn=tmpn->getParent();
158 for(unsigned i=stack.size()-1;i>0;i--) {
167 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 string FGPropertyNode::GetRelativeName( const string &path ) const
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);
181 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183 bool FGPropertyNode::GetBool (const string &name, bool defaultValue) const
185 return getBoolValue(name.c_str(), defaultValue);
188 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190 int FGPropertyNode::GetInt (const string &name, int defaultValue ) const
192 return getIntValue(name.c_str(), defaultValue);
195 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197 int FGPropertyNode::GetLong (const string &name, long defaultValue ) const
199 return getLongValue(name.c_str(), defaultValue);
202 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204 float FGPropertyNode::GetFloat (const string &name, float defaultValue ) const
206 return getFloatValue(name.c_str(), defaultValue);
209 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
211 double FGPropertyNode::GetDouble (const string &name, double defaultValue ) const
213 return getDoubleValue(name.c_str(), defaultValue);
216 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218 string FGPropertyNode::GetString (const string &name, string defaultValue ) const
220 return string(getStringValue(name.c_str(), defaultValue.c_str()));
223 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
225 bool FGPropertyNode::SetBool (const string &name, bool val)
227 return setBoolValue(name.c_str(), val);
230 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232 bool FGPropertyNode::SetInt (const string &name, int val)
234 return setIntValue(name.c_str(), val);
237 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
239 bool FGPropertyNode::SetLong (const string &name, long val)
241 return setLongValue(name.c_str(), val);
244 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246 bool FGPropertyNode::SetFloat (const string &name, float val)
248 return setFloatValue(name.c_str(), val);
251 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253 bool FGPropertyNode::SetDouble (const string &name, double val)
255 return setDoubleValue(name.c_str(), val);
258 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 bool FGPropertyNode::SetString (const string &name, const string &val)
262 return setStringValue(name.c_str(), val.c_str());
265 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
267 void FGPropertyNode::SetArchivable (const string &name, bool state )
269 SGPropertyNode * node = getNode(name.c_str());
272 "Attempt to set archive flag for non-existent property "
275 node->setAttribute(SGPropertyNode::ARCHIVE, state);
278 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280 void FGPropertyNode::SetReadable (const string &name, bool state )
282 SGPropertyNode * node = getNode(name.c_str());
285 "Attempt to set read flag for non-existant property "
288 node->setAttribute(SGPropertyNode::READ, state);
291 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293 void FGPropertyNode::SetWritable (const string &name, bool state )
295 SGPropertyNode * node = getNode(name.c_str());
298 "Attempt to set write flag for non-existant property "
301 node->setAttribute(SGPropertyNode::WRITE, state);
304 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306 void FGPropertyManager::Untie (const string &name)
308 SGPropertyNode* property = root->getNode(name.c_str());
310 cerr << "Attempt to untie a non-existant property." << name << endl;
314 vector <SGPropertyNode_ptr>::iterator it;
315 for (it = tied_properties.begin(); it != tied_properties.end(); ++it) {
316 if (*it == property) {
318 tied_properties.erase(it);
319 if (FGJSBBase::debug_lvl & 0x20) cout << "Untied " << name << endl;
324 cerr << "Failed to untie property " << name << endl
325 << "JSBSim is not the owner of this property." << endl;
328 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330 void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
332 SGPropertyNode* property = root->getNode(name.c_str(), true);
334 cerr << "Could not get or create property " << name << endl;
338 if (!property->tie(SGRawValuePointer<bool>(pointer), useDefault))
339 cerr << "Failed to tie property " << name << " to a pointer" << endl;
341 tied_properties.push_back(property);
342 if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
346 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348 void FGPropertyManager::Tie (const string &name, int *pointer,
351 SGPropertyNode* property = root->getNode(name.c_str(), true);
353 cerr << "Could not get or create property " << name << endl;
357 if (!property->tie(SGRawValuePointer<int>(pointer), useDefault))
358 cerr << "Failed to tie property " << name << " to a pointer" << endl;
360 tied_properties.push_back(property);
361 if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
365 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367 void FGPropertyManager::Tie (const string &name, long *pointer,
370 SGPropertyNode* property = root->getNode(name.c_str(), true);
372 cerr << "Could not get or create property " << name << endl;
376 if (!property->tie(SGRawValuePointer<long>(pointer), useDefault))
377 cerr << "Failed to tie property " << name << " to a pointer" << endl;
379 tied_properties.push_back(property);
380 if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
384 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386 void FGPropertyManager::Tie (const string &name, float *pointer,
389 SGPropertyNode* property = root->getNode(name.c_str(), true);
391 cerr << "Could not get or create property " << name << endl;
395 if (!property->tie(SGRawValuePointer<float>(pointer), useDefault))
396 cerr << "Failed to tie property " << name << " to a pointer" << endl;
398 tied_properties.push_back(property);
399 if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
403 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
405 void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault)
407 SGPropertyNode* property = root->getNode(name.c_str(), true);
409 cerr << "Could not get or create property " << name << endl;
413 if (!property->tie(SGRawValuePointer<double>(pointer), useDefault))
414 cerr << "Failed to tie property " << name << " to a pointer" << endl;
416 tied_properties.push_back(property);
417 if (FGJSBBase::debug_lvl & 0x20) cout << name << endl;
421 } // namespace JSBSim