Rewrite CmdClosure to actually invoke rather then to create a tr1::bind term

basically this should close Ticket #205  (some details missing)
This commit is contained in:
Fischlurch 2009-09-21 03:15:06 +02:00
parent 925fa685b1
commit 246c535569
7 changed files with 51 additions and 56 deletions

View file

@ -151,14 +151,14 @@ namespace control {
} }
virtual CmdFunctor closeArguments (CmdFunctor const& func) virtual void invoke (CmdFunctor const& func)
{ {
if (!isValid()) if (!isValid())
throw lumiera::error::State ("Lifecycle error: can't bind functor, " throw lumiera::error::State ("Lifecycle error: can't bind functor, "
"command arguments not yet provided", "command arguments not yet provided",
LUMIERA_ERROR_UNBOUND_ARGUMENTS); LUMIERA_ERROR_UNBOUND_ARGUMENTS);
return arguments_->closeArguments(func); arguments_->invoke(func);
} }

View file

@ -126,13 +126,13 @@ namespace control {
public: public:
virtual ~CmdClosure() {} virtual ~CmdClosure() {}
virtual operator string() const =0; virtual operator string() const =0;
virtual bool isValid () const =0; virtual bool isValid () const =0;
virtual void bindArguments (Arguments&) =0; virtual void bindArguments (Arguments&) =0;
virtual CmdFunctor closeArguments (CmdFunctor const&) =0; virtual void invoke (CmdFunctor const&) =0;
virtual PClo createClone (TypedAllocationManager&) =0; virtual PClo createClone (TypedAllocationManager&) =0;
}; };
@ -213,8 +213,8 @@ namespace control {
typedef typename FunctionSignature< function<SIG> >::Args Args; typedef typename FunctionSignature< function<SIG> >::Args Args;
typedef BuildTupleAccessor<Args,ParamAccessor> Accessor; typedef BuildTupleAccessor<Args,ParamAccessor> Builder;
typedef typename BuildAccessor::Accessor ParamStorageTuple; typedef typename Builder::Accessor ParamStorageTuple;
ParamStorageTuple params_; ParamStorageTuple params_;
@ -222,7 +222,7 @@ namespace control {
typedef Tuple<Args> ArgTuple; typedef Tuple<Args> ArgTuple;
Closure (ArgTuple const& args) Closure (ArgTuple const& args)
: params_(Accessor(args)) : params_(Builder (args))
{ } { }
/** create a clone copy of this, without disclosing the exact type */ /** create a clone copy of this, without disclosing the exact type */
@ -240,26 +240,19 @@ namespace control {
} }
/** Core operation: use the embedded argument tuple /** Core operation: use the embedded argument tuple for invoking a functor
* to close a given functor over its arguments. * @param unboundFunctor an function object, whose function arguments are
* @param unboundFunctor an function object, whose * required to match the types of the embedded ParamStorageTuple
* function arguments are required to match
* the types of the embedded ParamStorageTuple
* @return new functor object containing the function<void()>,
* which is created by binding all arguments of the
* input functor.
* @note ASSERTION failure if the function signature * @note ASSERTION failure if the function signature
* doesn't match the argument types tuple. * doesn't match the argument types tuple.
* @note when finally invoked, the functor, which is * @note the functor might actually \em modify the param values.
* bound here to the argument tuple, might actually * Thus this function can't be const.
* \em modify the param values. Thus this function
* can't be const.
*/ */
CmdFunctor void
closeArguments (CmdFunctor const& unboundFunctor) invoke (CmdFunctor const& unboundFunctor)
{ {
return CmdFunctor (TupleApplicator<SIG> (params_) TupleApplicator<SIG> apply_this_arguments(params_);
.bind ( unboundFunctor.getFun<SIG>()) ); apply_this_arguments (unboundFunctor.getFun<SIG>());
} }
@ -289,6 +282,5 @@ namespace control {
} // namespace control } // namespace control
#endif #endif

View file

@ -31,6 +31,7 @@
#include "proc/control/command-impl.hpp" #include "proc/control/command-impl.hpp"
#include "proc/control/command-argument-holder.hpp"
//#include "proc/mobject/mobject-ref.hpp" //#include "proc/mobject/mobject-ref.hpp"
//#include "proc/mobject/mobject.hpp" //#include "proc/mobject/mobject.hpp"
//#include "proc/mobject/placement.hpp" //#include "proc/mobject/placement.hpp"
@ -49,6 +50,13 @@ namespace control {
/////////////////////////////////////////TODO: is this impl file actually necessary?? /////////////////////////////////////////TODO: is this impl file actually necessary??
bool
CommandImpl::hasUndoState (CmdClosure const& closure)
{
UNIMPLEMENTED ("how the hell do we get at the memento-captured state???");
// REQUIRE (INSTANCEOF (ArgumentHolder, &closure));
// return static_cast<ArgumentHolder const&> (closure).canUndo();
}

View file

@ -43,8 +43,8 @@
#define CONTROL_COMMAND_IMPL_H #define CONTROL_COMMAND_IMPL_H
#include "proc/control/command.hpp" #include "proc/control/command.hpp"
#include "proc/control/command-closure.hpp"
#include "proc/control/command-mutation.hpp" #include "proc/control/command-mutation.hpp"
#include "proc/control/command-argument-holder.hpp"
#include "proc/control/typed-allocation-manager.hpp" #include "proc/control/typed-allocation-manager.hpp"
#include "lib/bool-checkable.hpp" #include "lib/bool-checkable.hpp"
@ -63,7 +63,11 @@ namespace control {
/** /**
* @todo Type-comment * Proc-Layer Command implementation.
* Data record holding together the parts necessary for command execution
* - command operation functor
* - a functor to UNDO the command effect
* - closure holding actual parameters and UNDO state
*/ */
class CommandImpl class CommandImpl
: public lib::BoolCheckable<CommandImpl : public lib::BoolCheckable<CommandImpl
@ -173,22 +177,23 @@ namespace control {
canExec() const ///< state check: sufficiently defined to be invoked canExec() const ///< state check: sufficiently defined to be invoked
{ {
return isValid() return isValid()
&& *pClo_ && do_; && *pClo_;
} }
bool bool
canUndo() const ///< state check: has undo state been captured? canUndo() const ///< state check: has undo state been captured?
{ {
return isValid() && undo_; return isValid() && hasUndoState(*pClo_);
} }
////////////////////////////////////////////////////////////////////////////////////TODO comparisons ////////////////////////////////////////////////////////////////////////////////////TODO comparisons
protected: private:
static bool hasUndoState (CmdClosure const&);
}; };
////////////////TODO currently just fleshing out the API....

View file

@ -84,7 +84,7 @@ namespace control {
void void
operator() (CmdClosure const& clo) operator() (CmdClosure& clo)
{ {
if (!clo) if (!clo)
throw lumiera::error::State ("Lifecycle error: function arguments not ready", throw lumiera::error::State ("Lifecycle error: function arguments not ready",
@ -128,7 +128,7 @@ namespace control {
Mutation& Mutation&
captureState (CmdClosure const& clo) captureState (CmdClosure& clo)
{ {
if (!clo) if (!clo)
throw lumiera::error::State ("need additional function arguments to be able to capture UNDO state", throw lumiera::error::State ("need additional function arguments to be able to capture UNDO state",

View file

@ -29,6 +29,7 @@
#include "lib/util.hpp" #include "lib/util.hpp"
#include <boost/format.hpp> #include <boost/format.hpp>
#include <tr1/functional>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <cstdlib> #include <cstdlib>
@ -325,9 +326,9 @@ namespace test {
typedef function<void()> OpFun; typedef function<void()> OpFun;
// now close all the functions with the stored parameter values... // now close all the functions with the stored parameter values...
OpFun bound_doItFun = args.closeArguments (CmdFunctor(doItFun)).getFun<void()>(); OpFun bound_doItFun = std::tr1::bind (&CmdClosure::invoke, args, CmdFunctor(doItFun));
OpFun bound_undoFun = args.closeArguments (CmdFunctor(undoFun)).getFun<void()>(); OpFun bound_undoFun = std::tr1::bind (&CmdClosure::invoke, args, CmdFunctor(undoFun));
OpFun bound_captFun = args.closeArguments (CmdFunctor(captFun)).getFun<void()>(); OpFun bound_captFun = std::tr1::bind (&CmdClosure::invoke, args, CmdFunctor(captFun));
protocol.seekp(0); protocol.seekp(0);
protocol << "START..."; protocol << "START...";

View file

@ -98,11 +98,12 @@ namespace test {
void void
checkMutation () checkMutation ()
{ {
function<void(int)> funky = testFunc; typedef void SIG_fun(int);
function<SIG_fun> funky = testFunc;
Mutation functor (funky); Mutation functor (funky);
MissingArguments nullClosure; MissingArguments<SIG_fun> nullClosure;
ASSERT (!nullClosure); ASSERT (!nullClosure);
cout << "empty placeholder closure: " << nullClosure << endl; cout << "empty placeholder closure: " << nullClosure << endl;
VERIFY_ERROR (UNBOUND_ARGUMENTS, functor(nullClosure) ); VERIFY_ERROR (UNBOUND_ARGUMENTS, functor(nullClosure) );
@ -151,14 +152,13 @@ namespace test {
UndoMutation undoFunctor (mementoHolder); UndoMutation undoFunctor (mementoHolder);
ASSERT (!mementoHolder); ASSERT (!mementoHolder);
MissingArguments nullClosure; MissingArguments<void(void)> nullClosure;
VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor(nullClosure) ); VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor(nullClosure) );
VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor.captureState(nullClosure) ); VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor.captureState(nullClosure) );
Tuple<Types<> > param; Tuple<Types<> > param;
Closure<void()> clo (param); Closure<void()> clo (param);
undoFunctor.close(clo);
ASSERT (!mementoHolder); ASSERT (!mementoHolder);
VERIFY_ERROR (MISSING_MEMENTO, undoFunctor (clo) ); VERIFY_ERROR (MISSING_MEMENTO, undoFunctor (clo) );
VERIFY_ERROR (MISSING_MEMENTO, mementoHolder.getState() ); VERIFY_ERROR (MISSING_MEMENTO, mementoHolder.getState() );
@ -182,17 +182,6 @@ namespace test {
testVal = 9; testVal = 9;
undoFunctor(clo); undoFunctor(clo);
ASSERT (testVal == 42); ASSERT (testVal == 42);
UndoMutation clonedFunc (undoFunctor); // refers to the same state
ASSERT (clonedFunc);
ASSERT (33 == mementoHolder.getState());
clonedFunc.captureState(clo);
ASSERT (42 == mementoHolder.getState()); // and captures into the same storage
testVal = 0;
clonedFunc(clo);
ASSERT (testVal == 42);
} }