WIP working out the details of Mutation and UndoMutation
This commit is contained in:
parent
909c7a1715
commit
2aee99f2f3
2 changed files with 68 additions and 13 deletions
|
|
@ -82,7 +82,7 @@ namespace control {
|
|||
|
||||
|
||||
class CmdClosure;
|
||||
typedef std::tr1::shared_ptr<CmdClosure> PClo; ///< smart-ptr type used for handling concrete closures
|
||||
typedef std::tr1::shared_ptr<CmdClosure> PClosure; ///< smart-ptr type used for handling concrete closures
|
||||
|
||||
|
||||
/** Interface */
|
||||
|
|
@ -91,7 +91,7 @@ namespace control {
|
|||
public:
|
||||
virtual ~CmdClosure() {}
|
||||
|
||||
virtual PClo clone() const =0;
|
||||
virtual PClosure clone() const =0;
|
||||
|
||||
virtual operator string() const =0;
|
||||
|
||||
|
|
@ -204,10 +204,10 @@ namespace control {
|
|||
* hidden behind the generic CmdClosure interface
|
||||
* and owned by a shared_ptr PClo.
|
||||
*/
|
||||
PClo
|
||||
PClosure
|
||||
clone() const
|
||||
{
|
||||
return PClo (new Closure (this->params_));
|
||||
return PClosure (new Closure (this->params_));
|
||||
}
|
||||
|
||||
operator string() const
|
||||
|
|
@ -215,6 +215,23 @@ namespace control {
|
|||
UNIMPLEMENTED ("how to do a string conversion on the variable argument tuple??");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Special kind of Closure, which \em decorates an existing Closure
|
||||
* and provides a captured state memento as additional parameter on invocation.
|
||||
*
|
||||
* @todo concept isn't clear yet. Multiple MementoClosurese are to decorate a single Closure;
|
||||
* they have to match and extract the concrete type of the Closure and the provided Memento,
|
||||
* but the latter needs to be erased immediately. Basically, MementoClosure must be able
|
||||
* to stand-in for an simple parameter closure.
|
||||
*/
|
||||
class MementoClosure
|
||||
: public CmdClosure
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -63,21 +63,25 @@ namespace control {
|
|||
class Mutation
|
||||
{
|
||||
CmdFunctor func_;
|
||||
PClo clo_;
|
||||
Closure* clo_;
|
||||
|
||||
public:
|
||||
template<typename SIG>
|
||||
Mutation (function<SIG> const& func)
|
||||
: func_(func)
|
||||
: func_(func),
|
||||
clo_(0)
|
||||
{ }
|
||||
|
||||
virtual ~Mutation() {}
|
||||
|
||||
|
||||
virtual Mutation&
|
||||
close (CmdClosure const& closure)
|
||||
close (Closure& cmdClosure)
|
||||
{
|
||||
UNIMPLEMENTED ("accept and store a parameter closure");
|
||||
REQUIRE (!clo_, "Lifecycle error: already closed over the arguments");
|
||||
REQUIRE (func_, "Param error: not bound to a valid function");
|
||||
func_ = cmdClosure->bindArguments(func_);
|
||||
clo_ = &cmdClosure;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -85,12 +89,15 @@ namespace control {
|
|||
void
|
||||
operator() ()
|
||||
{
|
||||
UNIMPLEMENTED ("invoke the Mutation functor");
|
||||
if (!clo_)
|
||||
throw lumiera::error::State ("Lifecycle error: function arguments not yet provided",
|
||||
LUMIERA_ERROR_UNBOUND_ARGUMENTS);
|
||||
invoke (func_);
|
||||
}
|
||||
|
||||
|
||||
/* == diagnostics == */
|
||||
typedef PClo Mutation::*_unspecified_bool_type;
|
||||
typedef PClosure Mutation::*_unspecified_bool_type;
|
||||
|
||||
/** implicit conversion to "bool" */
|
||||
operator _unspecified_bool_type() const { return isValid()? &Mutation::clo_ : 0; } // never throws
|
||||
|
|
@ -105,7 +112,20 @@ namespace control {
|
|||
virtual bool
|
||||
isValid () const
|
||||
{
|
||||
UNIMPLEMENTED ("mutation lifecycle");
|
||||
return func_ && clo_;
|
||||
}
|
||||
|
||||
void
|
||||
invoke (CmdFunctor & closedFunction)
|
||||
{
|
||||
closedFunction.getFun<void()>() ();
|
||||
}
|
||||
|
||||
CmdClosure&
|
||||
getClosure() ///< Interface for subclasses to access the bound parameters
|
||||
{
|
||||
REQUIRE (clo_, "Lifecycle error: function arguments not yet bound");
|
||||
return *clo_;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -151,15 +171,33 @@ namespace control {
|
|||
Mutation&
|
||||
captureState ()
|
||||
{
|
||||
UNIMPLEMENTED ("invoke the state capturing Functor");
|
||||
if (!Mutation::isValid())
|
||||
throw lumiera::error::State ("need to bind function arguments prior to capturing undo state",
|
||||
LUMIERA_ERROR_UNBOUND_ARGUMENTS);
|
||||
|
||||
if (!memento_) // on first invocation we have to close the capture function
|
||||
captureFunc_ = Mutation::getClosure().bindArguments(func_);
|
||||
|
||||
memento_.reset (new MementoClosure (Mutation::getClosure(), invoke(captureFunc_) )) //////TODO verify exception safety!
|
||||
|
||||
UNIMPLEMENTED ("how to make the inherited operator() use the extended Parameters (including the memento)???");
|
||||
return *this;
|
||||
}
|
||||
|
||||
CmdClosure&
|
||||
getMemento()
|
||||
{
|
||||
UNIMPLEMENTED ("return the closure serving as memento");
|
||||
return *memento_;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool
|
||||
isValid () const
|
||||
{
|
||||
return Mutation::isValid() && captureFunc_ && memento_;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue