From 2ea2f1b4f29afe7d74e0474ca02874387526e804 Mon Sep 17 00:00:00 2001 From: frohlich Date: Thu, 4 Jan 2007 12:47:12 +0000 Subject: [PATCH] Modified Files: Makefile.am commands.cxx commands.hxx Added Files: SGBinding.cxx SGBinding.hxx: Move FGBinding to SGBinding --- simgear/structure/Makefile.am | 4 +- simgear/structure/SGBinding.cxx | 86 ++++++++++++++++++++++ simgear/structure/SGBinding.hxx | 125 ++++++++++++++++++++++++++++++++ simgear/structure/commands.cxx | 19 +++++ simgear/structure/commands.hxx | 17 +++-- 5 files changed, 244 insertions(+), 7 deletions(-) create mode 100644 simgear/structure/SGBinding.cxx create mode 100644 simgear/structure/SGBinding.hxx diff --git a/simgear/structure/Makefile.am b/simgear/structure/Makefile.am index 6cbc483c..5468f2b7 100644 --- a/simgear/structure/Makefile.am +++ b/simgear/structure/Makefile.am @@ -9,6 +9,7 @@ include_HEADERS = \ event_mgr.hxx \ subsystem_mgr.hxx \ SGAtomic.hxx \ + SGBinding.hxx \ SGReferenced.hxx \ SGSharedPtr.hxx @@ -17,7 +18,8 @@ libsgstructure_a_SOURCES = \ exception.cxx \ event_mgr.cxx\ subsystem_mgr.cxx \ - SGAtomic.cxx + SGAtomic.cxx \ + SGBinding.cxx INCLUDES = -I$(top_srcdir) diff --git a/simgear/structure/SGBinding.cxx b/simgear/structure/SGBinding.cxx new file mode 100644 index 00000000..acd91814 --- /dev/null +++ b/simgear/structure/SGBinding.cxx @@ -0,0 +1,86 @@ +/** + * \file commands.hxx + * Interface definition for encapsulated commands. + * Started Spring 2001 by David Megginson, david@megginson.com + * This code is released into the Public Domain. + * + * $Id$ + */ + +#include +#include "SGBinding.hxx" + +SGBinding::SGBinding() + : _command(0), + _arg(new SGPropertyNode), + _setting(0) +{ +} + +SGBinding::SGBinding(const SGPropertyNode* node, SGPropertyNode* root) + : _command(0), + _arg(0), + _setting(0) +{ + read(node, root); +} + +SGBinding::~SGBinding() +{ + _arg->getParent()->removeChild(_arg->getName(), _arg->getIndex(), false); +} + +void +SGBinding::read(const SGPropertyNode* node, SGPropertyNode* root) +{ + const SGPropertyNode * conditionNode = node->getChild("condition"); + if (conditionNode != 0) + setCondition(sgReadCondition(root, conditionNode)); + + _command_name = node->getStringValue("command", ""); + if (_command_name.empty()) { + SG_LOG(SG_INPUT, SG_WARN, "No command supplied for binding."); + _command = 0; + return; + } + + _arg = const_cast(node); + _setting = 0; +} + +void +SGBinding::fire () const +{ + if (test()) { + if (_command == 0) + _command = SGCommandMgr::instance()->getCommand(_command_name); + if (_command == 0) { + SG_LOG(SG_INPUT, SG_WARN, "No command attached to binding"); + } else if (!(*_command)(_arg)) { + SG_LOG(SG_INPUT, SG_ALERT, "Failed to execute command " + << _command_name); + } + } +} + +void +SGBinding::fire (double offset, double max) const +{ + if (test()) { + _arg->setDoubleValue("offset", offset/max); + fire(); + } +} + +void +SGBinding::fire (double setting) const +{ + if (test()) { + // A value is automatically added to + // the args + if (_setting == 0) // save the setting node for efficiency + _setting = _arg->getChild("setting", 0, true); + _setting->setDoubleValue(setting); + fire(); + } +} diff --git a/simgear/structure/SGBinding.hxx b/simgear/structure/SGBinding.hxx new file mode 100644 index 00000000..b15f7061 --- /dev/null +++ b/simgear/structure/SGBinding.hxx @@ -0,0 +1,125 @@ +/** + * \file commands.hxx + * Interface definition for encapsulated commands. + * Started Spring 2001 by David Megginson, david@megginson.com + * This code is released into the Public Domain. + * + * $Id$ + */ + +#ifndef __SGBINDING_HXX +#define __SGBINDING_HXX + + +#include + +#include +#include +#include + +#include +#include + +#include "commands.hxx" + +/** + * An input binding of some sort. + * + *

This class represents a binding that can be assigned to a + * keyboard key, a joystick button or axis, or even a panel + * instrument.

+ */ +class SGBinding : public SGConditional +{ +public: + + /** + * Default constructor. + */ + SGBinding (); + + + /** + * Convenience constructor. + * + * @param node The binding will be built from this node. + */ + SGBinding (const SGPropertyNode * node, SGPropertyNode* root); + + + /** + * Destructor. + */ + virtual ~SGBinding (); + + + /** + * Get the command name. + * + * @return The string name of the command for this binding. + */ + const string &getCommandName () const { return _command_name; } + + + /** + * Get the command itself. + * + * @return The command associated with this binding, or 0 if none + * is present. + */ + SGCommandMgr::command_t getCommand () const { return _command; } + + + /** + * Get the argument that will be passed to the command. + * + * @return A property node that will be passed to the command as its + * argument, or 0 if none was supplied. + */ + const SGPropertyNode * getArg () { return _arg; } + + + /** + * Read a binding from a property node. + * + * @param node The property node containing the binding. + */ + void read (const SGPropertyNode * node, SGPropertyNode* root); + + + /** + * Fire a binding. + */ + void fire () const; + + + /** + * Fire a binding with a scaled movement (rather than absolute position). + */ + void fire (double offset, double max) const; + + + /** + * Fire a binding with a setting (i.e. joystick axis). + * + * A double 'setting' property will be added to the arguments. + * + * @param setting The input setting, usually between -1.0 and 1.0. + */ + void fire (double setting) const; + + +private: + // just to be safe. + SGBinding (const SGBinding &binding); + + std::string _command_name; + mutable SGCommandMgr::command_t _command; + mutable SGPropertyNode_ptr _arg; + mutable SGPropertyNode_ptr _setting; +}; + +typedef std::vector > SGBindingList; +typedef std::map SGBindingMap; + +#endif diff --git a/simgear/structure/commands.cxx b/simgear/structure/commands.cxx index 2e2c5921..49a9c63c 100644 --- a/simgear/structure/commands.cxx +++ b/simgear/structure/commands.cxx @@ -4,7 +4,10 @@ // // $Id$ +#include #include +#include +#include #include "commands.hxx" @@ -25,6 +28,22 @@ SGCommandMgr::~SGCommandMgr () // no-op } +SGCommandMgr* +SGCommandMgr::instance() +{ + static std::auto_ptr mgr; + if (mgr.get()) + return mgr.get(); + + static SGMutex lock; + SGGuard guard(lock); + if (mgr.get()) + return mgr.get(); + + mgr = std::auto_ptr(new SGCommandMgr); + return mgr.get(); +} + void SGCommandMgr::addCommand (const string &name, command_t command) { diff --git a/simgear/structure/commands.hxx b/simgear/structure/commands.hxx index 4ab28a09..fa27ac7e 100644 --- a/simgear/structure/commands.hxx +++ b/simgear/structure/commands.hxx @@ -44,17 +44,15 @@ public: typedef bool (*command_t) (const SGPropertyNode * arg); - /** - * Default constructor. - */ - SGCommandMgr (); - - /** * Destructor. */ virtual ~SGCommandMgr (); + /** + * Implement the classical singleton. + */ + static SGCommandMgr* instance(); /** * Register a new command with the manager. @@ -99,6 +97,13 @@ public: */ virtual bool execute (const string &name, const SGPropertyNode * arg) const; +protected: + /** + * Default constructor. + */ + SGCommandMgr (); + + private: typedef map command_map; -- 2.39.5