second shot for implementing the binding: better the other way round

This commit is contained in:
Fischlurch 2009-08-04 02:25:50 +02:00
parent b6246cbb10
commit a677e2edde
6 changed files with 56 additions and 34 deletions

View file

@ -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)
{ }
};

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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)
{

View file

@ -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;
}