second shot for implementing the binding: better the other way round
This commit is contained in:
parent
b6246cbb10
commit
a677e2edde
6 changed files with 56 additions and 34 deletions
|
|
@ -492,47 +492,40 @@ namespace control {
|
|||
/**
|
||||
* Adapter interface for invoking an argument binding (e.g. as defined through
|
||||
* AcceptArgumentBinding) \em without the need to disclose the concrete type
|
||||
* actually accepting the bind call. This is an application of the "type erasure"
|
||||
* pattern; in order to use it
|
||||
* - the concrete type accepting the \bind(..) call need to have a vtable,
|
||||
* so it can be re-discovered by dynamic_cast
|
||||
* - moreover, the concrete type must inherit from
|
||||
* - at the call site, only a reference to the adapter interface is exposed.
|
||||
* actually accepting the bind call. This is an application of "type erasure"
|
||||
*/
|
||||
class ArgumentReceiver;
|
||||
struct Arguments;
|
||||
|
||||
template<typename SIG>
|
||||
class TypedArgumentReceiver;
|
||||
template<typename TUP>
|
||||
struct TypedArguments;
|
||||
|
||||
|
||||
class ArgumentReceiver
|
||||
struct Arguments
|
||||
{
|
||||
public:
|
||||
virtual ~ArgumentReceiver() {}
|
||||
virtual ~Arguments() {}
|
||||
|
||||
template<typename TUP>
|
||||
void
|
||||
bindArg (TUP const& args)
|
||||
TUP const&
|
||||
get ()
|
||||
{
|
||||
typedef typename bind_arg::_Type<TUP>::Sig Sig;
|
||||
typedef TypedArgumentReceiver<Sig> Receiver;
|
||||
|
||||
Receiver* dest = dynamic_cast<Receiver*> (this);
|
||||
TypedArguments<TUP>* dest = dynamic_cast<TypedArguments<TUP>*> (this);
|
||||
if (!dest)
|
||||
throw lumiera::error::Invalid("Wrong type or number of arguments");
|
||||
|
||||
dest->bindArg(args);
|
||||
return dest->args_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename SIG>
|
||||
class TypedArgumentReceiver
|
||||
: public ArgumentReceiver
|
||||
template<typename TUP>
|
||||
struct TypedArguments
|
||||
: Arguments
|
||||
{
|
||||
typedef typename bind_arg::_Type<SIG>::Args ArgTypes;
|
||||
TUP const& args_;
|
||||
|
||||
virtual void bindArg (lumiera::typelist::Tuple<ArgTypes> const&) =0;
|
||||
TypedArguments (TUP const& a)
|
||||
: args_(a)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -137,14 +137,24 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
virtual CmdFunctor bindArguments (CmdFunctor const& func)
|
||||
/** assign a new parameter tuple to this */
|
||||
virtual void bindArguments (Arguments& args)
|
||||
{
|
||||
if (!arguments_->isValid())
|
||||
bindArg(args.get<ArgTuple>());
|
||||
else
|
||||
arguments_->bindArguments(args);
|
||||
}
|
||||
|
||||
|
||||
virtual CmdFunctor closeArguments (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_->bindArguments(func);
|
||||
return arguments_->closeArguments(func);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -186,7 +196,7 @@ namespace control {
|
|||
/** store a new argument tuple within this ArgumentHolder,
|
||||
* discarding and previously stored arguments */
|
||||
void
|
||||
bindArg (ArgTuple argTup)
|
||||
bindArg (ArgTuple const& argTup)
|
||||
{
|
||||
arguments_.template create<ArgHolder> (argTup);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "lib/meta/tuple.hpp"
|
||||
#include "lib/format.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "proc/control/argument-tuple-accept.hpp" ////TODO better factor out struct TypedArguments
|
||||
|
||||
//#include <tr1/memory>
|
||||
#include <tr1/functional>
|
||||
|
|
@ -194,6 +195,14 @@ namespace control {
|
|||
{ }
|
||||
|
||||
|
||||
/** assign a new parameter tuple to this */
|
||||
void
|
||||
bindArguments (Arguments& args)
|
||||
{
|
||||
params_ = args.get<ArgTuple>();
|
||||
}
|
||||
|
||||
|
||||
/** Core operation: use the embedded argument tuple
|
||||
* to close a given functor over its arguments.
|
||||
* @param unboundFunctor an function object, whose
|
||||
|
|
|
|||
|
|
@ -118,10 +118,9 @@ namespace control {
|
|||
void exec (HandlingPattern const& execPattern);
|
||||
|
||||
|
||||
template<typename TYPES>
|
||||
void bindArg (Tuple<TYPES> const&)
|
||||
void setArguments (Arguments& args)
|
||||
{
|
||||
UNIMPLEMENTED ("actually bind arguments, maybe create ArgumentHolder");
|
||||
pClo_->bindArguments(args);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,16 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
/** @internal pass a new argument tuple to the
|
||||
* CommandImpl without exposing implementation.
|
||||
*/
|
||||
void
|
||||
Command::setArguments (Arguments& args)
|
||||
{
|
||||
_Handle::impl().setArguments(args);
|
||||
}
|
||||
|
||||
|
||||
CommandDef
|
||||
Command::storeDef (Symbol newCmdID)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "pre.hpp"
|
||||
#include "include/symbol.hpp"
|
||||
#include "proc/control/command-binding.hpp"
|
||||
#include "proc/control/command-mutation.hpp"
|
||||
#include "proc/control/command-mutation.hpp" /////TODO: do we need to expose this here?
|
||||
#include "proc/control/command-closure.hpp"
|
||||
#include "proc/control/handling-pattern.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
|
@ -140,7 +140,7 @@ namespace control {
|
|||
|
||||
|
||||
private:
|
||||
|
||||
void setArguments (Arguments&);
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
|
@ -154,9 +154,10 @@ namespace control {
|
|||
|
||||
template<typename TYPES>
|
||||
inline Command&
|
||||
Command::bindArg (Tuple<TYPES> const&)
|
||||
Command::bindArg (Tuple<TYPES> const& tuple)
|
||||
{
|
||||
UNIMPLEMENTED("delegate argument binding to command-impl");
|
||||
TypedArguments<Tuple<TYPES> > args(tuple);
|
||||
this->setArguments (args);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue