1
0
Fork 0
flightgear/src/AIModel/performancedb.cxx

174 lines
4.7 KiB
C++
Raw Normal View History

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "performancedb.hxx"
#include <boost/foreach.hpp>
2015-12-19 08:29:00 +00:00
#include <simgear/sg_inlines.h>
2009-05-05 10:36:38 +00:00
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
2015-12-19 08:29:00 +00:00
#include <simgear/structure/exception.hxx>
2009-05-05 10:36:38 +00:00
#include <Main/globals.hxx>
#include <iostream>
#include <fstream>
#include "performancedata.hxx"
2009-05-05 10:36:38 +00:00
using std::string;
using std::cerr;
PerformanceDB::PerformanceDB()
{
2015-12-19 08:29:00 +00:00
}
PerformanceDB::~PerformanceDB()
{
}
2015-12-19 08:29:00 +00:00
void PerformanceDB::init()
{
SGPath dbpath( globals->get_fg_root() );
2009-05-05 10:36:38 +00:00
dbpath.append( "/AI/Aircraft/" );
2015-12-19 08:29:00 +00:00
dbpath.append( "performancedb.xml");
2009-05-05 10:36:38 +00:00
load(dbpath);
2015-12-19 08:29:00 +00:00
if (getDefaultPerformance() == 0) {
SG_LOG(SG_AI, SG_WARN, "PerformanceDB: no default performance data found/loaded");
}
}
2015-12-19 08:29:00 +00:00
void PerformanceDB::shutdown()
{
PerformanceDataDict::iterator it;
for (it = _db.begin(); it != _db.end(); ++it) {
delete it->second;
}
2015-12-19 08:29:00 +00:00
_db.clear();
_aliases.clear();
}
void PerformanceDB::update(double dt)
{
SG_UNUSED(dt);
suspend();
}
void PerformanceDB::registerPerformanceData(const std::string& id, PerformanceData* data) {
//TODO if key exists already replace data "inplace", i.e. copy to existing PerfData instance
// this updates all aircraft currently using the PerfData instance.
_db[id] = data;
}
2015-12-19 08:29:00 +00:00
PerformanceData* PerformanceDB::getDataFor(const string& acType, const string& acClass) const
{
// first, try with the specific aircraft type, such as 738 or A322
2015-12-19 08:29:00 +00:00
PerformanceDataDict::const_iterator it;
it = _db.find(acType);
if (it != _db.end()) {
return it->second;
}
const string& alias = findAlias(acType);
2015-12-19 08:29:00 +00:00
it = _db.find(alias);
if (it != _db.end()) {
return it->second;
}
2015-12-19 08:29:00 +00:00
it = _db.find(acClass);
if (it == _db.end()) {
return getDefaultPerformance();
}
2015-12-19 08:29:00 +00:00
return it->second;
}
PerformanceData* PerformanceDB::getDefaultPerformance() const
{
PerformanceDataDict::const_iterator it = _db.find("jet_transport");
if (it == _db.end())
return NULL;
return it->second;
}
bool PerformanceDB::havePerformanceDataForAircraftType(const std::string& acType) const
{
PerformanceDataDict::const_iterator it = _db.find(acType);
if (it != _db.end())
return true;
const std::string alias(findAlias(acType));
return (_db.find(alias) != _db.end());
}
2009-05-05 10:36:38 +00:00
void PerformanceDB::load(const SGPath& filename)
{
2009-05-05 10:36:38 +00:00
SGPropertyNode root;
try {
2016-06-21 11:28:35 +00:00
readProperties(filename, &root);
2009-06-27 08:09:10 +00:00
} catch (const sg_exception &) {
SG_LOG(SG_AI, SG_ALERT,
2016-06-21 11:28:35 +00:00
"Error reading AI aircraft performance database: " << filename);
2009-05-05 10:36:38 +00:00
return;
}
SGPropertyNode * node = root.getNode("performancedb");
for (int i = 0; i < node->nChildren(); i++) {
2009-05-05 10:36:38 +00:00
SGPropertyNode * db_node = node->getChild(i);
if (!strcmp(db_node->getName(), "aircraft")) {
PerformanceData* data = NULL;
if (db_node->hasChild("base")) {
const 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);
const string& name = db_node->getStringValue("type", "heavy_jet");
registerPerformanceData(name, data);
} else if (!strcmp(db_node->getName(), "alias")) {
const 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")) {
const 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
2009-05-05 10:36:38 +00:00
}
const 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
static const string empty;
return empty;
}