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