diff --git a/src/proc/control/command-setup.cpp b/src/proc/control/command-setup.cpp index 284b856d8..8f697221c 100644 --- a/src/proc/control/command-setup.cpp +++ b/src/proc/control/command-setup.cpp @@ -39,10 +39,15 @@ #include "proc/control/command-setup.hpp" #include "proc/control/command-instance-manager.hpp" + //#include +#include +#include //using std::string; +using std::tuple; using std::function; +using std::move; //using util::cStr; //using util::_Fmt; @@ -52,9 +57,14 @@ namespace control { namespace error = lumiera::error; - - namespace { // implementation helper... - }//(End) implementation helper + namespace { // implementation details of command setup... + + using CmdDefEntry = std::tuple; + + std::deque pendingCmdDefinitions; + + + }//(End) implementation details @@ -64,22 +74,49 @@ namespace control { CommandSetup::~CommandSetup() { } + /** Start a command setup for defining a Proc-Layer command with the given cmdID */ CommandSetup::CommandSetup(Literal cmdID) : cmdID_(cmdID) { } + /** + * @param definitionBlock anything assignable to `function` + * @remarks this operation is intended for a very specific usage pattern, as established + * by the macro #COMMAND_DEFINITION. The purpose is to feed a given code block + * into the hidden queue for command definitions, from where it will be issued + * at the lifecycle event ON_BASIC_INIT (typically at start of application `main()`). + * On invocation, the code block is provided with an still unbound CommandDef object, + * which has been registered under the Command-ID as stored in this CommandSetup object. + * The assumption is that this _definition closure_ will care to define the command, + * state capturing and undo operations for the command definition in question. Thus, + * the result of invoking this closure will be to store a complete command prototype + * into the proc::control::CommandRegistry. + * @note this operation works by side-effect; the given argument is fed into a hidden static + * queue, but not stored within the object instance. + * @warning invoking this assignment _several times on the same CommandSetup object_ will likely + * lead to an invalid state, causing the Lumiera application to fail on start-up. The + * reason for this is the fact that CommandDef rejects duplicate command definitions. + * Moreover, please note that invoking this operation at any point _after_ the + * lifecycle event ON_BASIC_INIT will likely have no effect at all, since the + * given closure will then just sit in the static queue and never be invoked. + */ CommandSetup& - CommandSetup::operator= (function definitionBlock) + CommandSetup::operator= (DefinitionClosure definitionBlock) { - UNIMPLEMENTED ("definition queue"); + if (not definitionBlock) + throw error::Invalid ("unbound function/closure provided for CommandSetup" + , error::LUMIERA_ERROR_BOTTOM_VALUE); + + pendingCmdDefinitions.emplace_front (cmdID_, move(definitionBlock)); + return *this; } size_t CommandSetup::pendingCnt() { - UNIMPLEMENTED ("definition queue"); + return pendingCmdDefinitions.size(); } diff --git a/src/proc/control/command-setup.hpp b/src/proc/control/command-setup.hpp index 0ae934afc..00af17f83 100644 --- a/src/proc/control/command-setup.hpp +++ b/src/proc/control/command-setup.hpp @@ -74,6 +74,8 @@ namespace control { class CommandDef; + using DefinitionClosure = std::function; + /** @@ -100,7 +102,7 @@ namespace control { } /** core functionality: provide a command definition block. */ - CommandSetup& operator= (std::function); + CommandSetup& operator= (DefinitionClosure); /** diagnostics / test */ static size_t pendingCnt(); diff --git a/tests/core/proc/control/command-setup-test.cpp b/tests/core/proc/control/command-setup-test.cpp index a7538fe68..cca2d07b8 100644 --- a/tests/core/proc/control/command-setup-test.cpp +++ b/tests/core/proc/control/command-setup-test.cpp @@ -119,6 +119,8 @@ namespace test { CHECK (CommandSetup::pendingCnt() == 0); def_0 = do_something_pointless; + CHECK (CommandSetup::pendingCnt() == 1); + CommandSetup def_1{"test.CommandSetup.def_1"}; CommandSetup def_2{"test.CommandSetup.def_2"};