1
0
Fork 0

Allow scenarios to have load/unload scripts.

This makes it possible for the balloons scenario (for example) to
work correctly with dynamic loading and unloading.
This commit is contained in:
James Turner 2013-03-28 16:50:55 +00:00
parent a7e4f2a971
commit 4d144dfbf2
2 changed files with 64 additions and 12 deletions

View file

@ -26,12 +26,14 @@
#include <simgear/props/props_io.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/structure/commands.hxx>
#include <simgear/structure/SGBinding.hxx>
#include <boost/mem_fn.hpp>
#include <boost/foreach.hpp>
#include <Main/globals.hxx>
#include <Airports/airport.hxx>
#include <Scripting/NasalSys.hxx>
#include "AIManager.hxx"
#include "AIAircraft.hxx"
@ -50,8 +52,8 @@
class FGAIManager::Scenario
{
public:
Scenario(FGAIManager* man, SGPropertyNode* scenarios) :
_manager(man)
Scenario(FGAIManager* man, const std::string& nm, SGPropertyNode* scenarios) :
_internalName(nm)
{
BOOST_FOREACH(SGPropertyNode* scEntry, scenarios->getChildren("entry")) {
FGAIBasePtr ai = man->addObject(scEntry);
@ -59,6 +61,21 @@ public:
_objects.push_back(ai);
}
} // of scenario entry iteration
SGPropertyNode* nasalScripts = scenarios->getChild("nasal");
if (!nasalScripts) {
return;
}
_unloadScript = nasalScripts->getStringValue("unload");
std::string loadScript = nasalScripts->getStringValue("load");
if (!loadScript.empty()) {
FGNasalSys* nasalSys = (FGNasalSys*) globals->get_subsystem("nasal");
std::string moduleName = "scenario_" + _internalName;
nasalSys->createModule(moduleName.c_str(), moduleName.c_str(),
loadScript.c_str(), loadScript.size(),
0);
}
}
~Scenario()
@ -66,10 +83,21 @@ public:
BOOST_FOREACH(FGAIBasePtr ai, _objects) {
ai->setDie(true);
}
FGNasalSys* nasalSys = (FGNasalSys*) globals->get_subsystem("nasal");
std::string moduleName = "scenario_" + _internalName;
if (!_unloadScript.empty()) {
nasalSys->createModule(moduleName.c_str(), moduleName.c_str(),
_unloadScript.c_str(), _unloadScript.size(),
0);
}
nasalSys->deleteModule(moduleName.c_str());
}
private:
FGAIManager* _manager;
std::vector<FGAIBasePtr> _objects;
std::string _internalName;
std::string _unloadScript;
};
///////////////////////////////////////////////////////////////////////////////
@ -275,14 +303,28 @@ FGAIManager::processThermal( double dt, FGAIThermal* thermal ) {
bool FGAIManager::loadScenarioCommand(const SGPropertyNode* args)
{
std::string name = args->getStringValue("name");
return loadScenario(name);
if (_scenarios.find(name) != _scenarios.end()) {
SG_LOG(SG_AI, SG_WARN, "scenario '" << name << "' already loaded");
return false;
}
bool ok = loadScenario(name);
if (ok) {
// create /sim/ai node for consistency
int index = 0;
for (; root->hasChild("scenario", index); ++index) {}
SGPropertyNode* scenarioNode = root->getChild("scenario", index, true);
scenarioNode->setStringValue(name);
}
return ok;
}
bool FGAIManager::unloadScenarioCommand(const SGPropertyNode* args)
{
std::string name = args->getStringValue("name");
unloadScenario(name);
return true;
return unloadScenario(name);
}
bool FGAIManager::addObjectCommand(const SGPropertyNode* definition)
@ -351,22 +393,32 @@ FGAIManager::loadScenario( const string &filename )
return false;
}
_scenarios[filename] = new Scenario(this, scNode);
_scenarios[filename] = new Scenario(this, filename, scNode);
return true;
}
void
bool
FGAIManager::unloadScenario( const string &filename)
{
ScenarioDict::iterator it = _scenarios.find(filename);
if (it == _scenarios.end()) {
SG_LOG(SG_AI, SG_WARN, "unload scenario: not found:" << filename);
return;
return false;
}
// remove /sim/ai node
unsigned int index = 0;
for (SGPropertyNode* n = NULL; (n = root->getChild("scenario", index)) != NULL; ++index) {
if (n->getStringValue() == filename) {
root->removeChild("scenario", index);
break;
}
}
delete it->second;
_scenarios.erase(it);
return true;
}
SGPropertyNode_ptr

View file

@ -81,11 +81,11 @@ public:
int getNumAiObjects(void) const;
bool loadScenario( const string &filename );
bool loadScenario( const std::string &filename );
static SGPropertyNode_ptr loadScenarioFile(const std::string& filename);
static bool getStartPosition(const string& id, const string& pid,
static bool getStartPosition(const std::string& id, const std::string& pid,
SGGeod& geodPos, double& hdng, SGVec3d& uvw);
FGAIBasePtr addObject(const SGPropertyNode* definition);
@ -100,7 +100,7 @@ private:
bool addObjectCommand(const SGPropertyNode* definition);
bool removeObject(const SGPropertyNode* args);
void unloadScenario( const string &filename );
bool unloadScenario( const std::string &filename );
SGPropertyNode_ptr root;
SGPropertyNode_ptr enabled;