From dc6a88492823b0f4033bb719de1f9953e5f6cbda Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 23 May 2018 09:46:05 +0100 Subject: [PATCH] Generalise AI-model search ordering in AIBase Make the policy of using models in FGData/AI more flexible, with the option to prefer normal data sources. Keep the existing behaviour for everything except multiplayer aircraft, where we now prefer the data model (presumably, an installed aircraft) over the AI one. --- src/AIModel/AIBallistic.cxx | 5 +-- src/AIModel/AIBallistic.hxx | 2 +- src/AIModel/AIBase.cxx | 58 +++++++++++++++++++++------------ src/AIModel/AIBase.hxx | 10 +++++- src/AIModel/AICarrier.cxx | 4 +-- src/AIModel/AICarrier.hxx | 2 +- src/AIModel/AIEscort.cxx | 4 +-- src/AIModel/AIEscort.hxx | 2 +- src/AIModel/AIGroundVehicle.cxx | 4 +-- src/AIModel/AIGroundVehicle.hxx | 2 +- src/AIModel/AIManager.cxx | 15 +++++++-- src/AIModel/AIMultiplayer.cxx | 7 ++-- src/AIModel/AIMultiplayer.hxx | 2 +- src/AIModel/AIShip.cxx | 4 +-- src/AIModel/AIShip.hxx | 2 +- src/AIModel/AIStatic.cxx | 13 -------- src/AIModel/AIStatic.hxx | 3 -- src/AIModel/AIStorm.cxx | 13 -------- src/AIModel/AIStorm.hxx | 3 -- src/AIModel/AIThermal.cxx | 4 +-- src/AIModel/AIThermal.hxx | 2 +- src/AIModel/AIWingman.cxx | 5 +-- src/AIModel/AIWingman.hxx | 2 +- 23 files changed, 87 insertions(+), 81 deletions(-) diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index 3a8eb46e4..9123d9483 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -131,8 +131,9 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) { setParentName(scFileNode->getStringValue("parent")); } -bool FGAIBallistic::init(bool search_in_AI_path) { - FGAIBase::init(search_in_AI_path); +bool FGAIBallistic::init(ModelSearchOrder searchOrder) +{ + FGAIBase::init(searchOrder); reinit(); return true; } diff --git a/src/AIModel/AIBallistic.hxx b/src/AIModel/AIBallistic.hxx index 7abe4f2cd..2d9a0caea 100644 --- a/src/AIModel/AIBallistic.hxx +++ b/src/AIModel/AIBallistic.hxx @@ -40,7 +40,7 @@ public: void readFromScenario(SGPropertyNode* scFileNode); - bool init(bool search_in_AI_path=false); + bool init(ModelSearchOrder searchOrder) override; virtual void bind(); virtual void reinit(); virtual void update(double dt); diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index f163afe4d..bf200125b 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -378,7 +378,43 @@ void FGAIBase::Transform() { } -bool FGAIBase::init(bool search_in_AI_path) +std::string FGAIBase::resolveModelPath(ModelSearchOrder searchOrder) +{ + std::string aiPath; + if (searchOrder != DATA_ONLY) { + for (SGPath p : globals->get_data_paths("AI")) { + p.append(model_path); + if (p.exists()) { + aiPath = p.local8BitStr(); + break; + } + } // of AI data paths iteration + } + + // if we prefer AI, and it's valid, use it, we're done + if ((searchOrder == PREFER_AI) && !aiPath.empty()) { + _installed = true; + return aiPath; + } + + // regular search including aircraft paths + auto p = simgear::SGModelLib::findDataFile(model_path); + if (!p.empty()) { + _installed = true; + return p; + } + + // if we prefer data, but will still use AI paths, now is the time. + if ((searchOrder == PREFER_DATA) && !aiPath.empty()) { + _installed = true; + return aiPath; + } + + // okay, out of options, use the default model (the blue glider) + return fgGetString("/sim/multiplay/default-model", default_model); +} + +bool FGAIBase::init(ModelSearchOrder searchOrder) { if (_model.valid()) { @@ -386,26 +422,8 @@ bool FGAIBase::init(bool search_in_AI_path) return false; } - string f; - if(search_in_AI_path) - { - BOOST_FOREACH(SGPath p, globals->get_data_paths("AI")) { - p.append(model_path); - if (p.exists()) { - f = p.local8BitStr(); - break; - } - } // of AI data paths iteration - } // of search in AI path - - if (f.empty()) { - f = simgear::SGModelLib::findDataFile(model_path); - } + string f = resolveModelPath(searchOrder); - if(f.empty()) - f = fgGetString("/sim/multiplay/default-model", default_model); - else - _installed = true; props->addChild("type")->setStringValue("AI"); _modeldata = new FGAIModelData(props); diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index baf2b375c..6cedfa121 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -57,7 +57,13 @@ public: virtual void readFromScenario(SGPropertyNode* scFileNode); - virtual bool init(bool search_in_AI_path=false); + enum ModelSearchOrder { + DATA_ONLY, // don't search AI/ prefix at all + PREFER_AI, // search AI first, override other paths + PREFER_DATA // search data first but fall back to AI + }; + + virtual bool init(ModelSearchOrder searchOrder); virtual void initModel(); virtual void update(double dt); virtual void bind(); @@ -248,6 +254,8 @@ private: SGSharedPtr _fx; + std::string resolveModelPath(ModelSearchOrder searchOrder); + public: object_type getType(); diff --git a/src/AIModel/AICarrier.cxx b/src/AIModel/AICarrier.cxx index a6f323d63..1514b4b3c 100644 --- a/src/AIModel/AICarrier.cxx +++ b/src/AIModel/AICarrier.cxx @@ -205,8 +205,8 @@ void FGAICarrier::update(double dt) { source = 0; } //end update -bool FGAICarrier::init(bool search_in_AI_path) { - if (!FGAIShip::init(search_in_AI_path)) +bool FGAICarrier::init(ModelSearchOrder searchOrder) { + if (!FGAIShip::init(searchOrder)) return false; _longitude_node = fgGetNode("/position/longitude-deg", true); diff --git a/src/AIModel/AICarrier.hxx b/src/AIModel/AICarrier.hxx index 072599579..d7194f914 100644 --- a/src/AIModel/AICarrier.hxx +++ b/src/AIModel/AICarrier.hxx @@ -64,7 +64,7 @@ public: void ReturnToBox(); bool OutsideBox(); - bool init(bool search_in_AI_path=false); + bool init(ModelSearchOrder searchOrder) override; virtual const char* getTypeString(void) const { return "carrier"; } diff --git a/src/AIModel/AIEscort.cxx b/src/AIModel/AIEscort.cxx index b4662b708..088c89996 100644 --- a/src/AIModel/AIEscort.cxx +++ b/src/AIModel/AIEscort.cxx @@ -118,8 +118,8 @@ void FGAIEscort::bind() { SGRawValuePointer(&_patrol)); } -bool FGAIEscort::init(bool search_in_AI_path) { - if (!FGAIShip::init(search_in_AI_path)) +bool FGAIEscort::init(ModelSearchOrder searchOrder) { + if (!FGAIShip::init(searchOrder)) return false; reinit(); return true; diff --git a/src/AIModel/AIEscort.hxx b/src/AIModel/AIEscort.hxx index 4f0522622..b4c82e82f 100644 --- a/src/AIModel/AIEscort.hxx +++ b/src/AIModel/AIEscort.hxx @@ -40,7 +40,7 @@ public: virtual void readFromScenario(SGPropertyNode* scFileNode); - bool init(bool search_in_AI_path=false); + bool init(ModelSearchOrder searchOrder) override; virtual void bind(); virtual void reinit(); virtual void update (double dt); diff --git a/src/AIModel/AIGroundVehicle.cxx b/src/AIModel/AIGroundVehicle.cxx index da72f905a..521480468 100644 --- a/src/AIModel/AIGroundVehicle.cxx +++ b/src/AIModel/AIGroundVehicle.cxx @@ -121,8 +121,8 @@ void FGAIGroundVehicle::bind() { SGRawValuePointer(&_contact_x2_offset)); } -bool FGAIGroundVehicle::init(bool search_in_AI_path) { - if (!FGAIShip::init(search_in_AI_path)) +bool FGAIGroundVehicle::init(ModelSearchOrder searchOrder) { + if (!FGAIShip::init(searchOrder)) return false; reinit(); return true; diff --git a/src/AIModel/AIGroundVehicle.hxx b/src/AIModel/AIGroundVehicle.hxx index 40cbe1994..a4b118e22 100644 --- a/src/AIModel/AIGroundVehicle.hxx +++ b/src/AIModel/AIGroundVehicle.hxx @@ -38,7 +38,7 @@ public: virtual void readFromScenario(SGPropertyNode* scFileNode); - bool init(bool search_in_AI_path=false); + bool init(ModelSearchOrder searchOrder) override; virtual void bind(); virtual void reinit(); virtual void update (double dt); diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index 74041d56a..745f1786c 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -306,9 +306,18 @@ FGAIManager::attach(FGAIBase *model) model->setManager(this, p); ai_list.push_back(model); - model->init(model->getType()==FGAIBase::otAircraft - || model->getType()==FGAIBase::otMultiplayer - || model->getType()==FGAIBase::otStatic); + FGAIBase::ModelSearchOrder modelPolicy = FGAIBase::DATA_ONLY; + switch (model->getType()) { + case FGAIBase::otAircraft: + case FGAIBase::otStatic: + modelPolicy = FGAIBase::PREFER_AI; + case FGAIBase::otMultiplayer: + modelPolicy = FGAIBase::PREFER_DATA; + default: + break; + } + + model->init(modelPolicy); model->bind(); p->setBoolValue("valid", true); } diff --git a/src/AIModel/AIMultiplayer.cxx b/src/AIModel/AIMultiplayer.cxx index a4b74da66..d565eb192 100644 --- a/src/AIModel/AIMultiplayer.cxx +++ b/src/AIModel/AIMultiplayer.cxx @@ -56,8 +56,9 @@ FGAIMultiplayer::FGAIMultiplayer() : FGAIMultiplayer::~FGAIMultiplayer() { } -bool FGAIMultiplayer::init(bool search_in_AI_path) { - props->setStringValue("sim/model/path", model_path.c_str()); +bool FGAIMultiplayer::init(ModelSearchOrder searchOrder) +{ + props->setStringValue("sim/model/path", model_path); //refuel_node = fgGetNode("systems/refuel/contact", true); isTanker = false; // do this until this property is // passed over the net @@ -73,7 +74,7 @@ bool FGAIMultiplayer::init(bool search_in_AI_path) { } // load model - bool result = FGAIBase::init(search_in_AI_path); + bool result = FGAIBase::init(searchOrder); // propagate installation state (used by MP pilot list) props->setBoolValue("model-installed", _installed); return result; diff --git a/src/AIModel/AIMultiplayer.hxx b/src/AIModel/AIMultiplayer.hxx index c813ef57d..fdfaed525 100644 --- a/src/AIModel/AIMultiplayer.hxx +++ b/src/AIModel/AIMultiplayer.hxx @@ -32,7 +32,7 @@ public: FGAIMultiplayer(); virtual ~FGAIMultiplayer(); - virtual bool init(bool search_in_AI_path=false); + bool init(ModelSearchOrder searchOrder) override; virtual void bind(); virtual void update(double dt); diff --git a/src/AIModel/AIShip.cxx b/src/AIModel/AIShip.cxx index 26883c0cf..ad89c223f 100644 --- a/src/AIModel/AIShip.cxx +++ b/src/AIModel/AIShip.cxx @@ -111,9 +111,9 @@ void FGAIShip::readFromScenario(SGPropertyNode* scFileNode) { } } -bool FGAIShip::init(bool search_in_AI_path) { +bool FGAIShip::init(ModelSearchOrder searchOrder) { reinit(); - return FGAIBase::init(search_in_AI_path); + return FGAIBase::init(searchOrder); } void FGAIShip::reinit() diff --git a/src/AIModel/AIShip.hxx b/src/AIModel/AIShip.hxx index 1c91b6437..c0f62133a 100644 --- a/src/AIModel/AIShip.hxx +++ b/src/AIModel/AIShip.hxx @@ -37,7 +37,7 @@ public: virtual void readFromScenario(SGPropertyNode* scFileNode); - virtual bool init(bool search_in_AI_path=false); + bool init(ModelSearchOrder searchOrder) override; virtual void bind(); virtual void update(double dt); virtual void reinit(); diff --git a/src/AIModel/AIStatic.cxx b/src/AIModel/AIStatic.cxx index 5da570732..cc404b2dd 100644 --- a/src/AIModel/AIStatic.cxx +++ b/src/AIModel/AIStatic.cxx @@ -40,19 +40,6 @@ FGAIStatic::FGAIStatic() : FGAIBase(otStatic, false) { FGAIStatic::~FGAIStatic() { } -bool FGAIStatic::init(bool search_in_AI_path) { - return FGAIBase::init(search_in_AI_path); -} - -void FGAIStatic::bind() { - FGAIBase::bind(); -} - -void FGAIStatic::unbind() { - FGAIBase::unbind(); -} - - void FGAIStatic::update(double dt) { FGAIBase::update(dt); Transform(); diff --git a/src/AIModel/AIStatic.hxx b/src/AIModel/AIStatic.hxx index f7ca53a39..7deb7d558 100644 --- a/src/AIModel/AIStatic.hxx +++ b/src/AIModel/AIStatic.hxx @@ -35,9 +35,6 @@ public: FGAIStatic(); ~FGAIStatic(); - virtual bool init(bool search_in_AI_path=false); - virtual void bind(); - virtual void unbind(); virtual void update(double dt); virtual const char* getTypeString(void) const { return "static"; } diff --git a/src/AIModel/AIStorm.cxx b/src/AIModel/AIStorm.cxx index cbb4225cc..4e10f811b 100644 --- a/src/AIModel/AIStorm.cxx +++ b/src/AIModel/AIStorm.cxx @@ -75,19 +75,6 @@ void FGAIStorm::readFromScenario(SGPropertyNode* scFileNode) { setStrengthNorm(scFileNode->getDoubleValue("strength-norm", 1.0)); } -bool FGAIStorm::init(bool search_in_AI_path) { - return FGAIBase::init(search_in_AI_path); -} - -void FGAIStorm::bind() { - FGAIBase::bind(); -} - -void FGAIStorm::unbind() { - FGAIBase::unbind(); -} - - void FGAIStorm::update(double dt) { FGAIBase::update(dt); Run(dt); diff --git a/src/AIModel/AIStorm.hxx b/src/AIModel/AIStorm.hxx index f6a7e9018..ddc23e28d 100644 --- a/src/AIModel/AIStorm.hxx +++ b/src/AIModel/AIStorm.hxx @@ -37,9 +37,6 @@ public: void readFromScenario(SGPropertyNode* scFileNode); - virtual bool init(bool search_in_AI_path=false); - virtual void bind(); - virtual void unbind(); virtual void update(double dt); inline void setStrengthNorm( double s ) { strength_norm = s; }; inline void setDiameter( double d ) { diameter = d; }; diff --git a/src/AIModel/AIThermal.cxx b/src/AIModel/AIThermal.cxx index 4e8e63b2e..fcff08bea 100644 --- a/src/AIModel/AIThermal.cxx +++ b/src/AIModel/AIThermal.cxx @@ -61,7 +61,7 @@ void FGAIThermal::readFromScenario(SGPropertyNode* scFileNode) { setHeight(scFileNode->getDoubleValue("height-msl", 5000.0)); } -bool FGAIThermal::init(bool search_in_AI_path) { +bool FGAIThermal::init(ModelSearchOrder searchOrder) { factor = 8.0 * max_strength / (diameter * diameter * diameter); setAltitude( height ); _surface_wind_from_deg_node = @@ -73,7 +73,7 @@ bool FGAIThermal::init(bool search_in_AI_path) { _aloft_wind_speed_node = fgGetNode("/environment/config/aloft/entry[2]/wind-speed-kt", true); do_agl_calc = 1; - return FGAIBase::init(search_in_AI_path); + return FGAIBase::init(searchOrder); } void FGAIThermal::bind() { diff --git a/src/AIModel/AIThermal.hxx b/src/AIModel/AIThermal.hxx index 1f37acdf0..4b004dda1 100644 --- a/src/AIModel/AIThermal.hxx +++ b/src/AIModel/AIThermal.hxx @@ -38,7 +38,7 @@ public: void readFromScenario(SGPropertyNode* scFileNode); - virtual bool init(bool search_in_AI_path=false); + bool init(ModelSearchOrder searchOrder) override; virtual void bind(); virtual void update(double dt); diff --git a/src/AIModel/AIWingman.cxx b/src/AIModel/AIWingman.cxx index 916830f28..8cf9f18e5 100644 --- a/src/AIModel/AIWingman.cxx +++ b/src/AIModel/AIWingman.cxx @@ -158,8 +158,9 @@ void FGAIWingman::bind() { SGRawValueMethods(*this, &FGAIBallistic::getTgtZOffset, &FGAIBallistic::setTgtZOffset)); } -bool FGAIWingman::init(bool search_in_AI_path) { - if (!FGAIBallistic::init(search_in_AI_path)) +bool FGAIWingman::init(ModelSearchOrder searchOrder) +{ + if (!FGAIBallistic::init(searchOrder)) return false; reinit(); return true; diff --git a/src/AIModel/AIWingman.hxx b/src/AIModel/AIWingman.hxx index 0b02b7491..39fe5018c 100644 --- a/src/AIModel/AIWingman.hxx +++ b/src/AIModel/AIWingman.hxx @@ -35,7 +35,7 @@ public: virtual void readFromScenario(SGPropertyNode* scFileNode); - bool init(bool search_in_AI_path=false); + bool init(ModelSearchOrder searchOrder) override; virtual void bind(); virtual void reinit(); virtual void update (double dt);