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())
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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...";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue