From 2348a5af2b5298df175ddba67d9912f96335587b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 6 Jul 2009 05:26:31 +0200 Subject: [PATCH] WIP draft capturing mechanism implementation, using the new tools and helpers... --- src/proc/control/command-mutation.hpp | 72 +++++-------------------- src/proc/control/memento-tie.hpp | 78 ++++++++++++++++++++------- 2 files changed, 74 insertions(+), 76 deletions(-) diff --git a/src/proc/control/command-mutation.hpp b/src/proc/control/command-mutation.hpp index cf745b778..0b1fa9937 100644 --- a/src/proc/control/command-mutation.hpp +++ b/src/proc/control/command-mutation.hpp @@ -37,6 +37,7 @@ //#include "pre.hpp" #include "lib/error.hpp" +#include "lib/bool-checkable.hpp" #include "proc/control/command-closure.hpp" #include "proc/control/memento-tie.hpp" @@ -66,6 +67,7 @@ namespace control { * @todo Type-comment */ class Mutation + : public lib::BoolCheckable { CmdFunctor func_; CmdClosure* clo_; @@ -101,37 +103,24 @@ namespace control { } - /* == diagnostics == */ - typedef CmdClosure* Mutation::*_unspecified_bool_type; - - /** implicit conversion to "bool" */ - operator _unspecified_bool_type() const { return isValid()? &Mutation::clo_ : 0; } // never throws - bool operator! () const { return !isValid(); } // ditto - + /** diagnostics */ operator string() const { return isValid()? string (*clo_) : "Mutation(state missing)"; } - protected: virtual bool isValid () const { return func_ && clo_; } + protected: void invoke (CmdFunctor & closedFunction) { closedFunction.getFun() (); } - - CmdClosure& - getClosure() ///< Interface for subclasses to access the bound parameters - { - REQUIRE (clo_, "Lifecycle error: function arguments not yet bound"); - return *clo_; - } }; @@ -146,51 +135,24 @@ namespace control { class UndoMutation : public Mutation { - Mutation memento_; + Mutation captureMemento_; public: - template - UndoMutation (function const& undoFunc, - function const& captureFunc) - : Mutation (undoFunc) - , memento_(captureFunc) + template + UndoMutation (TIE & mementoHolder) + : Mutation (mementoHolder.tieUndoFunc()) + , captureMemento_(mementoHolder.tieCaptureFunc()) { } - -#if false /////////////////////////////////////////////////TODO: remove after refactoring - UndoMutation (UndoMutation const& o) - : Mutation (*this) - , captureFunc_(o.captureFunc_) - , memento_(o.memento_->clone().get()) - { } - - UndoMutation& - operator= (UndoMutation const& o) - { - Mutation::operator= (o); - captureFunc_ = o.captureFunc_; - memento_.reset(o.memento_->clone().get()); - return *this; - } virtual Mutation& close (CmdClosure& cmdClosure) { - REQUIRE (!memento_, "Lifecycle error: already closed over the arguments"); - REQUIRE (captureFunc_, "Param error: not bound to a valid function"); - - // create a special state closure, which can later on store the captured undo state (memento) - scoped_ptr stateClosure (new MementoClosure (captureFunc_)); - CmdFunctor closedCaptureFunc = cmdClosure.bindArguments(captureFunc_); - - // the undoFunc (within parent class) will retrieve an argument tuple extended by the memento - Mutation::close (stateClosure->decorate (cmdClosure)); - - captureFunc_ = closedCaptureFunc; -// memento_.swap(stateClosure); + Mutation::close(cmdClosure); + captureMemento_.close(cmdClosure); return *this; } -#endif + Mutation& captureState () @@ -199,22 +161,16 @@ namespace control { throw lumiera::error::State ("need to bind function arguments prior to capturing undo state", LUMIERA_ERROR_UNBOUND_ARGUMENTS); - memento_(); + captureMemento_(); return *this; } - CmdClosure& - getMemento() - { - ASSERT (memento_, "Lifecycle error: need to close first"); -// return *memento_; - } private: virtual bool isValid () const { -// return Mutation::isValid() && captureFunc_ && memento_; + return Mutation::isValid() && memento_; } diff --git a/src/proc/control/memento-tie.hpp b/src/proc/control/memento-tie.hpp index 14fc45a90..2f73575b7 100644 --- a/src/proc/control/memento-tie.hpp +++ b/src/proc/control/memento-tie.hpp @@ -28,7 +28,6 @@ ** the "undo capture function" and the actual "undo function", by retrieving the ** memento data or memento object from the former and feeding it to the latter ** as an additional parameter, when the undo operation is invoked. - ** //TODO ** ** @see CmdClosure ** @see UndoMutation @@ -44,7 +43,7 @@ //#include "pre.hpp" //#include "lib/meta/typelist.hpp" ////////////////TODO include these?? //#include "lib/meta/function.hpp" -//#include "lib/meta/function-closure.hpp" +#include "lib/meta/function-closure.hpp" //#include "lib/meta/function-erasure.hpp" //#include "lib/meta/tuple.hpp" #include "proc/control/command-signature.hpp" @@ -52,7 +51,7 @@ #include "lib/util.hpp" //#include -//#include +#include //#include //#include @@ -70,6 +69,7 @@ namespace control { // using std::tr1::shared_ptr; // using util::unConst; using std::string; + using lumiera::typelist::func::bindLast; // using std::ostream; // using std::tr1::function; // using lumiera::typelist::FunctionSignature; @@ -85,10 +85,10 @@ namespace control { /** * Binding together state capturing and execution of the undo operation. - * MementoTie itself is passive container object with a very specific type, + * MementoTie itself is a passive container object with a very specific type, * depending on the type of the operation arguments and the type of the memento. * It is to be allocated within the ArgumentHolder of the command, thereby wrapping - * or decorating the undo and capture function, setting up the necessary bindings and + * or decorating the undo and capture function, setting up the necessary bindings and * closures, allowing them to cooperate behind the scenes to carry out the UNDO functionality. * Through a reference to the MementoTie, the UndoMutation functor gets access to the prepared * functions, storing them into generic containers (type erasure) for later invocation. @@ -109,20 +109,15 @@ namespace control { /** storage holding the captured state for undo */ MEM memento_; - function undo_; - function capture_; + bool isCaptured_; + function undo_; + function capture_; - function - buildFun() + void capture (MEM const& mementoVal) { -// PlaceholderTuple tup; -// return tupleApplicator(tup).bind(origFun); - } - - void capture () - { - memento_ = capture(); + memento_ = mementoVal; + isCaptured_ = true; } public: @@ -133,11 +128,58 @@ namespace control { */ MementoTie (function const& undoFunc, function const& captureFunc) + : memento_() + , isCaptured_(false) + , undo_(undoFunc) + , capture_(captureFunc) { } + + /** bind the undo function to the internal memento store within this object. + * @return a functor, which, when invoked with the remaining arguments, will + * automatically call #getState() to retrieve the current memento value. + * @note similar to #getState(), the returned functor will throw + * when the state capturing wasn't yet invoked + */ + function + tieUndoFunc() + { + using std::tr1::bind; + + return bindLast( undo_ + , bind (&MementoTie::getState, this) + ); + } + + /** bind the capturing function to the internal memento store within this object. + * @return a functor, which on invocation will automatically store the return value + * of the capturing function (= the current memento value) into the field + * #memento_ within this object + */ + function + tieCaptureFunc() + { + using std::tr1::placeholders::_1; + + function doCaptureMemento = bind (&MementoTie::capture, this, _1); + + return chained(capture_, doCaptureMemento); + } + + + /** get the currently captured memento state value + * @throw when the capturing function wasn't yet invoked + */ + MEM& + getState () + { + if (!isCaptured_) + throw lumiera::error::State ("need to invoke memento state capturing beforehand", + LUMIERA_ERROR_MISSING_MEMENTO); + return memento_; + } + }; - - ////////////////TODO currently just fleshing out the API....