WIP brainstorming about a way how the extended memento capturing closure might work

This commit is contained in:
Fischlurch 2009-06-24 05:51:02 +02:00
parent 2aee99f2f3
commit 69d6bad1f4
2 changed files with 68 additions and 6 deletions

View file

@ -168,6 +168,24 @@ namespace control {
}
virtual Mutation&
close (Closure& 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<CmdClosure> stateClosure (new MementoClosure (captureFunc_));
CmdFunctor closedCaptureFunc = stateClosure->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;
}
Mutation&
captureState ()
{
@ -175,18 +193,14 @@ namespace control {
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)???");
invoke(captureFunc_);
return *this;
}
CmdClosure&
getMemento()
{
ASSERT (memento_, "Lifecycle error: need to close first");
return *memento_;
}

View file

@ -41,6 +41,7 @@
#include <tr1/functional>
//#include <boost/format.hpp>
#include <iostream>
#include <cstdlib>
#include <string>
using std::tr1::bind;
@ -51,6 +52,7 @@ using std::tr1::function;
//using lumiera::Time;
//using util::contains;
using std::string;
using std::rand;
using std::cout;
using std::endl;
@ -135,6 +137,8 @@ namespace test {
functor.close(clo);
ASSERT (functor);
cout << "param values: " << clo << endl;
testVal = 0;
functor();
ASSERT (testVal == 23);
@ -202,6 +206,50 @@ namespace test {
clonedFunc();
ASSERT (testVal == 42);
}
void
checkStateCapturingClosure ()
{
function<void(int)> undo_func = bind (&testFunc,_1);
function<int(void)> cap_func = bind (&capture );
MementoClosure memClo (cap_func);
CmdFunctor closed_cap_func = memClo.bindArguments (cap_func);
Tuple<Types<> > param;
Closure<void()> clo (param);
cout << "plain param values: " << clo << endl;
Closure<void(int)> extendedClo = memClo.decorate (clo);
cout << "params including memento storage: " << extendedClo << endl;
CmdFunctor closed_undo_func = extendedClo.bindArguments (undo_func);
VERIFY_ERROR (MISSING_MEMENTO, closed_undo_func() ); // invalid, because no state was captured
int rr (rand() %100);
testVal = rr;
closed_cap_func(); // invoke state capturing
cout << "params including memento: " << memClo << endl;
cout << "captured memento state : " << extendedClo << endl;
testVal = -10; // meanwhile "somehow" mutate the state
closed_undo_func(); // invoking the undo() feeds back the memento
ASSERT (rr == testVal); // which is then restored into the state
// this cycle can be repeated with different state values
rr = (rand() %100);
testVal = rr;
closed_cap_func(); // capture new state
cout << "params including memento: " << memClo << endl;
// ....note the changed memento!
testVal = -20;
closed_undo_func();
ASSERT (rr == testVal);
}
};