]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/performancedb.cxx
toggle fullscreen: also adapt GUI plane when resizing
[flightgear.git] / src / AIModel / performancedb.cxx
index e8dd2361e93ab2adeb88a5f894b5b3b9546791c7..a5230a59a1f3d7a196bed6ba88720a0b1f4be053 100644 (file)
@@ -1,24 +1,33 @@
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
 #include "performancedb.hxx"
 
+#include <boost/foreach.hpp>
+
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/props/props.hxx>
+#include <simgear/props/props_io.hxx>
+#include <simgear/xml/easyxml.hxx>
+
+#include <Main/globals.hxx>
+#include <iostream>
+#include <fstream>
+
+#include "performancedata.hxx"
+
+using std::string;
+using std::cerr;
+
 PerformanceDB::PerformanceDB()
 {
-    // these are the 6 classes originally defined in the PERFSTRUCT
-    // Plus a few more for testing
-    registerPerformanceData("heavy_jet", new PerformanceData(
-        4.0, 2.0,  3000.0, 1500.0,  150.0, 160.0,  300.0, 430.0,  300.0,  170.0, 150.0, 15.0));
-    registerPerformanceData("light", new PerformanceData(
-        2.0, 2.0,  450.0, 1000.0,  70.0, 70.0,  80.0, 100.0,  80.0,  70.0, 60.0, 15.0));
-    registerPerformanceData("ww2_fighter", new PerformanceData(
-        4.0, 2.0,  3000.0, 1500.0,  110.0, 110.0,  180.0, 250.0,  200.0,  130.0, 100.0, 15.0));
-    registerPerformanceData("jet_fighter", new PerformanceData(
-        7.0, 3.0,  4000.0, 2000.0,  120.0, 150.0,  350.0, 500.0,  350.0,  170.0, 150.0, 15.0));
-    registerPerformanceData("jet_transport", new PerformanceData(
-        5.0, 2.0,  3000.0, 1500.0,  100.0, 140.0,  300.0, 430.0,  300.0,  170.0, 130.0, 15.0));
-    registerPerformanceData("tanker", new PerformanceData(
-        5.0, 2.0,  3000.0, 1500.0,  100.0, 140.0,  300.0, 430.0,  300.0,  170.0, 130.0, 15.0));
-    registerPerformanceData("ufo", new PerformanceData(
-        30.0, 30.0, 6000.0, 6000.0, 150.0, 150.0, 300.0, 430.0, 300.0, 170.0, 130.0, 15.0));
+    SGPath dbpath( globals->get_fg_root() );
+    
 
+    dbpath.append( "/AI/Aircraft/" );
+    dbpath.append( "performancedb.xml"); 
+    load(dbpath);
 }
 
 
@@ -31,13 +40,87 @@ void PerformanceDB::registerPerformanceData(const std::string& id, PerformanceDa
     _db[id] = data;
 }
 
-void PerformanceDB::registerPerformanceData(const std::string& id, const std::string& filename) {
-    registerPerformanceData(id, new PerformanceData(filename));
+PerformanceData* PerformanceDB::getDataFor(const string& acType, const string& acClass)
+{
+  // first, try with the specific aircraft type, such as 738 or A322
+    if (_db.find(acType) != _db.end()) {
+        return _db[acType];
+    }
+    
+    string alias = findAlias(acType);
+    if (_db.find(alias) != _db.end()) {
+      return _db[alias];
+    }
+  
+    SG_LOG(SG_AI, SG_INFO, "no performance data for " << acType);
+  
+    if (_db.find(acClass) == _db.end()) {
+        return _db["jet_transport"];
+    }
+  
+    return _db[acClass];
 }
 
-PerformanceData* PerformanceDB::getDataFor(const std::string& id) {
-    if (_db.find(id) == _db.end()) // id not found -> return jet_transport data
-        return _db["jet_transport"];
+void PerformanceDB::load(const SGPath& filename)
+{
+    SGPropertyNode root;
+    try {
+        readProperties(filename.str(), &root);
+    } catch (const sg_exception &) {
+        SG_LOG(SG_AI, SG_ALERT,
+            "Error reading AI aircraft performance database: " << filename.str());
+        return;
+    }
 
-    return _db[id];
+    SGPropertyNode * node = root.getNode("performancedb");
+    for (int i = 0; i < node->nChildren(); i++) {
+        SGPropertyNode * db_node = node->getChild(i);
+        if (!strcmp(db_node->getName(), "aircraft")) {
+            PerformanceData* data = NULL;
+            if (db_node->hasChild("base")) {
+              string baseName = db_node->getStringValue("base");
+              PerformanceData* baseData = _db[baseName];
+              if (!baseData) {
+                SG_LOG(SG_AI, SG_ALERT,
+                       "Error reading AI aircraft performance database: unknown base type " << baseName);
+                return;
+              }
+              
+              // clone base data to 'inherit' from it
+              data = new PerformanceData(baseData); 
+            } else {
+              data = new PerformanceData;
+            }
+          
+            data->initFromProps(db_node);
+            string name  = db_node->getStringValue("type", "heavy_jet");
+            registerPerformanceData(name, data);
+        } else if (!strcmp(db_node->getName(), "alias")) {
+            string alias(db_node->getStringValue("alias"));
+            if (alias.empty()) {
+                SG_LOG(SG_AI, SG_ALERT, "performance DB alias entry with no <alias> definition");
+                continue;
+            }
+          
+            BOOST_FOREACH(SGPropertyNode* matchNode, db_node->getChildren("match")) {
+                string match(matchNode->getStringValue());
+                _aliases.push_back(StringPair(match, alias));
+            }
+        } else {
+            SG_LOG(SG_AI, SG_ALERT, "unrecognized performance DB entry:" << db_node->getName());
+        }
+    } // of nodes iteration
 }
+
+string PerformanceDB::findAlias(const string& acType) const
+{
+    BOOST_FOREACH(const StringPair& alias, _aliases) {
+        if (acType.find(alias.first) == 0) { // matched!
+            return alias.second;
+        }
+    } // of alias iteration
+  
+    return string();
+}
+
+