This fixes the animation bindings to use the defined property tree root - to support multiplayer (or other) model that can bind to the correct part of the property tree. Requires a corresponding fix in fg to allow the command methods to take an optional root parameter. What this means is that when inside someone else's multiplayer model (e.g. backseat, or co-pilot), the multipalyer (AI) model will correctly modify properties inside the correct part of the property tree inside (/ai), rather than modifying the properties inside the same part of the tree as the non-ai model. This means that a properly setup model will operate within it's own space in the property tree; and permit more generic multiplayer code to be written. This is probably responsible for some of the pollution of the /sim property tree with MP aircraft properties.
135 lines
2.8 KiB
C++
135 lines
2.8 KiB
C++
// commands.cxx - encapsulated commands.
|
|
// Started Spring 2001 by David Megginson, david@megginson.com
|
|
// This code is released into the Public Domain.
|
|
//
|
|
// $Id$
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <simgear_config.h>
|
|
#endif
|
|
|
|
#include <memory>
|
|
#include <cassert>
|
|
|
|
#include <simgear/props/props_io.hxx>
|
|
|
|
#include "commands.hxx"
|
|
|
|
#include <simgear/structure/exception.hxx>
|
|
#include <simgear/threads/SGThread.hxx>
|
|
#include <simgear/threads/SGGuard.hxx>
|
|
#include <simgear/debug/logstream.hxx>
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Implementation of SGCommandMgr class.
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
static SGCommandMgr* static_instance = NULL;
|
|
|
|
SGCommandMgr::SGCommandMgr ()
|
|
{
|
|
assert(static_instance == NULL);
|
|
static_instance = this;
|
|
}
|
|
|
|
SGCommandMgr::~SGCommandMgr ()
|
|
{
|
|
assert(static_instance == this);
|
|
static_instance = NULL;
|
|
}
|
|
|
|
SGCommandMgr*
|
|
SGCommandMgr::instance()
|
|
{
|
|
return static_instance ? static_instance : new SGCommandMgr;
|
|
}
|
|
|
|
void
|
|
SGCommandMgr::addCommandObject (const std::string &name, Command* command)
|
|
{
|
|
if (_commands.find(name) != _commands.end())
|
|
throw sg_exception("duplicate command name:" + name);
|
|
|
|
_commands[name] = command;
|
|
}
|
|
|
|
SGCommandMgr::Command*
|
|
SGCommandMgr::getCommand (const std::string &name) const
|
|
{
|
|
const command_map::const_iterator it = _commands.find(name);
|
|
return (it != _commands.end() ? it->second : 0);
|
|
}
|
|
|
|
string_list
|
|
SGCommandMgr::getCommandNames () const
|
|
{
|
|
string_list names;
|
|
command_map::const_iterator it = _commands.begin();
|
|
command_map::const_iterator last = _commands.end();
|
|
while (it != last) {
|
|
names.push_back(it->first);
|
|
++it;
|
|
}
|
|
return names;
|
|
}
|
|
|
|
bool
|
|
SGCommandMgr::execute (const std::string &name, const SGPropertyNode * arg, SGPropertyNode *root) const
|
|
{
|
|
Command* command = getCommand(name);
|
|
if (command == 0)
|
|
{
|
|
SG_LOG(SG_GENERAL, SG_WARN, "command not found: '" << name << "'");
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
return (*command)(arg, root);
|
|
}
|
|
catch(sg_exception& e)
|
|
{
|
|
SG_LOG
|
|
(
|
|
SG_GENERAL,
|
|
SG_ALERT,
|
|
"command '" << name << "' failed with exception\n"
|
|
"\tmessage:" << e.getMessage() << " (from " << e.getOrigin() << ")"
|
|
);
|
|
}
|
|
catch(std::exception& ex)
|
|
{
|
|
SG_LOG
|
|
(
|
|
SG_GENERAL,
|
|
SG_ALERT,
|
|
"command '" << name << "' failed with exception: " << ex.what()
|
|
);
|
|
}
|
|
catch(...)
|
|
{
|
|
SG_LOG
|
|
(
|
|
SG_GENERAL,
|
|
SG_ALERT,
|
|
"command '" << name << "' failed with unknown exception."
|
|
);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool SGCommandMgr::removeCommand(const std::string& name)
|
|
{
|
|
command_map::iterator it = _commands.find(name);
|
|
if (it == _commands.end())
|
|
return false;
|
|
|
|
delete it->second;
|
|
_commands.erase(it);
|
|
return true;
|
|
}
|
|
|
|
// end of commands.cxx
|