00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00042 #ifndef CONTROL_COMMAND_ARGUMENT_HOLDER_H
00043 #define CONTROL_COMMAND_ARGUMENT_HOLDER_H
00044
00045 #include "lib/typed-allocation-manager.hpp"
00046 #include "proc/control/command-closure.hpp"
00047 #include "proc/control/memento-tie.hpp"
00048 #include "proc/control/command-impl-clone-builder.hpp"
00049 #include "lib/opaque-holder.hpp"
00050
00051 #include <string>
00052
00053
00054
00055 namespace control {
00056
00057 using lib::TypedAllocationManager;
00058 using lib::InPlaceBuffer;
00059 using std::string;
00060
00061
00062 namespace {
00063
00064 template<typename SIG>
00065 struct MissingArguments
00066 : Closure<SIG>
00067 {
00068 typedef typename Closure<SIG>::ArgTuple ArgTuple;
00069
00070 MissingArguments ()
00071 : Closure<SIG> (ArgTuple ())
00072 { }
00073
00074 private:
00075 virtual bool isValid () const { return false; }
00076 };
00077
00078
00079 template<typename SIG, typename MEM>
00080 struct UntiedMemento
00081 : MementoTie<SIG,MEM>
00082 {
00083 typedef typename CommandSignature<SIG,MEM>::CaptureSig SIG_cap;
00084 typedef typename CommandSignature<SIG,MEM>::UndoOp_Sig SIG_undo;
00085
00086 UntiedMemento()
00087 : MementoTie<SIG,MEM> (function<SIG_undo>(), function<SIG_cap>() )
00088 { }
00089 };
00090
00091 }
00092
00093
00094
00095
00106 template<typename SIG, typename MEM>
00107 class ArgumentHolder
00108 : public AbstractClosure
00109 {
00111 ArgumentHolder& operator= (ArgumentHolder const&);
00112
00113
00114 typedef Closure<SIG> ArgHolder;
00115 typedef MementoTie<SIG,MEM> MemHolder;
00116
00117 typedef InPlaceBuffer<ArgHolder, sizeof(ArgHolder), MissingArguments<SIG> > ArgumentBuff;
00118 typedef InPlaceBuffer<MemHolder, sizeof(MemHolder), UntiedMemento<SIG,MEM> > MementoBuff;
00119
00120 typedef typename ArgHolder::ArgTuple ArgTuple;
00121
00122
00123
00124
00125 ArgumentBuff arguments_;
00126 MementoBuff memento_;
00127
00128
00129
00130
00131
00132 public:
00133 virtual bool isValid () const
00134 {
00135 return arguments_->isValid();
00136 }
00137
00138 virtual bool isCaptured() const
00139 {
00140 return memento_->isValid();
00141 }
00142
00143
00144
00146 virtual void bindArguments (Arguments& args)
00147 {
00148 if (!arguments_->isValid())
00149 storeTuple (args.get<ArgTuple>());
00150 else
00151 arguments_->bindArguments(args);
00152 }
00153
00154
00155 virtual void invoke (CmdFunctor const& func)
00156 {
00157 if (!isValid())
00158 throw lumiera::error::State ("Lifecycle error: can't bind functor, "
00159 "command arguments not yet provided",
00160 LUMIERA_ERROR_UNBOUND_ARGUMENTS);
00161
00162 arguments_->invoke(func);
00163 }
00164
00165
00166 virtual operator string() const
00167 {
00168 return "Command-State{ arguments="
00169 + (*arguments_? string(*arguments_) : "unbound")
00170 + ", "+string(*memento_)+"}"
00171 ;
00172 }
00173
00174
00175
00181 ArgumentHolder ()
00182 : arguments_()
00183 , memento_()
00184 { }
00185
00187 ArgumentHolder (ArgumentHolder const& oAh)
00188 : arguments_()
00189 , memento_()
00190 {
00191 if (oAh.arguments_->isValid())
00192 arguments_.template create<ArgHolder> (*oAh.arguments_);
00193
00194
00195 memento_.template create<MemHolder> (*oAh.memento_);
00196 }
00197
00200 void
00201 accept (CommandImplCloneBuilder& visitor) const
00202 {
00203 visitor.buildCloneContext (*this);
00204 }
00205
00206
00208 bool canUndo () const { return memento_->isValid(); }
00209 bool empty () const { return !arguments_->isValid(); }
00210
00211
00214 void
00215 storeTuple (ArgTuple const& argTup)
00216 {
00217 arguments_.template create<ArgHolder> (argTup);
00218 }
00219
00220
00221 typedef typename CommandSignature<SIG,MEM>::OperateSig SIG_op;
00222 typedef typename CommandSignature<SIG,MEM>::CaptureSig SIG_cap;
00223 typedef typename CommandSignature<SIG,MEM>::UndoOp_Sig SIG_undo;
00224
00228 MementoTie<SIG,MEM>&
00229 tie (function<SIG_undo> const& undoFunc,
00230 function<SIG_cap> const& captureFunc)
00231 {
00232 return memento_.template create<MemHolder> (undoFunc,captureFunc);
00233 }
00234
00237 MementoTie<SIG,MEM>&
00238 getMementoWiring ()
00239 {
00240 return *memento_;
00241 }
00242
00243
00244
00248 MEM&
00249 memento ()
00250 {
00251 return memento_->getState();
00252 }
00253
00254 bool
00255 equals (CmdClosure const& other) const
00256 {
00257 const ArgumentHolder* toCompare = dynamic_cast<const ArgumentHolder*> (&other);
00258 return (toCompare)
00259 && (*this == *toCompare);
00260 }
00261
00263 friend bool
00264 operator== (ArgumentHolder const& a1, ArgumentHolder const& a2)
00265 {
00266 return (a1.arguments_->isValid() == a2.arguments_->isValid())
00267 && (*a1.arguments_ == *a2.arguments_)
00268 && (a1.memento_->isValid() == a2.memento_->isValid())
00269 && (*a1.memento_ == *a2.memento_)
00270 ;
00271 }
00272
00273 friend bool
00274 operator!= (ArgumentHolder const& a1, ArgumentHolder const& a2)
00275 {
00276 return ! (a1 == a2);
00277 }
00278 };
00279
00280
00281
00282 }
00283 #endif