Commands: implement the registration queue for command definitions

This commit is contained in:
Fischlurch 2017-03-18 04:40:16 +01:00
parent 29ce5b9c69
commit d044abe3c7
3 changed files with 48 additions and 7 deletions

View file

@ -39,10 +39,15 @@
#include "proc/control/command-setup.hpp"
#include "proc/control/command-instance-manager.hpp"
//#include <string>
#include <tuple>
#include <utility>
//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<Literal, DefinitionClosure>;
std::deque<CmdDefEntry> 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<void(CommandDef&)>`
* @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<void(CommandDef&)> 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();
}

View file

@ -74,6 +74,8 @@ namespace control {
class CommandDef;
using DefinitionClosure = std::function<void(CommandDef&)>;
/**
@ -100,7 +102,7 @@ namespace control {
}
/** core functionality: provide a command definition block. */
CommandSetup& operator= (std::function<void(CommandDef&)>);
CommandSetup& operator= (DefinitionClosure);
/** diagnostics / test */
static size_t pendingCnt();

View file

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