From a4527c5e7568308047de7740182d48336a9d56dd Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 8 Apr 2017 15:42:51 +0200 Subject: [PATCH] Commands: Instance management implementation finished (#1089) --- src/proc/control/command-instance-manager.hpp | 40 +++++++++++-------- src/proc/control/command-setup.cpp | 17 ++++++-- wiki/thinkPad.ichthyo.mm | 36 ++++++++++------- 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/proc/control/command-instance-manager.hpp b/src/proc/control/command-instance-manager.hpp index 4212bce3a..4788cccb3 100644 --- a/src/proc/control/command-instance-manager.hpp +++ b/src/proc/control/command-instance-manager.hpp @@ -29,14 +29,19 @@ ** be formed during an extended time period, non-deterministically -- since the actual context ** depends on the user interactions. Within the UI, there is a dedicated mechanism to form such ** command invocations similar to forming sentences of a language (with subject, predication and - ** possibly some further objects). The UI manages several InteractionStateManager instances to - ** observe and pick up contextual state, finally leading to a complete parametrisation of a command. + ** possibly some further objects). The UI manages several InteractionStateManager instances to observe + ** and pick up contextual state, finally leading to a complete parametrisation of a command. ** The CommandInstanceManager is a service to support this process; it prepares command instances ** and provides dedicated instance IDs, which can be stored in the UI and later used to retrieve ** those instances for invocation. These IDs are created by decorating a base command ID, allowing ** for several competing invocations to exist at the same time. When finally a given invocation is ** about to happen, a corresponding registration handle is transfered to the ProcDispatcher, where - ** it is enqueued for execution. + ** it is enqueued for execution. + ** \par lifecycle + ** There CommandInstanceManager is maintained by the SessionCommandService, which in turn is + ** installed and removed by the implementation within ProcDispatcher. Its lifecycle is thus tied + ** to the opening / closing of the Proc-Layer interface, as dictated by the Session lifecycle. + ** When the current session is closed, all command instances "underway" will thus be discarded. ** ** @see command-setup.cpp service implementation ** @see command.hpp @@ -55,7 +60,6 @@ #include "lib/error.hpp" #include "proc/control/command-dispatch.hpp" #include "lib/symbol.hpp" -//#include "proc/common.hpp" #include #include @@ -63,18 +67,30 @@ - namespace proc { namespace control { using std::string; using lib::Symbol; - //using std::shared_ptr; - /** - * @todo write type comment + * Maintain a _current command instance_ for parametrisation. + * The definition of a *Proc-Layer command* is used like a prototype. + * For invocation, an anonymous clone copy is created from the definition + * by calling #newInstance. Several competing usages of the same command can be + * kept apart with the help of the `invocationID`, which is used to decorate the basic + * command-ID to form a distinct _`instanceID`_. After #newInstance has "opened" an instance + * this way and returned the instanceID, the actual \ref Command handle can be retrieved with + * #getInstance. It represents an _anonymous instance_ kept alive solely by the CommandInstanceManager + * (i.e. there is no registration of a command under that instanceID in the global CommandRegistry). + * When done with the parametrisation, by calling #dispatch, this anonymous instance will be handed + * over to the [Dispatcher](CommandDispatch) (installed on construction). Typically, this will in fact + * be the proc::control::ProcDispatcher, which runs in a dedicated thread ("session loop thread") and + * maintains a queue of commands to be dispatched towards the current session. Since Command is a smart + * handle, the enqueued instance will stay alive until execution and then go out of scope. But, after + * #dispatch, it is no longer accessible from the CommandInstanceManger, and while it is still waiting + * in the execution queue, the next instance for the same invocationID might already be opened. */ class CommandInstanceManager : boost::noncopyable @@ -91,17 +107,9 @@ namespace control { void dispatch (Symbol instanceID); bool contains (Symbol instanceID) const; - - private: }; - - /** */ - - - - }} // namespace proc::control #endif /*CONTROL_COMMAND_INSTANCE_MANAGER_H*/ diff --git a/src/proc/control/command-setup.cpp b/src/proc/control/command-setup.cpp index 7545c9c0b..f127a2105 100644 --- a/src/proc/control/command-setup.cpp +++ b/src/proc/control/command-setup.cpp @@ -23,10 +23,12 @@ /** @file command-setup.cpp ** Implementation details of instance management for command invocation by the GUI. + ** This translation unit combines the implementation code of several facilities + ** related to definition and instantiation of concrete command instances. ** ** @see command-setup.hpp ** @see command-instance-manager.hpp - ** @see TODO_CommandInstanceManager_test + ** @see CommandInstanceManager_test ** @see command.hpp ** @see command-registry.hpp ** @@ -155,13 +157,21 @@ namespace control { // emit dtors of embedded objects here.... CommandInstanceManager::~CommandInstanceManager() { } + /** create a CommandInstanceManager and wire it with the given CommandDispatch implementation. + * Typically, this is done in SessionCommandService. The embedded hash table for pending + * command instances is sized in relation to the number of registered global Command definitions. + */ CommandInstanceManager::CommandInstanceManager (CommandDispatch& dispatcher) : dispatcher_{dispatcher} , table_{2 * Command::definition_count()} { } - /** @todo more to come here...*/ + /** Create and thus "open" a new anonymous command instance. + * @param prototypeID the underlying Command definition to create a clone copy + * @param invocationID used to decorate the prototypeID to from an unique instanceID + * @throws error::Logic in case an instance is for this ID combination is already "open" + */ Symbol CommandInstanceManager::newInstance (Symbol prototypeID, string invocationID) { @@ -182,6 +192,7 @@ namespace control { } + /** @return handle to the currently "opened" instance with the given ID */ Command& CommandInstanceManager::getInstance (Symbol instanceID) { @@ -194,7 +205,7 @@ namespace control { } - /** */ + /** hand over the designated command instance to the dispatcher installed on construction */ void CommandInstanceManager::dispatch (Symbol instanceID) { diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index ead7a88dc..a955c727d 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -11706,9 +11706,9 @@ - + - + @@ -11716,7 +11716,8 @@ - + + @@ -11729,8 +11730,8 @@ - - + + @@ -11744,9 +11745,9 @@ - - - + + + @@ -11762,7 +11763,7 @@ - + @@ -11782,14 +11783,17 @@ - + + + + + + + + + - - - - - @@ -12324,6 +12328,8 @@ + +