core/vgui/vgui_command.h
Go to the documentation of this file.
00001 // This is core/vgui/vgui_command.h
00002 #ifndef vgui_command_h_
00003 #define vgui_command_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \author fsm and pcp@robots.ox.ac.uk
00010 // \brief  Defines the abstract interface to commands.
00011 //
00012 // \verbatim
00013 //  Modifications
00014 //   awf - Renamed derived classes to be consistent with header-file naming convention.
00015 //   fsm - Fixed everything afterwards....
00016 //   2004/09/10 Peter Vanroose - Added explicit copy constructor (ref_count !)
00017 // \endverbatim
00018 
00019 #include <vbl/vbl_ref_count.h>
00020 
00021 #include "vgui_command_sptr.h"
00022 
00023 //: Defines the abstract interface to commands
00024 struct vgui_command : public vbl_ref_count
00025 {
00026   vgui_command();
00027   vgui_command(vgui_command const&) : vbl_ref_count() {}
00028   virtual ~vgui_command();
00029   virtual void execute() =0;
00030 };
00031 
00032 //: An implementation using a C callback function
00033 struct vgui_command_cfunc : public vgui_command
00034 {
00035   typedef void (*function_pv)(void const*);
00036   typedef void (*function)();
00037   function_pv fn_pv;
00038   function fn;
00039   void const *data;
00040 
00041   vgui_command_cfunc(function_pv, void const *);
00042   vgui_command_cfunc(function);
00043  ~vgui_command_cfunc();
00044   void execute();
00045 };
00046 
00047 //: Command for toggle buttons
00048 struct vgui_command_toggle : public vgui_command
00049 {
00050   bool state;
00051   vgui_command_toggle(bool v) : state(v) { }
00052   ~vgui_command_toggle();
00053   void execute();
00054 };
00055 
00056 template <class receiver>
00057 //: pcp's templated bound member functions.
00058 // All methods are inline, so we don't need a separate .cxx file.
00059 //
00060 // vgui_command_simple is a convenient way to build vgui_commands from
00061 // object/method pairs where the method is of the form
00062 // void receiver::method();
00063 // So, if you have
00064 // \code
00065 //    class myclass {
00066 //      void do_thing();
00067 //    };
00068 //    myclass* my_app;
00069 // \endcode
00070 // You can make a command such as
00071 //    vgui_command_simple<myclass>(my_app, myclass::do_thing);
00072 //  and pass it to a menu.
00073 struct vgui_command_simple : public vgui_command
00074 {
00075   typedef void (receiver::* action)();
00076 
00077   vgui_command_simple(receiver* o, action m) : obj(o), mem(m) { }
00078   void execute() { (obj->*mem)(); }
00079 
00080   receiver* obj;
00081   action mem;
00082 };
00083 
00084 #define VGUI_COMMAND_SIMPLE_INSTANTIATE(receiver) \
00085 template struct vgui_command_simple<receiver >
00086 
00087 template <class object_t, class data_t>
00088 
00089 //: For methods that take a single argument (fsm).
00090 struct vgui_command_bound_method : public vgui_command
00091 {
00092   typedef void (object_t::*action_t)(data_t);
00093 
00094   vgui_command_bound_method(object_t *o, action_t m, data_t d) : obj(o), mem(m), dat(d) { }
00095   void execute() { (obj->*mem)(dat); }
00096 
00097   object_t *obj;
00098   action_t mem;
00099   data_t dat;
00100 };
00101 
00102 #define VGUI_COMMAND_BOUND_METHOD_INSTANTIATE(O, D) \
00103 template struct vgui_command_bound_method<O, D >
00104 
00105 //----------------------------------------------------------------------
00106 
00107 #define INSTANTIATE_VGUI_simple_command(receiver) \
00108 VGUI_COMMAND_SIMPLE_INSTANTIATE(receiver) /* backwards compat */
00109 
00110 #endif // vgui_command_h_