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())
throw lumiera::error::State ("Lifecycle error: can't bind functor, "
"command arguments not yet provided",
LUMIERA_ERROR_UNBOUND_ARGUMENTS);
return arguments_->closeArguments(func);
arguments_->invoke(func);
}

View file

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

View file

@ -31,6 +31,7 @@
#include "proc/control/command-impl.hpp"
#include "proc/control/command-argument-holder.hpp"
//#include "proc/mobject/mobject-ref.hpp"
//#include "proc/mobject/mobject.hpp"
//#include "proc/mobject/placement.hpp"
@ -49,7 +50,14 @@ namespace control {
/////////////////////////////////////////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
#include "proc/control/command.hpp"
#include "proc/control/command-closure.hpp"
#include "proc/control/command-mutation.hpp"
#include "proc/control/command-argument-holder.hpp"
#include "proc/control/typed-allocation-manager.hpp"
#include "lib/bool-checkable.hpp"
@ -59,11 +59,15 @@ namespace control {
using std::tr1::function;
using std::tr1::shared_ptr;
/**
* @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
: public lib::BoolCheckable<CommandImpl
@ -173,25 +177,26 @@ namespace control {
canExec() const ///< state check: sufficiently defined to be invoked
{
return isValid()
&& *pClo_ && do_;
&& *pClo_;
}
bool
canUndo() const ///< state check: has undo state been captured?
{
return isValid() && undo_;
return isValid() && hasUndoState(*pClo_);
}
////////////////////////////////////////////////////////////////////////////////////TODO comparisons
protected:
private:
static bool hasUndoState (CmdClosure const&);
};
////////////////TODO currently just fleshing out the API....
} // namespace control

View file

@ -84,7 +84,7 @@ namespace control {
void
operator() (CmdClosure const& clo)
operator() (CmdClosure& clo)
{
if (!clo)
throw lumiera::error::State ("Lifecycle error: function arguments not ready",
@ -128,7 +128,7 @@ namespace control {
Mutation&
captureState (CmdClosure const& clo)
captureState (CmdClosure& clo)
{
if (!clo)
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 <boost/format.hpp>
#include <tr1/functional>
#include <iostream>
#include <sstream>
#include <cstdlib>
@ -325,9 +326,9 @@ namespace test {
typedef function<void()> OpFun;
// now close all the functions with the stored parameter values...
OpFun bound_doItFun = args.closeArguments (CmdFunctor(doItFun)).getFun<void()>();
OpFun bound_undoFun = args.closeArguments (CmdFunctor(undoFun)).getFun<void()>();
OpFun bound_captFun = args.closeArguments (CmdFunctor(captFun)).getFun<void()>();
OpFun bound_doItFun = std::tr1::bind (&CmdClosure::invoke, args, CmdFunctor(doItFun));
OpFun bound_undoFun = std::tr1::bind (&CmdClosure::invoke, args, CmdFunctor(undoFun));
OpFun bound_captFun = std::tr1::bind (&CmdClosure::invoke, args, CmdFunctor(captFun));
protocol.seekp(0);
protocol << "START...";

View file

@ -98,11 +98,12 @@ namespace test {
void
checkMutation ()
{
function<void(int)> funky = testFunc;
typedef void SIG_fun(int);
function<SIG_fun> funky = testFunc;
Mutation functor (funky);
MissingArguments nullClosure;
MissingArguments<SIG_fun> nullClosure;
ASSERT (!nullClosure);
cout << "empty placeholder closure: " << nullClosure << endl;
VERIFY_ERROR (UNBOUND_ARGUMENTS, functor(nullClosure) );
@ -151,14 +152,13 @@ namespace test {
UndoMutation undoFunctor (mementoHolder);
ASSERT (!mementoHolder);
MissingArguments nullClosure;
MissingArguments<void(void)> nullClosure;
VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor(nullClosure) );
VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor.captureState(nullClosure) );
Tuple<Types<> > param;
Closure<void()> clo (param);
undoFunctor.close(clo);
ASSERT (!mementoHolder);
VERIFY_ERROR (MISSING_MEMENTO, undoFunctor (clo) );
VERIFY_ERROR (MISSING_MEMENTO, mementoHolder.getState() );
@ -182,17 +182,6 @@ namespace test {
testVal = 9;
undoFunctor(clo);
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);
}