Rapicorn - Experimental UI Toolkit - Source Code  13.07.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
commands.hh
Go to the documentation of this file.
00001  // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
00002 #include <ui/widget.hh> // unguarded, because item.hh includes commands.hh
00003 
00004 #ifndef __RAPICORN_COMMANDS_HH__
00005 #define __RAPICORN_COMMANDS_HH__
00006 
00007 namespace Rapicorn {
00008 
00009 struct Command : ReferenceCountable {
00010   const String ident;
00011   const String blurb;
00012   bool         needs_arg;
00013   Command (const char *cident, const char *cblurb, bool has_arg);
00014   virtual bool   exec (Deletable *obj, const StringSeq &args) = 0;
00015 protected:
00016   virtual ~Command();
00017 };
00018 
00019 struct CommandList {
00020   uint      n_commands;
00021   Command **commands;
00022   CommandList () : n_commands (0), commands (NULL) {}
00023   template<typename Array>
00024   CommandList (Array             &a,
00025                const CommandList &chain = CommandList()) :
00026     n_commands (0),
00027     commands (NULL)
00028   {
00029     uint array_length = sizeof (a) / sizeof (a[0]);
00030     n_commands = array_length + chain.n_commands;
00031     commands = new Command*[n_commands];
00032     uint i;
00033     for (i = 0; i < array_length; i++)
00034       commands[i] = ref_sink (a[i]);
00035     for (; i < n_commands; i++)
00036       commands[i] = ref (chain.commands[i - array_length]);
00037   }
00038   ~CommandList()
00039   {
00040     for (uint i = 0; i < n_commands; i++)
00041       unref (commands[i]);
00042     delete[] commands;
00043   }
00044 };
00045 
00046 #define RAPICORN_MakeNamedCommand(Type, cident, blurb, method, data)   \
00047   create_command (&Type::method, cident, blurb, data)
00048 #define RAPICORN_MakeSimpleCommand(Type, method, blurb)                 \
00049   create_command (&Type::method, #method, blurb)
00050 
00051 /* --- command implementations --- */
00052 /* command with data and arg string */
00053 template<class Class, class Data>
00054 struct CommandDataArg : Command {
00055   typedef bool (Class::*CommandMethod) (Data data, const StringSeq &args);
00056   bool (Class::*command_method) (Data data, const StringSeq &args);
00057   Data data;
00058   CommandDataArg (bool (Class::*method) (Data, const String&),
00059                   const char *cident, const char *cblurb, const Data &method_data);
00060   virtual bool exec (Deletable *obj, const StringSeq &args);
00061 };
00062 template<class Class, class Data> inline Command*
00063 create_command (bool (Class::*method) (Data, const String&),
00064                 const char *ident, const char *blurb, const Data &method_data)
00065 { return new CommandDataArg<Class,Data> (method, ident, blurb, method_data); }
00066 
00067 /* command with data */
00068 template<class Class, class Data>
00069 struct CommandData : Command {
00070   typedef bool (Class::*CommandMethod) (Data data);
00071   bool (Class::*command_method) (Data data);
00072   Data data;
00073   CommandData (bool (Class::*method) (Data),
00074                const char *cident, const char *cblurb, const Data &method_data);
00075   virtual bool exec (Deletable *obj, const StringSeq&);
00076 };
00077 template<class Class, class Data> inline Command*
00078 create_command (bool (Class::*method) (Data),
00079                 const char *ident, const char *blurb, const Data &method_data)
00080 { return new CommandData<Class,Data> (method, ident, blurb, method_data); }
00081 
00082 /* command with arg string */
00083 template<class Class>
00084 struct CommandArg: Command {
00085   typedef bool (Class::*CommandMethod) (const StringSeq &args);
00086   bool (Class::*command_method) (const StringSeq &args);
00087   CommandArg (bool (Class::*method) (const String&),
00088               const char *cident, const char *cblurb);
00089   virtual bool exec (Deletable *obj, const StringSeq &args);
00090 };
00091 template<class Class> inline Command*
00092 create_command (bool (Class::*method) (const String&),
00093                 const char *ident, const char *blurb)
00094 { return new CommandArg<Class> (method, ident, blurb); }
00095 
00096 /* simple command */
00097 template<class Class>
00098 struct CommandSimple : Command {
00099   typedef bool (Class::*CommandMethod) ();
00100   bool (Class::*command_method) ();
00101   CommandSimple (bool (Class::*method) (),
00102                  const char *cident, const char *cblurb);
00103   virtual bool exec (Deletable *obj, const StringSeq&);
00104 };
00105 template<class Class> inline Command*
00106 create_command (bool (Class::*method) (),
00107                 const char *ident, const char *blurb)
00108 { return new CommandSimple<Class> (method, ident, blurb); }
00109 
00110 /* --- implementations --- */
00111 /* command with data and arg string */
00112 template<class Class, typename Data>
00113 CommandDataArg<Class,Data>::CommandDataArg (bool (Class::*method) (Data, const String&),
00114                                             const char *cident, const char *cblurb, const Data &method_data) :
00115   Command (cident, cblurb, true),
00116   command_method (method),
00117   data (method_data)
00118 {}
00119 template<class Class, typename Data> bool
00120 CommandDataArg<Class,Data>::exec (Deletable *obj, const StringSeq &args)
00121 {
00122   Class *instance = dynamic_cast<Class*> (obj);
00123   if (!instance)
00124     fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_name().c_str());
00125   return (instance->*command_method) (data, args);
00126 }
00127 
00128 /* command arg string */
00129 template<class Class>
00130 CommandArg<Class>::CommandArg (bool (Class::*method) (const String&),
00131                                const char *cident, const char *cblurb) :
00132   Command (cident, cblurb, true),
00133   command_method (method)
00134 {}
00135 template<class Class> bool
00136 CommandArg<Class>::exec (Deletable *obj, const StringSeq &args)
00137 {
00138   Class *instance = dynamic_cast<Class*> (obj);
00139   if (!instance)
00140     fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_name().c_str());
00141   return (instance->*command_method) (args);
00142 }
00143 
00144 /* command with data */
00145 template<class Class, typename Data>
00146 CommandData<Class,Data>::CommandData (bool (Class::*method) (Data),
00147                                       const char *cident, const char *cblurb, const Data &method_data) :
00148   Command (cident, cblurb, false),
00149   command_method (method),
00150   data (method_data)
00151 {}
00152 template<class Class, typename Data> bool
00153 CommandData<Class,Data>::exec (Deletable *obj, const StringSeq&)
00154 {
00155   Class *instance = dynamic_cast<Class*> (obj);
00156   if (!instance)
00157     fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_name().c_str());
00158   return (instance->*command_method) (data);
00159 }
00160 
00161 /* simple command */
00162 template<class Class>
00163 CommandSimple<Class>::CommandSimple (bool (Class::*method) (),
00164                                      const char *cident, const char *cblurb) :
00165   Command (cident, cblurb, false),
00166   command_method (method)
00167 {}
00168 template<class Class> bool
00169 CommandSimple<Class>::exec (Deletable *obj, const StringSeq&)
00170 {
00171   Class *instance = dynamic_cast<Class*> (obj);
00172   if (!instance)
00173     fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_name().c_str());
00174   return (instance->*command_method) ();
00175 }
00176 
00177 } // Rapicorn
00178 
00179 #endif  /* __RAPICORN_COMMANDS_HH__ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines