WIP impl draft for ArgumentHolder
This commit is contained in:
parent
6ef1aca3a4
commit
accaba4904
5 changed files with 124 additions and 38 deletions
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
//#include "pre.hpp"
|
||||
//#include "lib/error.hpp"
|
||||
#include "proc/control/command-closure.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
//#include <boost/scoped_ptr.hpp>
|
||||
|
|
@ -60,38 +61,128 @@ namespace control {
|
|||
// using std::tr1::shared_ptr;
|
||||
// using boost::scoped_ptr;
|
||||
// using std::tr1::function;
|
||||
using std::ostream;
|
||||
// using std::ostream;
|
||||
using std::string;
|
||||
|
||||
namespace { // empty state marker objects for ArgumentHolder
|
||||
|
||||
template<typename SIG>
|
||||
struct MissingArguments
|
||||
: Closure<SIG>
|
||||
{
|
||||
typedef typename Closure<SIG>::ArgTuple ArgTuple;
|
||||
|
||||
MissingArguments ()
|
||||
: Closure<SIG> (ArgTuple ())
|
||||
{ }
|
||||
|
||||
private:
|
||||
virtual bool isValid () const { return false; }
|
||||
};
|
||||
|
||||
|
||||
template<typename SIG, typename MEM>
|
||||
struct UntiedMemento
|
||||
: MementoTie<SIG,MEM>
|
||||
{
|
||||
typedef typename CommandSignature<SIG,MEM>::CaptureSig SIG_cap;
|
||||
typedef typename CommandSignature<SIG,MEM>::UndoOp_Sig SIG_undo;
|
||||
|
||||
UntiedMemento()
|
||||
: MementoTie<SIG,MEM> (function<SIG_undo>, function<SIG_cap>)
|
||||
{ }
|
||||
};
|
||||
|
||||
} // (END) impl details / empty state marker objects
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @todo Type-comment
|
||||
/* Specifically typed CmdClosure, which serves for
|
||||
* actually allocating storage to hold the command arguments
|
||||
* and the undo state (memento) for Proc-Layer commands.
|
||||
*/
|
||||
class CommandArgumentHolder
|
||||
{
|
||||
|
||||
public:
|
||||
virtual ~CommandArgumentHolder() { };
|
||||
virtual operator string() const =0;
|
||||
};
|
||||
|
||||
|
||||
inline ostream& operator<< (ostream& os, CommandArgumentHolder const& arg) { return os << string(arg); }
|
||||
|
||||
|
||||
|
||||
|
||||
/** specifically typed subclass used for actual storage */
|
||||
template<typename SIG, typename MEM>
|
||||
class ArgumentHolder
|
||||
: public CommandArgumentHolder
|
||||
: public CmdClosure
|
||||
{
|
||||
Closure<SIG> arguments_;
|
||||
MementoTie<SIG,MEM> memento_;
|
||||
|
||||
operator string() const { return "bääääh!"; } /////////////////TODO
|
||||
typedef typename Closure<SIG>::ArgTuple ArgTuple;
|
||||
|
||||
|
||||
/* === proxied CmdClosure interface === */
|
||||
|
||||
virtual bool isValid () const
|
||||
{
|
||||
return bool(arguments_);
|
||||
}
|
||||
|
||||
|
||||
virtual CmdFunctor bindArguments (CmdFunctor& func)
|
||||
{
|
||||
if (!arguments_)
|
||||
throw lumiera::error::State ("Lifecycle error: can't bind functor, "
|
||||
"command arguments not yet provided",
|
||||
LUMIERA_ERROR_UNBOUND_ARGUMENTS);
|
||||
|
||||
return arguments_.bindArguments(func);
|
||||
}
|
||||
|
||||
|
||||
virtual operator string() const
|
||||
{
|
||||
return "Command-State{ arguments="
|
||||
+ arguments_? arguments_ : "unbound"
|
||||
+ memento_ ? ", <memento> }" : "<no undo> }"
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
/** per default, all data within ArgumentHolder
|
||||
* is set up in \em empty state. Later on, the
|
||||
* command arguments are to be provided by #bind ,
|
||||
* whereas the undo functions will be wired by #tie
|
||||
*/
|
||||
ArgumentHolder ()
|
||||
: arguments_(MissingArguments<SIG>)
|
||||
, memento_(UntiedMemento<SIG,MEM>)
|
||||
{ }
|
||||
|
||||
/** has undo state capturing been invoked? */
|
||||
bool
|
||||
canUndo ()
|
||||
{
|
||||
return bool(memento_);
|
||||
}
|
||||
|
||||
|
||||
/** store a new argument tuple within this ArgumentHolder,
|
||||
* discarding and previously stored arguments */
|
||||
void
|
||||
bind (ArgTuple argTup)
|
||||
{
|
||||
this->arguments_ = Closure<SIG> (argTup);
|
||||
}
|
||||
|
||||
|
||||
typedef typename CommandSignature<SIG,MEM>::CaptureSig SIG_cap;
|
||||
typedef typename CommandSignature<SIG,MEM>::UndoOp_Sig SIG_undo;
|
||||
|
||||
/** create a new memento storage wiring, discarding existing memento state.
|
||||
* @note any bound undo/capture functions based on the previously held MementoTie
|
||||
* are silently invalidated; using them will likely cause memory corruption! */
|
||||
MementoTie<SIG,MEM>&
|
||||
tie (function<SIG_undo> const& undoFunc,
|
||||
function<SIG_cap> const& captureFunc)
|
||||
{
|
||||
return this->memento_ = MementoTie<SIG,MEM> (undoFunc,captureFunc);
|
||||
}
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#define CONTROL_COMMAND_CLOSURE_H
|
||||
|
||||
//#include "pre.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/meta/typelist.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/function-closure.hpp"
|
||||
|
|
@ -73,7 +74,11 @@ namespace control {
|
|||
using lumiera::typelist::StoreFunction;
|
||||
|
||||
using lumiera::typelist::NullType;
|
||||
|
||||
|
||||
|
||||
|
||||
LUMIERA_ERROR_DECLARE (UNBOUND_ARGUMENTS); ///< Command functor not yet usable, because arguments aren't bound
|
||||
|
||||
|
||||
/**
|
||||
* A neutral container internally holding
|
||||
|
|
@ -82,19 +87,17 @@ namespace control {
|
|||
typedef FunErasure<StoreFunction> CmdFunctor;
|
||||
|
||||
|
||||
class CmdClosure;
|
||||
typedef std::tr1::shared_ptr<CmdClosure> PClosure; ///< smart-ptr type used for handling concrete closures
|
||||
|
||||
|
||||
/** Interface */
|
||||
class CmdClosure
|
||||
: public lib::BoolCheckable<CmdClosure>
|
||||
{
|
||||
public:
|
||||
virtual ~CmdClosure() {}
|
||||
|
||||
virtual PClosure clone() const =0;
|
||||
virtual operator string() const =0;
|
||||
|
||||
virtual operator string() const =0;
|
||||
virtual bool isValid () const { return true; }
|
||||
|
||||
virtual CmdFunctor bindArguments (CmdFunctor&) =0;
|
||||
};
|
||||
|
|
@ -159,7 +162,6 @@ namespace control {
|
|||
{
|
||||
typedef typename FunctionSignature< function<SIG> >::Args Args;
|
||||
|
||||
typedef Tuple<Args> ArgTuple;
|
||||
|
||||
typedef BuildTupleAccessor<Args,ParamAccessor> BuildAccessor;
|
||||
typedef typename BuildAccessor::Accessor ParamStorageTuple;
|
||||
|
|
@ -167,6 +169,8 @@ namespace control {
|
|||
ParamStorageTuple params_;
|
||||
|
||||
public:
|
||||
typedef Tuple<Args> ArgTuple;
|
||||
|
||||
Closure (ArgTuple const& args)
|
||||
: params_(BuildAccessor(args))
|
||||
{ }
|
||||
|
|
@ -195,15 +199,6 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
/** create a clone copy of this concrete closure,
|
||||
* hidden behind the generic CmdClosure interface
|
||||
* and owned by a shared_ptr PClo.
|
||||
*/
|
||||
PClosure
|
||||
clone() const
|
||||
{
|
||||
return PClosure (new Closure (this->params_));
|
||||
}
|
||||
|
||||
operator string() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ namespace control {
|
|||
using std::string;
|
||||
|
||||
|
||||
LUMIERA_ERROR_DECLARE (UNBOUND_ARGUMENTS); ///< Mutation functor not yet usable, because arguments aren't bound
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
namespace control {
|
||||
|
||||
LUMIERA_ERROR_DEFINE (UNBOUND_ARGUMENTS, "Mutation functor not yet usable, because arguments aren't bound");
|
||||
LUMIERA_ERROR_DEFINE (UNBOUND_ARGUMENTS, "Command mutation functor not yet usable, because arguments aren't bound");
|
||||
LUMIERA_ERROR_DEFINE (MISSING_MEMENTO, "Undo functor not yet usable, because no undo state has been captured");
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ namespace test {
|
|||
bound_undoFun();
|
||||
cout << protocol.str() << endl;
|
||||
|
||||
// Commands can serve as prototype to be copied....
|
||||
Args argsCopy (args);
|
||||
bound_captFun();
|
||||
protocol.seekp(0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue