5 #include "performancedb.hxx"
7 #include <boost/foreach.hpp>
9 #include <simgear/sg_inlines.h>
10 #include <simgear/misc/sg_path.hxx>
11 #include <simgear/props/props.hxx>
12 #include <simgear/props/props_io.hxx>
13 #include <simgear/structure/exception.hxx>
15 #include <Main/globals.hxx>
19 #include "performancedata.hxx"
24 PerformanceDB::PerformanceDB()
29 PerformanceDB::~PerformanceDB()
33 void PerformanceDB::init()
35 SGPath dbpath( globals->get_fg_root() );
36 dbpath.append( "/AI/Aircraft/" );
37 dbpath.append( "performancedb.xml");
40 if (getDefaultPerformance() == 0) {
41 SG_LOG(SG_AI, SG_WARN, "PerformanceDB: no default performance data found/loaded");
45 void PerformanceDB::shutdown()
47 PerformanceDataDict::iterator it;
48 for (it = _db.begin(); it != _db.end(); ++it) {
56 void PerformanceDB::update(double dt)
62 void PerformanceDB::registerPerformanceData(const std::string& id, PerformanceData* data) {
63 //TODO if key exists already replace data "inplace", i.e. copy to existing PerfData instance
64 // this updates all aircraft currently using the PerfData instance.
68 PerformanceData* PerformanceDB::getDataFor(const string& acType, const string& acClass) const
70 // first, try with the specific aircraft type, such as 738 or A322
71 PerformanceDataDict::const_iterator it;
72 it = _db.find(acType);
73 if (it != _db.end()) {
77 const string& alias = findAlias(acType);
79 if (it != _db.end()) {
83 it = _db.find(acClass);
84 if (it == _db.end()) {
85 return getDefaultPerformance();
91 PerformanceData* PerformanceDB::getDefaultPerformance() const
93 PerformanceDataDict::const_iterator it = _db.find("jet_transport");
100 bool PerformanceDB::havePerformanceDataForAircraftType(const std::string& acType) const
102 PerformanceDataDict::const_iterator it = _db.find(acType);
106 const std::string alias(findAlias(acType));
107 return (_db.find(alias) != _db.end());
110 void PerformanceDB::load(const SGPath& filename)
114 readProperties(filename.str(), &root);
115 } catch (const sg_exception &) {
116 SG_LOG(SG_AI, SG_ALERT,
117 "Error reading AI aircraft performance database: " << filename.str());
121 SGPropertyNode * node = root.getNode("performancedb");
122 for (int i = 0; i < node->nChildren(); i++) {
123 SGPropertyNode * db_node = node->getChild(i);
124 if (!strcmp(db_node->getName(), "aircraft")) {
125 PerformanceData* data = NULL;
126 if (db_node->hasChild("base")) {
127 const string& baseName = db_node->getStringValue("base");
128 PerformanceData* baseData = _db[baseName];
130 SG_LOG(SG_AI, SG_ALERT,
131 "Error reading AI aircraft performance database: unknown base type " << baseName);
135 // clone base data to 'inherit' from it
136 data = new PerformanceData(baseData);
138 data = new PerformanceData;
141 data->initFromProps(db_node);
142 const string& name = db_node->getStringValue("type", "heavy_jet");
143 registerPerformanceData(name, data);
144 } else if (!strcmp(db_node->getName(), "alias")) {
145 const string& alias(db_node->getStringValue("alias"));
147 SG_LOG(SG_AI, SG_ALERT, "performance DB alias entry with no <alias> definition");
151 BOOST_FOREACH(SGPropertyNode* matchNode, db_node->getChildren("match")) {
152 const string& match(matchNode->getStringValue());
153 _aliases.push_back(StringPair(match, alias));
156 SG_LOG(SG_AI, SG_ALERT, "unrecognized performance DB entry:" << db_node->getName());
158 } // of nodes iteration
161 const string& PerformanceDB::findAlias(const string& acType) const
163 BOOST_FOREACH(const StringPair& alias, _aliases) {
164 if (acType.find(alias.first) == 0) { // matched!
167 } // of alias iteration
169 static const string empty;