]> git.mxchange.org Git - simgear.git/blob - simgear/structure/commands.hxx
Reset: commands can be removed
[simgear.git] / simgear / structure / commands.hxx
1 /**
2  * \file commands.hxx
3  * Interface definition for encapsulated commands.
4  * Started Spring 2001 by David Megginson, david@megginson.com
5  * This code is released into the Public Domain.
6  *
7  * $Id$
8  */
9
10 #ifndef __COMMANDS_HXX
11 #define __COMMANDS_HXX
12
13
14 #include <simgear/compiler.h>
15
16 #include <string>
17 #include <map>
18
19 #include <simgear/threads/SGThread.hxx>
20 #include <simgear/math/sg_types.hxx>
21
22 // forward decls
23 class SGPropertyNode;
24      
25 /**
26  * Manage commands.
27  *
28  * <p>This class allows the application to register and unregister
29  * commands, and provides shortcuts for executing them.  Commands are
30  * simple functions that take a const pointer to an SGPropertyNode:
31  * the function may use the nodes children as parameters.</p>
32  *
33  * @author David Megginson, david@megginson.com
34  */
35 class SGCommandMgr
36 {
37 public:
38     /**
39      * Command functor object
40      */
41     class Command
42     {
43     public:
44         virtual ~Command() { }
45         virtual bool operator()(const SGPropertyNode * arg) = 0;
46     };
47
48     
49           typedef bool (*command_t) (const SGPropertyNode * arg);
50
51 private:
52     class FunctionCommand : public Command
53     {
54     public:
55         FunctionCommand( command_t fun )
56         : f_(fun) {}
57
58         virtual bool operator()(const SGPropertyNode * arg) { return (*f_)(arg); }
59     private:
60         command_t f_;
61     };
62
63     template< class ObjPtr, typename MemFn >
64     class MethodCommand : public Command
65     {
66     public:
67         MethodCommand( const ObjPtr& pObj, MemFn pMemFn ) :
68           pObj_(pObj), pMemFn_(pMemFn) {}
69
70         virtual bool operator()(const SGPropertyNode * arg)
71         {
72              return ((*pObj_).*pMemFn_)(arg);
73         }
74     private:
75         ObjPtr pObj_;
76         MemFn pMemFn_;
77     };
78     
79    /**
80     * Helper template functions.
81     */
82
83    template< class ObjPtr, typename MemFn >
84    Command* make_functor( const ObjPtr& pObj, MemFn pMemFn )
85    {
86        return new MethodCommand<ObjPtr,MemFn>(pObj, pMemFn );
87    }
88    
89 public:
90
91
92   /**
93    * Destructor.
94    */
95   virtual ~SGCommandMgr ();
96
97   /**
98    * Implement the classical singleton.
99    */
100   static SGCommandMgr* instance();
101
102   /**
103    * Register a new command with the manager.
104    *
105    * @param name The command name.  Any existing command with
106    * the same name will silently be overwritten.
107    * @param command A pointer to a one-arg function returning
108    * a bool result.  The argument is always a const pointer to
109    * an SGPropertyNode (which may contain multiple values).
110    */
111   void addCommand(const std::string& name, command_t f)
112   { addCommandObject(name, new FunctionCommand(f)); }
113        
114   void addCommandObject (const std::string &name, Command* command);
115
116   template<class OBJ, typename METHOD>
117   void addCommand(const std::string& name, const OBJ& o, METHOD m)
118   { 
119     addCommandObject(name, make_functor(o,m));
120   }
121   
122   /**
123    * Look up an existing command.
124    *
125    * @param name The command name.
126    * @return A pointer to the command, or 0 if there is no registered
127    * command with the name specified.
128    */
129   virtual Command* getCommand (const std::string &name) const;
130
131
132   /**
133    * Get a list of all existing command names.
134    *
135    * @return A (possibly empty) vector of the names of all registered
136    * commands.
137    */
138   virtual string_list getCommandNames () const;
139
140
141   /**
142    * Execute a command.
143    *
144    * @param name The name of the command.
145    * @param arg A const pointer to an SGPropertyNode.  The node
146    * may have a value and/or children, etc., so that it is possible
147    * to pass an arbitrarily complex data structure to a command.
148    * @return true if the command is present and executes successfully,
149    * false otherwise.
150    */
151   virtual bool execute (const std::string &name, const SGPropertyNode * arg) const;
152
153   /**
154    * Remove a command registration
155    */
156   bool removeCommand(const std::string& name);
157 protected:
158   /**
159    * Default constructor.
160    */
161   SGCommandMgr ();
162
163
164 private:
165
166   typedef std::map<std::string,Command*> command_map;
167   command_map _commands;
168
169   static SGMutex _instanceMutex;
170
171 };
172
173 #endif // __COMMANDS_HXX
174
175 // end of commands.hxx