]> git.mxchange.org Git - simgear.git/blob - simgear/structure/commands.hxx
Command-manager supports functors.
[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 private:
49     template< typename Fun >
50     class FunctionCommand : public Command
51     {
52     public:
53         FunctionCommand( const Fun* fun )
54         : f_(fun) {}
55
56         virtual bool operator()(const SGPropertyNode * arg) { return (*f_)(arg); }
57     private:
58         Fun* f_;
59     };
60
61     template< class ObjPtr, typename MemFn >
62     class MethodCommand : public Command
63     {
64     public:
65         MethodCommand( const ObjPtr& pObj, MemFn pMemFn ) :
66           pObj_(pObj), pMemFn_(pMemFn) {}
67
68         virtual bool operator()(const SGPropertyNode * arg)
69         {
70              return ((*pObj_).*pMemFn_)(arg);
71         }
72     private:
73         ObjPtr pObj_;
74         MemFn pMemFn_;
75     };
76     
77    /**
78     * Helper template functions.
79     */
80
81    template< typename Fun >
82    Command* make_functor( const Fun* fun )
83    {
84        return new FunctionCommand<Fun>(fun);
85    }
86
87    template< class ObjPtr, typename MemFn >
88    Command* make_functor( const ObjPtr& pObj, MemFn pMemFn )
89    {
90        return new MethodCommand<ObjPtr,MemFn>(pObj, pMemFn );
91    }
92    
93 public:
94     
95   typedef bool (*command_t) (const SGPropertyNode * arg);
96
97   /**
98    * Destructor.
99    */
100   virtual ~SGCommandMgr ();
101
102   /**
103    * Implement the classical singleton.
104    */
105   static SGCommandMgr* instance();
106
107   /**
108    * Register a new command with the manager.
109    *
110    * @param name The command name.  Any existing command with
111    * the same name will silently be overwritten.
112    * @param command A pointer to a one-arg function returning
113    * a bool result.  The argument is always a const pointer to
114    * an SGPropertyNode (which may contain multiple values).
115    */
116   template<typename FUNC>
117   void addCommand(const std::string& name, const FUNC* f)
118   { addCommand(name, make_functor(f)); }
119        
120   void addCommand (const std::string &name, Command* command);
121
122   template<class OBJ, typename METHOD>
123   void addCommand(const std::string& name, const OBJ& o, METHOD m)
124   { 
125     addCommand(name, make_functor(o,m));
126   }
127   
128   /**
129    * Look up an existing command.
130    *
131    * @param name The command name.
132    * @return A pointer to the command, or 0 if there is no registered
133    * command with the name specified.
134    */
135   virtual Command* getCommand (const std::string &name) const;
136
137
138   /**
139    * Get a list of all existing command names.
140    *
141    * @return A (possibly empty) vector of the names of all registered
142    * commands.
143    */
144   virtual string_list getCommandNames () const;
145
146
147   /**
148    * Execute a command.
149    *
150    * @param name The name of the command.
151    * @param arg A const pointer to an SGPropertyNode.  The node
152    * may have a value and/or children, etc., so that it is possible
153    * to pass an arbitrarily complex data structure to a command.
154    * @return true if the command is present and executes successfully,
155    * false otherwise.
156    */
157   virtual bool execute (const std::string &name, const SGPropertyNode * arg) const;
158
159 protected:
160   /**
161    * Default constructor.
162    */
163   SGCommandMgr ();
164
165
166 private:
167
168   typedef std::map<std::string,Command*> command_map;
169   command_map _commands;
170
171   static SGMutex _instanceMutex;
172
173 };
174
175 #endif // __COMMANDS_HXX
176
177 // end of commands.hxx