Rapicorn - Experimental UI Toolkit - Source Code 10.08.1
commands.hh
Go to the documentation of this file.
00001 /* Rapicorn
00002  * Copyright (C) 2005 Tim Janik
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * A copy of the GNU Lesser General Public License should ship along
00015  * with this library; if not, see http://www.gnu.org/copyleft/.
00016  */
00017 #include <ui/item.hh> // unguarded, because item.hh includes commands.hh
00018 
00019 #ifndef __RAPICORN_COMMANDS_HH__
00020 #define __RAPICORN_COMMANDS_HH__
00021 
00022 namespace Rapicorn {
00023 
00024 struct Command : ReferenceCountable {
00025   const String ident;
00026   const String blurb;
00027   bool         needs_arg;
00028   Command (const char *cident, const char *cblurb, bool has_arg);
00029   virtual bool   exec (Deletable *obj, const StringList &args) = 0;
00030 protected:
00031   virtual ~Command();
00032 };
00033 
00034 struct CommandList {
00035   uint      n_commands;
00036   Command **commands;
00037   CommandList () : n_commands (0), commands (NULL) {}
00038   template<typename Array>
00039   CommandList (Array             &a,
00040                const CommandList &chain = CommandList()) :
00041     n_commands (0),
00042     commands (NULL)
00043   {
00044     uint array_length = sizeof (a) / sizeof (a[0]);
00045     n_commands = array_length + chain.n_commands;
00046     commands = new Command*[n_commands];
00047     uint i;
00048     for (i = 0; i < array_length; i++)
00049       commands[i] = ref_sink (a[i]);
00050     for (; i < n_commands; i++)
00051       commands[i] = ref (chain.commands[i - array_length]);
00052   }
00053   ~CommandList()
00054   {
00055     for (uint i = 0; i < n_commands; i++)
00056       unref (commands[i]);
00057     delete[] commands;
00058   }
00059 };
00060 
00061 #define RAPICORN_MakeNamedCommand(Type, cident, blurb, method, data)   \
00062   create_command (&Type::method, cident, blurb, data)
00063 #define RAPICORN_MakeSimpleCommand(Type, method, blurb)                 \
00064   create_command (&Type::method, #method, blurb)
00065 
00066 /* --- command implementations --- */
00067 /* command with data and arg string */
00068 template<class Class, class Data>
00069 struct CommandDataArg : Command {
00070   typedef bool (Class::*CommandMethod) (Data data, const StringList &args);
00071   bool (Class::*command_method) (Data data, const StringList &args);
00072   Data data;
00073   CommandDataArg (bool (Class::*method) (Data, const String&),
00074                   const char *cident, const char *cblurb, const Data &method_data);
00075   virtual bool exec (Deletable *obj, const StringList &args);
00076 };
00077 template<class Class, class Data> inline Command*
00078 create_command (bool (Class::*method) (Data, const String&),
00079                 const char *ident, const char *blurb, const Data &method_data)
00080 { return new CommandDataArg<Class,Data> (method, ident, blurb, method_data); }
00081 
00082 /* command with data */
00083 template<class Class, class Data>
00084 struct CommandData : Command {
00085   typedef bool (Class::*CommandMethod) (Data data);
00086   bool (Class::*command_method) (Data data);
00087   Data data;
00088   CommandData (bool (Class::*method) (Data),
00089                const char *cident, const char *cblurb, const Data &method_data);
00090   virtual bool exec (Deletable *obj, const StringList&);
00091 };
00092 template<class Class, class Data> inline Command*
00093 create_command (bool (Class::*method) (Data),
00094                 const char *ident, const char *blurb, const Data &method_data)
00095 { return new CommandData<Class,Data> (method, ident, blurb, method_data); }
00096 
00097 /* command with arg string */
00098 template<class Class>
00099 struct CommandArg: Command {
00100   typedef bool (Class::*CommandMethod) (const StringList &args);
00101   bool (Class::*command_method) (const StringList &args);
00102   CommandArg (bool (Class::*method) (const String&),
00103               const char *cident, const char *cblurb);
00104   virtual bool exec (Deletable *obj, const StringList &args);
00105 };
00106 template<class Class> inline Command*
00107 create_command (bool (Class::*method) (const String&),
00108                 const char *ident, const char *blurb)
00109 { return new CommandArg<Class> (method, ident, blurb); }
00110 
00111 /* simple command */
00112 template<class Class>
00113 struct CommandSimple : Command {
00114   typedef bool (Class::*CommandMethod) ();
00115   bool (Class::*command_method) ();
00116   CommandSimple (bool (Class::*method) (),
00117                  const char *cident, const char *cblurb);
00118   virtual bool exec (Deletable *obj, const StringList&);
00119 };
00120 template<class Class> inline Command*
00121 create_command (bool (Class::*method) (),
00122                 const char *ident, const char *blurb)
00123 { return new CommandSimple<Class> (method, ident, blurb); }
00124 
00125 /* --- implementations --- */
00126 /* command with data and arg string */
00127 template<class Class, typename Data>
00128 CommandDataArg<Class,Data>::CommandDataArg (bool (Class::*method) (Data, const String&),
00129                                             const char *cident, const char *cblurb, const Data &method_data) :
00130   Command (cident, cblurb, true),
00131   command_method (method),
00132   data (method_data)
00133 {}
00134 template<class Class, typename Data> bool
00135 CommandDataArg<Class,Data>::exec (Deletable *obj, const StringList &args)
00136 {
00137   Class *instance = dynamic_cast<Class*> (obj);
00138   if (!instance)
00139     fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_pretty_name().c_str());
00140   return (instance->*command_method) (data, args);
00141 }
00142 
00143 /* command arg string */
00144 template<class Class>
00145 CommandArg<Class>::CommandArg (bool (Class::*method) (const String&),
00146                                const char *cident, const char *cblurb) :
00147   Command (cident, cblurb, true),
00148   command_method (method)
00149 {}
00150 template<class Class> bool
00151 CommandArg<Class>::exec (Deletable *obj, const StringList &args)
00152 {
00153   Class *instance = dynamic_cast<Class*> (obj);
00154   if (!instance)
00155     fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_pretty_name().c_str());
00156   return (instance->*command_method) (args);
00157 }
00158 
00159 /* command with data */
00160 template<class Class, typename Data>
00161 CommandData<Class,Data>::CommandData (bool (Class::*method) (Data),
00162                                       const char *cident, const char *cblurb, const Data &method_data) :
00163   Command (cident, cblurb, false),
00164   command_method (method),
00165   data (method_data)
00166 {}
00167 template<class Class, typename Data> bool
00168 CommandData<Class,Data>::exec (Deletable *obj, const StringList&)
00169 {
00170   Class *instance = dynamic_cast<Class*> (obj);
00171   if (!instance)
00172     fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_pretty_name().c_str());
00173   return (instance->*command_method) (data);
00174 }
00175 
00176 /* simple command */
00177 template<class Class>
00178 CommandSimple<Class>::CommandSimple (bool (Class::*method) (),
00179                                      const char *cident, const char *cblurb) :
00180   Command (cident, cblurb, false),
00181   command_method (method)
00182 {}
00183 template<class Class> bool
00184 CommandSimple<Class>::exec (Deletable *obj, const StringList&)
00185 {
00186   Class *instance = dynamic_cast<Class*> (obj);
00187   if (!instance)
00188     fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_pretty_name().c_str());
00189   return (instance->*command_method) ();
00190 }
00191 
00192 } // Rapicorn
00193 
00194 #endif  /* __RAPICORN_COMMANDS_HH__ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines