WIP working out the details of Mutation and UndoMutation

This commit is contained in:
Fischlurch 2009-06-23 05:54:54 +02:00
parent 909c7a1715
commit 2aee99f2f3
2 changed files with 68 additions and 13 deletions

View file

@ -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....

View file

@ -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....