00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00052 #ifndef CONTROL_COMMAND_H
00053 #define CONTROL_COMMAND_H
00054
00055 #include "pre.hpp"
00056 #include "lib/error.hpp"
00057 #include "lib/symbol.hpp"
00058 #include "proc/control/argument-erasure.hpp"
00059 #include "proc/control/argument-tuple-accept.hpp"
00060 #include "proc/control/handling-pattern.hpp"
00061 #include "lib/bool-checkable.hpp"
00062 #include "lib/meta/tuple.hpp"
00063 #include "lib/handle.hpp"
00064
00065 #include <string>
00066
00068
00069
00070
00071 namespace control {
00072
00073 using std::string;
00074 using lib::Symbol;
00075 using std::tr1::shared_ptr;
00076 using lumiera::typelist::Tuple;
00077
00078
00079 LUMIERA_ERROR_DECLARE (UNBOUND_ARGUMENTS);
00080 LUMIERA_ERROR_DECLARE (INVALID_COMMAND);
00081 LUMIERA_ERROR_DECLARE (DUPLICATE_COMMAND);
00082 LUMIERA_ERROR_DECLARE (INVALID_ARGUMENTS);
00083
00084
00085
00086 typedef void* FuncPtr;
00087
00088 class CommandDef;
00089 class CommandImpl;
00090
00091
00106 class Command
00107 : public AcceptAnyBinding<Command
00108 , Command&
00109 , lib::Handle<CommandImpl>
00110 >
00111 {
00112 typedef lib::Handle<CommandImpl> _Handle;
00113
00114 public:
00115
00116 static Command get (Symbol cmdID);
00117 static Command get (FuncPtr func);
00118 static bool remove (Symbol cmdID);
00119
00121 Command storeDef (Symbol newCmdID) const;
00122 Command newInstance () const;
00123
00124 Command (Symbol cmdID) { *this = get (cmdID); }
00125 Command() { }
00126 ~Command();
00127
00128
00129
00130
00131
00132 template<typename TYPES>
00133 Command& bindArg (Tuple<TYPES> const&);
00134
00135
00136 ExecResult operator() () ;
00137 ExecResult undo () ;
00138
00139
00144 ExecResult exec (HandlingPattern const& execPattern);
00145 ExecResult exec (HandlingPattern::ID);
00146
00148 ExecResult execSync ();
00149
00151 HandlingPattern::ID getDefaultHandlingPattern() const;
00152
00155 HandlingPattern::ID setHandlingPattern (HandlingPattern::ID);
00156
00157
00158
00159
00160
00161 static size_t definition_count();
00162 static size_t instance_count();
00163
00164 bool canExec() const;
00165 bool canUndo() const;
00166
00167 static bool defined (Symbol cmdID);
00168 static bool canExec (Symbol cmdID);
00169 static bool canUndo (Symbol cmdID);
00170
00171 void duplicate_detected (Symbol) const;
00172
00173 operator string() const;
00174 friend bool operator== (Command const&, Command const&);
00175 friend bool operator< (Command const&, Command const&);
00176
00177
00178 protected:
00179 static Command fetchDef (Symbol cmdID);
00180 void activate (shared_ptr<CommandImpl> const&, Symbol cmdID =0);
00181
00182 friend class CommandDef;
00183
00184
00185 private:
00186 void setArguments (Arguments&);
00187 static bool equivalentImpl (Command const&, Command const&);
00188 };
00189
00190
00191
00192
00193
00194 inline ExecResult
00195 Command::operator() ()
00196 {
00197 return exec (getDefaultHandlingPattern());
00198 }
00199
00200
00201 template<typename TYPES>
00202 inline Command&
00203 Command::bindArg (Tuple<TYPES> const& tuple)
00204 {
00205 TypedArguments<Tuple<TYPES> > args(tuple);
00206 this->setArguments (args);
00207 return *this;
00208 }
00209
00210
00211
00212
00213
00214 inline bool
00215 Command::defined (Symbol cmdID)
00216 {
00217 return fetchDef(cmdID).isValid();
00218 }
00219
00220
00221 #define _FAILSAFE_COMMAND_QUERY(_ID_, _QUERY_) \
00222 try \
00223 { \
00224 return Command::get(_ID_)._QUERY_; \
00225 } \
00226 catch(lumiera::error::Invalid&) \
00227 { \
00228 lumiera_error(); \
00229 return false; \
00230 }
00231
00232
00233 inline bool
00234 Command::canExec (Symbol cmdID)
00235 {
00236 _FAILSAFE_COMMAND_QUERY (cmdID, canExec() );
00237 }
00238
00239
00240 inline bool
00241 Command::canUndo (Symbol cmdID)
00242 {
00243 _FAILSAFE_COMMAND_QUERY (cmdID, canUndo() );
00244 }
00245
00246 #undef _FAILSAFE_COMMAND_QUERY
00247
00248
00249
00250
00251 inline bool
00252 operator== (Command const& c1, Command const& c2)
00253 {
00254 return (!c1 && !c2)
00255 || ( c1 && c2 && ( &c1.impl() == &c2.impl()
00256 || Command::equivalentImpl (c1,c2)
00257 ));
00258 }
00259
00260 inline bool
00261 operator!= (Command const& c1, Command const& c2)
00262 {
00263 return ! (c1 == c2);
00264 }
00265
00267 inline bool
00268 operator< (Command const& c1, Command const& c2)
00269 {
00270 return (!c1 && c2)
00271 || ( c1 && c2 && (&c1.impl() < &c2.impl()));
00272 }
00273
00274
00275
00276
00277 }
00278 #endif