WIP draft capturing mechanism implementation, using the new tools and helpers...

This commit is contained in:
Fischlurch 2009-07-06 05:26:31 +02:00
parent c8c577c4cc
commit 2348a5af2b
2 changed files with 74 additions and 76 deletions

View file

@ -37,6 +37,7 @@
//#include "pre.hpp" //#include "pre.hpp"
#include "lib/error.hpp" #include "lib/error.hpp"
#include "lib/bool-checkable.hpp"
#include "proc/control/command-closure.hpp" #include "proc/control/command-closure.hpp"
#include "proc/control/memento-tie.hpp" #include "proc/control/memento-tie.hpp"
@ -66,6 +67,7 @@ namespace control {
* @todo Type-comment * @todo Type-comment
*/ */
class Mutation class Mutation
: public lib::BoolCheckable<Mutation>
{ {
CmdFunctor func_; CmdFunctor func_;
CmdClosure* clo_; CmdClosure* clo_;
@ -101,37 +103,24 @@ namespace control {
} }
/* == diagnostics == */ /** 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
operator string() const operator string() const
{ {
return isValid()? string (*clo_) : "Mutation(state missing)"; return isValid()? string (*clo_) : "Mutation(state missing)";
} }
protected:
virtual bool virtual bool
isValid () const isValid () const
{ {
return func_ && clo_; return func_ && clo_;
} }
protected:
void void
invoke (CmdFunctor & closedFunction) invoke (CmdFunctor & closedFunction)
{ {
closedFunction.getFun<void()>() (); closedFunction.getFun<void()>() ();
} }
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 class UndoMutation
: public Mutation : public Mutation
{ {
Mutation memento_; Mutation captureMemento_;
public: public:
template<typename SIG_undo, typename SIG_cap> template<typename TIE>
UndoMutation (function<SIG_undo> const& undoFunc, UndoMutation (TIE & mementoHolder)
function<SIG_cap> const& captureFunc) : Mutation (mementoHolder.tieUndoFunc())
: Mutation (undoFunc) , captureMemento_(mementoHolder.tieCaptureFunc())
, memento_(captureFunc)
{ } { }
#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& virtual Mutation&
close (CmdClosure& cmdClosure) close (CmdClosure& cmdClosure)
{ {
REQUIRE (!memento_, "Lifecycle error: already closed over the arguments"); Mutation::close(cmdClosure);
REQUIRE (captureFunc_, "Param error: not bound to a valid function"); captureMemento_.close(cmdClosure);
// create a special state closure, which can later on store the captured undo state (memento)
scoped_ptr<MementoClosure> 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);
return *this; return *this;
} }
#endif
Mutation& Mutation&
captureState () captureState ()
@ -199,22 +161,16 @@ namespace control {
throw lumiera::error::State ("need to bind function arguments prior to capturing undo state", throw lumiera::error::State ("need to bind function arguments prior to capturing undo state",
LUMIERA_ERROR_UNBOUND_ARGUMENTS); LUMIERA_ERROR_UNBOUND_ARGUMENTS);
memento_(); captureMemento_();
return *this; return *this;
} }
CmdClosure&
getMemento()
{
ASSERT (memento_, "Lifecycle error: need to close first");
// return *memento_;
}
private: private:
virtual bool virtual bool
isValid () const isValid () const
{ {
// return Mutation::isValid() && captureFunc_ && memento_; return Mutation::isValid() && memento_;
} }

View file

@ -28,7 +28,6 @@
** the "undo capture function" and the actual "undo function", by retrieving the ** 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 ** memento data or memento object from the former and feeding it to the latter
** as an additional parameter, when the undo operation is invoked. ** as an additional parameter, when the undo operation is invoked.
** //TODO
** **
** @see CmdClosure ** @see CmdClosure
** @see UndoMutation ** @see UndoMutation
@ -44,7 +43,7 @@
//#include "pre.hpp" //#include "pre.hpp"
//#include "lib/meta/typelist.hpp" ////////////////TODO include these?? //#include "lib/meta/typelist.hpp" ////////////////TODO include these??
//#include "lib/meta/function.hpp" //#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/function-erasure.hpp"
//#include "lib/meta/tuple.hpp" //#include "lib/meta/tuple.hpp"
#include "proc/control/command-signature.hpp" #include "proc/control/command-signature.hpp"
@ -52,7 +51,7 @@
#include "lib/util.hpp" #include "lib/util.hpp"
//#include <tr1/memory> //#include <tr1/memory>
//#include <tr1/functional> #include <tr1/functional>
//#include <iostream> //#include <iostream>
//#include <string> //#include <string>
@ -70,6 +69,7 @@ namespace control {
// using std::tr1::shared_ptr; // using std::tr1::shared_ptr;
// using util::unConst; // using util::unConst;
using std::string; using std::string;
using lumiera::typelist::func::bindLast;
// using std::ostream; // using std::ostream;
// using std::tr1::function; // using std::tr1::function;
// using lumiera::typelist::FunctionSignature; // using lumiera::typelist::FunctionSignature;
@ -85,10 +85,10 @@ namespace control {
/** /**
* Binding together state capturing and execution of the undo operation. * 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. * 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 * 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. * 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 * 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. * functions, storing them into generic containers (type erasure) for later invocation.
@ -109,20 +109,15 @@ namespace control {
/** storage holding the captured state for undo */ /** storage holding the captured state for undo */
MEM memento_; MEM memento_;
function<SIG> undo_; bool isCaptured_;
function<SIG> capture_;
function<SIG_undo> undo_;
function<SIG_cap> capture_;
function<SIG> void capture (MEM const& mementoVal)
buildFun()
{ {
// PlaceholderTuple<SIG> tup; memento_ = mementoVal;
// return tupleApplicator(tup).bind(origFun); isCaptured_ = true;
}
void capture ()
{
memento_ = capture();
} }
public: public:
@ -133,11 +128,58 @@ namespace control {
*/ */
MementoTie (function<SIG_undo> const& undoFunc, MementoTie (function<SIG_undo> const& undoFunc,
function<SIG_cap> const& captureFunc) function<SIG_cap> 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<SIG>
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<SIG>
tieCaptureFunc()
{
using std::tr1::placeholders::_1;
function<void(MEM)> 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....