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:
parent
925fa685b1
commit
246c535569
7 changed files with 51 additions and 56 deletions
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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....
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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...";
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue