00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00053 #ifndef CONTROL_COMMAND_DEF_H
00054 #define CONTROL_COMMAND_DEF_H
00055
00056
00057 #include "lib/error.hpp"
00058 #include "include/logging.h"
00059 #include "lib/symbol.hpp"
00060 #include "proc/control/command.hpp"
00061 #include "proc/control/command-impl.hpp"
00062 #include "proc/control/command-registry.hpp"
00063 #include "proc/control/command-signature.hpp"
00064 #include "proc/control/command-mutation.hpp"
00065 #include "proc/control/command-closure.hpp"
00066 #include "proc/control/argument-tuple-accept.hpp"
00067 #include "lib/bool-checkable.hpp"
00068 #include "lib/meta/function.hpp"
00069 #include "lib/meta/typelist.hpp"
00070 #include "lib/meta/typelist-util.hpp"
00071 #include "lib/meta/tuple.hpp"
00072 #include "lib/util.hpp"
00073
00074 #include <tr1/memory>
00075 #include <tr1/functional>
00076
00077
00078
00079
00080 namespace control {
00081
00082 using std::tr1::shared_ptr;
00083 using std::tr1::function;
00084 using std::tr1::bind;
00085 using std::tr1::placeholders::_1;
00086 using lib::Symbol;
00087 using util::cStr;
00088
00089 using lumiera::typelist::FunctionSignature;
00090 using lumiera::typelist::FunctionTypedef;
00091 using lumiera::typelist::Types;
00092 using lumiera::typelist::NullType;
00093 using lumiera::typelist::Tuple;
00094 using lumiera::typelist::tuple::makeNullTuple;
00095
00096
00097
00098
00099 namespace stage {
00100
00101 typedef shared_ptr<CommandImpl> ImplInstance;
00102 typedef function<Command&(ImplInstance const&)> Activation;
00103
00104
00105
00106
00107 template<typename SIG>
00108 struct CompletedDefinition
00109 : AcceptArgumentBindingRet< Command&, SIG
00110 , CompletedDefinition<SIG>
00111 >
00112 {
00113 Command& prototype_;
00114
00115 typedef typename FunctionSignature< function<SIG> >::Args CmdArgs;
00116
00117 CompletedDefinition (Command& definedCommand)
00118 : prototype_(definedCommand)
00119 {
00120 REQUIRE (prototype_);
00121 maybeArm_if_zero_parameters();
00122 TRACE (command_dbg, "Completed definition of %s.", cStr(prototype_));
00123 }
00124
00125
00126 typedef HandlingPattern::ID PattID;
00127
00130 CompletedDefinition
00131 setHandlingPattern (PattID newID)
00132 {
00133 prototype_.setHandlingPattern(newID);
00134 return *this;
00135 }
00136
00137
00141 Command&
00142 bindArg (Tuple<CmdArgs> const& params)
00143 {
00144 return prototype_.bindArg(params);
00145 }
00146
00147
00151 operator Command ()
00152 {
00153 return prototype_;
00154 }
00155
00156 private:
00161 void
00162 maybeArm_if_zero_parameters()
00163 {
00164 if (0 == Tuple<CmdArgs>::SIZE )
00165 prototype_.bindArg (makeNullTuple());
00166 }
00167 };
00168
00169
00170
00171
00172
00173 template<typename SIG, typename MEM>
00174 struct UndoDefinition
00175 {
00176 typedef CommandSignature<SIG,MEM> CmdType;
00177 typedef typename CmdType::OperateSig CommandOperationSig;
00178 typedef typename CmdType::UndoOp_Sig UndoOperationSig;
00179 typedef typename CmdType::CaptureSig UndoCaptureSig;
00180 typedef typename CmdType::CmdArgs CmdArgs;
00181
00182 typedef function<CommandOperationSig> OperFunc;
00183 typedef function<UndoOperationSig> UndoFunc;
00184 typedef function<UndoCaptureSig> CaptFunc;
00185
00186 Activation activatePrototype_;
00187 OperFunc operFunctor_;
00188 CaptFunc captFunctor_;
00189 UndoFunc undoFunctor_;
00190
00191
00192 UndoDefinition (Activation const& whenComplete,
00193 OperFunc const& commandOperation,
00194 CaptFunc const& undoCapOperation)
00195 : activatePrototype_(whenComplete)
00196 , operFunctor_(commandOperation)
00197 , captFunctor_(undoCapOperation)
00198 , undoFunctor_()
00199 { }
00200
00201
00202 CompletedDefinition<SIG>
00203 undoOperation (UndoOperationSig& how_to_Undo)
00204 {
00205 undoFunctor_ = UndoFunc (how_to_Undo);
00206 REQUIRE (operFunctor_);
00207 REQUIRE (undoFunctor_);
00208 REQUIRE (captFunctor_);
00209
00210 CommandRegistry& registry = CommandRegistry::instance();
00211 ImplInstance completedDef = registry.newCommandImpl(operFunctor_
00212 ,captFunctor_
00213 ,undoFunctor_);
00214 return CompletedDefinition<SIG> (activatePrototype_(completedDef));
00215 }
00216 };
00217
00218
00219
00220
00223 template<typename U_SIG>
00224 struct BuildUndoDefType
00225 {
00226 typedef UndoDefinition<typename U_SIG::OperateSig, typename U_SIG::Memento> Type;
00227 };
00228
00229
00230
00231
00232
00233
00234 template<typename SIG>
00235 struct BasicDefinition
00236 {
00237 Activation callback_;
00238 function<SIG> operation_;
00239
00240 BasicDefinition(Activation const& whenComplete, function<SIG> const& operation)
00241 : callback_(whenComplete)
00242 , operation_(operation)
00243 { }
00244
00245
00246 template<typename SIG2>
00247 typename BuildUndoDefType<UndoSignature<SIG2> >::Type
00248 captureUndo (SIG2& how_to_capture_UndoState)
00249 {
00250 typedef typename UndoSignature<SIG2>::CaptureSig UndoCapSig;
00251 typedef typename BuildUndoDefType<UndoSignature<SIG2> >::Type SpecificUndoDefinition;
00252
00253 function<UndoCapSig> captureOperation (how_to_capture_UndoState);
00254 return SpecificUndoDefinition (callback_, operation_, captureOperation);
00255 }
00256 };
00257
00258 }
00259
00260
00278 class CommandDef
00279 : public lib::BoolCheckable<CommandDef>
00280 {
00281 Symbol id_;
00282 Command prototype_;
00283
00284 typedef stage::ImplInstance PImpl;
00285 typedef stage::Activation Activation;
00286
00287 public:
00288 CommandDef (Symbol cmdID)
00289 : id_(cmdID)
00290 , prototype_(Command::fetchDef(cmdID))
00291 {
00292 TRACE (command_dbg, "starting CommandDef('%s')...", cmdID.c() );
00293 }
00294
00295 ~CommandDef();
00296
00297
00298
00299 template<typename SIG>
00300 stage::BasicDefinition<SIG>
00301 operation (SIG& operation_to_define)
00302 {
00303 function<SIG> opera1 (operation_to_define);
00304 Activation callback_when_defined = bind (&CommandDef::activate, this, _1);
00305
00306 return stage::BasicDefinition<SIG>(callback_when_defined, opera1);
00307 }
00308
00309
00310 bool isValid() const;
00311
00312
00313 private:
00317 Command& activate (PImpl const& completedDef)
00318 {
00319 prototype_.activate (completedDef, id_);
00320 ENSURE (prototype_);
00321 return prototype_;
00322 }
00323 };
00324
00325
00326
00327
00328
00329 }
00330 #endif