diff --git a/src/proc/control/argument-tuple-accept.hpp b/src/proc/control/argument-tuple-accept.hpp index 80cc94f9b..003a38391 100644 --- a/src/proc/control/argument-tuple-accept.hpp +++ b/src/proc/control/argument-tuple-accept.hpp @@ -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 - class TypedArgumentReceiver; + template + struct TypedArguments; - class ArgumentReceiver + struct Arguments { - public: - virtual ~ArgumentReceiver() {} + virtual ~Arguments() {} template - void - bindArg (TUP const& args) + TUP const& + get () { - typedef typename bind_arg::_Type::Sig Sig; - typedef TypedArgumentReceiver Receiver; - - Receiver* dest = dynamic_cast (this); + TypedArguments* dest = dynamic_cast*> (this); if (!dest) throw lumiera::error::Invalid("Wrong type or number of arguments"); - dest->bindArg(args); + return dest->args_; } }; - template - class TypedArgumentReceiver - : public ArgumentReceiver + template + struct TypedArguments + : Arguments { - typedef typename bind_arg::_Type::Args ArgTypes; + TUP const& args_; - virtual void bindArg (lumiera::typelist::Tuple const&) =0; + TypedArguments (TUP const& a) + : args_(a) + { } }; diff --git a/src/proc/control/command-argument-holder.hpp b/src/proc/control/command-argument-holder.hpp index 10daadaf9..bbd6a54a2 100644 --- a/src/proc/control/command-argument-holder.hpp +++ b/src/proc/control/command-argument-holder.hpp @@ -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()); + 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 (argTup); } diff --git a/src/proc/control/command-closure.hpp b/src/proc/control/command-closure.hpp index dce2c9e22..d1ce82d1d 100644 --- a/src/proc/control/command-closure.hpp +++ b/src/proc/control/command-closure.hpp @@ -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 #include @@ -194,6 +195,14 @@ namespace control { { } + /** assign a new parameter tuple to this */ + void + bindArguments (Arguments& args) + { + params_ = args.get(); + } + + /** Core operation: use the embedded argument tuple * to close a given functor over its arguments. * @param unboundFunctor an function object, whose diff --git a/src/proc/control/command-impl.hpp b/src/proc/control/command-impl.hpp index 7778d0ce7..9b2c93df6 100644 --- a/src/proc/control/command-impl.hpp +++ b/src/proc/control/command-impl.hpp @@ -118,10 +118,9 @@ namespace control { void exec (HandlingPattern const& execPattern); - template - void bindArg (Tuple const&) + void setArguments (Arguments& args) { - UNIMPLEMENTED ("actually bind arguments, maybe create ArgumentHolder"); + pClo_->bindArguments(args); } diff --git a/src/proc/control/command.cpp b/src/proc/control/command.cpp index fad9cd19d..cafeac58a 100644 --- a/src/proc/control/command.cpp +++ b/src/proc/control/command.cpp @@ -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) { diff --git a/src/proc/control/command.hpp b/src/proc/control/command.hpp index 51b7c57a9..61f19ff0f 100644 --- a/src/proc/control/command.hpp +++ b/src/proc/control/command.hpp @@ -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 inline Command& - Command::bindArg (Tuple const&) + Command::bindArg (Tuple const& tuple) { - UNIMPLEMENTED("delegate argument binding to command-impl"); + TypedArguments > args(tuple); + this->setArguments (args); return *this; }