]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/performancedb.cxx
Don't duplicate userpos in in AIObjects.
[flightgear.git] / src / AIModel / performancedb.cxx
1 #ifdef HAVE_CONFIG_H
2   #include "config.h"
3 #endif
4
5 #include "performancedb.hxx"
6
7 #include <boost/foreach.hpp>
8
9 #include <simgear/misc/sg_path.hxx>
10 #include <simgear/props/props.hxx>
11 #include <simgear/props/props_io.hxx>
12 #include <simgear/xml/easyxml.hxx>
13
14 #include <Main/globals.hxx>
15 #include <iostream>
16 #include <fstream>
17
18 #include "performancedata.hxx"
19
20 using std::string;
21 using std::cerr;
22
23 PerformanceDB::PerformanceDB()
24 {
25     SGPath dbpath( globals->get_fg_root() );
26     
27
28     dbpath.append( "/AI/Aircraft/" );
29     dbpath.append( "performancedb.xml"); 
30     load(dbpath);
31 }
32
33
34 PerformanceDB::~PerformanceDB()
35 {}
36
37 void PerformanceDB::registerPerformanceData(const std::string& id, PerformanceData* data) {
38     //TODO if key exists already replace data "inplace", i.e. copy to existing PerfData instance
39     // this updates all aircraft currently using the PerfData instance.
40     _db[id] = data;
41 }
42
43 PerformanceData* PerformanceDB::getDataFor(const string& acType, const string& acClass)
44 {
45   // first, try with the specific aircraft type, such as 738 or A322
46     if (_db.find(acType) != _db.end()) {
47         return _db[acType];
48     }
49     
50     const string& alias = findAlias(acType);
51     if (_db.find(alias) != _db.end()) {
52       return _db[alias];
53     }
54   
55     SG_LOG(SG_AI, SG_INFO, "no performance data for " << acType);
56   
57     if (_db.find(acClass) == _db.end()) {
58         return _db["jet_transport"];
59     }
60   
61     return _db[acClass];
62 }
63
64 void PerformanceDB::load(const SGPath& filename)
65 {
66     SGPropertyNode root;
67     try {
68         readProperties(filename.str(), &root);
69     } catch (const sg_exception &) {
70         SG_LOG(SG_AI, SG_ALERT,
71             "Error reading AI aircraft performance database: " << filename.str());
72         return;
73     }
74
75     SGPropertyNode * node = root.getNode("performancedb");
76     for (int i = 0; i < node->nChildren(); i++) {
77         SGPropertyNode * db_node = node->getChild(i);
78         if (!strcmp(db_node->getName(), "aircraft")) {
79             PerformanceData* data = NULL;
80             if (db_node->hasChild("base")) {
81               const string& baseName = db_node->getStringValue("base");
82               PerformanceData* baseData = _db[baseName];
83               if (!baseData) {
84                 SG_LOG(SG_AI, SG_ALERT,
85                        "Error reading AI aircraft performance database: unknown base type " << baseName);
86                 return;
87               }
88               
89               // clone base data to 'inherit' from it
90               data = new PerformanceData(baseData); 
91             } else {
92               data = new PerformanceData;
93             }
94           
95             data->initFromProps(db_node);
96             const string& name  = db_node->getStringValue("type", "heavy_jet");
97             registerPerformanceData(name, data);
98         } else if (!strcmp(db_node->getName(), "alias")) {
99             const string& alias(db_node->getStringValue("alias"));
100             if (alias.empty()) {
101                 SG_LOG(SG_AI, SG_ALERT, "performance DB alias entry with no <alias> definition");
102                 continue;
103             }
104           
105             BOOST_FOREACH(SGPropertyNode* matchNode, db_node->getChildren("match")) {
106                 const string& match(matchNode->getStringValue());
107                 _aliases.push_back(StringPair(match, alias));
108             }
109         } else {
110             SG_LOG(SG_AI, SG_ALERT, "unrecognized performance DB entry:" << db_node->getName());
111         }
112     } // of nodes iteration
113 }
114
115 const string& PerformanceDB::findAlias(const string& acType) const
116 {
117     BOOST_FOREACH(const StringPair& alias, _aliases) {
118         if (acType.find(alias.first) == 0) { // matched!
119             return alias.second;
120         }
121     } // of alias iteration
122   
123     static const string empty;
124     return empty;
125 }
126
127