From 95af930a71efca6e78a08ead08bfc5fc009063d6 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 31 Mar 2017 18:15:02 +0200 Subject: [PATCH] Commands: finish CommandSetup helper (#1088) this is a prerequisite for command instance management: We have now an (almost) complete framework for writing actual command definitions in practice, which will be registered automatically. This could be complemented (future work) by a script in the build process to regenerate proc/cmd.hpp based on the IDs of those automatic definitions. --- src/proc/control/command-setup.cpp | 29 +++++++++-------- src/proc/control/command-setup.hpp | 31 +++++++++++++------ tests/45controller.tests | 7 ++++- .../core/proc/control/command-setup-test.cpp | 12 ++----- wiki/thinkPad.ichthyo.mm | 10 ++++-- 5 files changed, 53 insertions(+), 36 deletions(-) diff --git a/src/proc/control/command-setup.cpp b/src/proc/control/command-setup.cpp index 6a1dc98f4..45af66222 100644 --- a/src/proc/control/command-setup.cpp +++ b/src/proc/control/command-setup.cpp @@ -34,21 +34,18 @@ #include "lib/error.hpp" -//#include "lib/symbol.hpp" #include "include/logging.h" #include "include/lifecycle.h" -//#include "lib/format-string.hpp" #include "proc/control/command-setup.hpp" #include "proc/control/command-instance-manager.hpp" #include "proc/control/command-def.hpp" +//#include "lib/format-string.hpp" //#include "lib/util.hpp" -//#include #include #include -//using std::string; using std::tuple; using std::get; using std::function; @@ -56,6 +53,7 @@ using std::move; using lib::Symbol; using lumiera::LifecycleHook; using lumiera::ON_GLOBAL_INIT; +//using std::string; //using util::cStr; //using util::_Fmt; @@ -64,25 +62,27 @@ namespace proc { namespace control { namespace error = lumiera::error; - - namespace { // implementation details of command setup... + namespace { // implementation details: storage for pending static command definitions... using CmdDefEntry = std::tuple; std::deque pendingCmdDefinitions; - }//(End) implementation details - /** storage for.... */ CommandSetup::~CommandSetup() { } - /** Start a command setup for defining a Proc-Layer command with the given cmdID */ + /** Start a command setup for defining a Proc-Layer command with the given cmdID + * @param cmdID the ID under with the new command will be registered + * @note after defining a static variable of type CommandSetup, + * a functor or lambda should be assigned, which then + * provides the actual setup of the CommandDef + */ CommandSetup::CommandSetup(Symbol cmdID) : cmdID_(cmdID) { } @@ -107,7 +107,7 @@ namespace control { * 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. + * given closure will then just sit in the static queue and never be invoked. */ CommandSetup& CommandSetup::operator= (DefinitionClosure definitionBlock) @@ -116,11 +116,11 @@ namespace control { throw error::Invalid ("unbound function/closure provided for CommandSetup" , error::LUMIERA_ERROR_BOTTOM_VALUE); - pendingCmdDefinitions.emplace_front (Symbol(cmdID_), move(definitionBlock)); + pendingCmdDefinitions.emplace_front (cmdID_, move(definitionBlock)); return *this; } - + size_t CommandSetup::pendingCnt() { @@ -149,6 +149,9 @@ namespace control { } + + + // emit dtors of embedded objects here.... CommandInstanceManager::~CommandInstanceManager() { } @@ -157,7 +160,7 @@ namespace control { - /** more to come here...*/ + /* more to come here...*/ diff --git a/src/proc/control/command-setup.hpp b/src/proc/control/command-setup.hpp index 65ed9336c..63c6271c8 100644 --- a/src/proc/control/command-setup.hpp +++ b/src/proc/control/command-setup.hpp @@ -31,16 +31,14 @@ ** the Session data must be performed by invoking such commands, a huge amount of individual command ** definitions need to be written eventually. ** - ** The macro COMMAND_DEFINITION(name) allows to introduce a new definition with a single line, + ** The macro COMMAND_DEFINITION(_NAME_) allows to introduce a new definition with a single line, ** followed by a code block, which actually ends up as the body of a lambda function, and receives - ** the bare CommandDef as single argument with name `cmd`. The `name` argument of the macro ends up - ** both stringified as the value of the command-ID, and as an identifier holding a new CommandSetup + ** the bare CommandDef as single argument with name `cmd`. The `_NAME_` argument of the macro ends up + ** both stringified as the value of the command-ID, and as an variable holding a new CommandSetup ** instance. It is assumed that a header with corresponding _declarations_ (the header \ref cmd.hpp) ** is included by all UI elements actually to use, handle and invoke commands towards the ** session-command-facade.h ** - ** @todo WIP-WIP 3/2017 initial draft - ** ** @see command-def.hpp ** @see command.hpp ** @see command-accessor.hpp @@ -56,7 +54,6 @@ #include "lib/error.hpp" #include "proc/control/command.hpp" #include "lib/symbol.hpp" -//#include "proc/common.hpp" #include #include @@ -68,9 +65,7 @@ namespace proc { namespace control { using std::string; -// using lib::Symbol; using lib::Symbol; - //using std::shared_ptr; class CommandDef; @@ -79,7 +74,23 @@ namespace control { /** - * @todo write type comment + * Marker and Helper for writing Proc-Layer Command definitions. + * Together with the Macro #COMMAND_DEFINITION, such definitions + * may be written statically, in DSL-style: + * - statically define a variable of type CommandSetup, + * with external linkage + * - the ctor argument is what will be used as command-ID + * - assign a functor, function or lambda to this variable, + * with the signature `void(CommandDef&)` + * - the argument passed to this functor will be the CommandDef + * about to be configured and registered. Thus, the body of the + * functor should use the member functions of CommandDef to setup + * the command's operation, state capturing and undo functions. + * - behind the scenes, a lumiera::LifecycleHook is scheduled + * to run ON_GLOBAL_INIT. When this hook is activated, all the + * lambdas assigned to all CommandSetup instances thus far will + * be invoked one by one. Which causes all those commands actually + * to be defined and configured for use with the session subsystem. */ class CommandSetup { @@ -131,7 +142,7 @@ namespace control { * and immediately be assigned by a lambda, whose body is what follows the macro invocation */ #define COMMAND_DEFINITION(_NAME_) \ - CommandSetup _NAME_ = CommandSetup{STRINGIFY(_NAME_)} = [&](CommandDef& def) + CommandSetup _NAME_ = CommandSetup{STRINGIFY(_NAME_)} = [&](CommandDef& def) diff --git a/tests/45controller.tests b/tests/45controller.tests index ee09c3692..ce01bc4ae 100644 --- a/tests/45controller.tests +++ b/tests/45controller.tests @@ -3,7 +3,7 @@ TESTING "Component Test Suite: Proc-Layer controller" ./test-suite --group=contr -TEST "CommandBasic_test" CommandBasic_test < #include #include -//using std::rand; - - namespace proc { namespace cmd { namespace test { -//using lib::time::Time; -//using lib::time::TimeVar; -//using lib::time::TimeValue; -//using lib::time::Offset; using lib::Literal; using std::string; using std::regex; @@ -188,6 +178,7 @@ namespace test { _Fmt pattern{" %d times."}; + /** @test actually issue the definitions captured as side-effect of the preceding test. */ void verify_DefinitionRegistration() @@ -213,6 +204,7 @@ namespace test { com1.bind (string{"^(\\w+)"}, string{"No $1"}); com2.bind (uint(42)); + CHECK (testString == "Ichthyostega wuz here"); com1(); CHECK (testString == "No Ichthyostega wuz here"); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index ef00d073e..cee8883b4 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -11678,7 +11678,12 @@ - + + + + + + @@ -11814,7 +11819,8 @@ - + +