From 876c1dd1fdcbc7c4721c4cb94cdbb2f24d48b5ea Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 17 Apr 2017 03:09:12 +0200 Subject: [PATCH] Commands: change implementation frame to include the command-ID while the initial design treated the commands in a strictly top-down manner, where the ID is known solely to the CommandRegistry, this change and information duplication became necessary now, since by default we now always enqueue and dispatch anonymous clone copies from the original command definition (prototype). This implementation uses the trick to tag this command-ID when a command-hanlde is activated, which is also the moment when it is tracked in the registry. --- src/proc/control/command-impl.hpp | 15 ++++-- src/proc/control/command-registry.hpp | 5 +- src/proc/control/command.cpp | 17 +++--- src/proc/control/command.hpp | 2 +- tests/45controller.tests | 18 +++---- wiki/renderengine.html | 8 ++- wiki/thinkPad.ichthyo.mm | 77 ++++++++++++++++++--------- 7 files changed, 90 insertions(+), 52 deletions(-) diff --git a/src/proc/control/command-impl.hpp b/src/proc/control/command-impl.hpp index de1a13a98..cddabe1bd 100644 --- a/src/proc/control/command-impl.hpp +++ b/src/proc/control/command-impl.hpp @@ -137,15 +137,22 @@ namespace control { CommandImpl (CommandImpl const& orig ,UndoMutation const& newUndo ,shared_ptr const& newClosure) - : do_(orig.do_) - , undo_(newUndo) - , pClo_(newClosure) - , defaultPatt_(orig.defaultPatt_) + : do_{orig.do_} + , undo_{newUndo} + , pClo_{newClosure} + , defaultPatt_{orig.defaultPatt_} + , cmdID{orig.cmdID} { } explicit operator bool() const { return isValid(); } + /** human-readable marker for diagnostics, + * will be (re)assigned when activating this CommandImpl + */ + Symbol cmdID; + + /** assist with building a clone copy of this CommandImpl. * By accepting the clone builder as a visitor and dispatching * this visitation down into the concrete closure, the builder diff --git a/src/proc/control/command-registry.hpp b/src/proc/control/command-registry.hpp index eab91db38..02dfe6fa0 100644 --- a/src/proc/control/command-registry.hpp +++ b/src/proc/control/command-registry.hpp @@ -31,7 +31,8 @@ ** to the TypedAllocationManager ** - maintaining an index to find pre-built command definitions (prototypes) ** - ** \par Services during command lifecycle + ** ## Services during command lifecycle + ** ** Each command starts out as command definition, accessed by client code through CommandDef. ** While collecting the necessary parts of such a definition, there is just an empty (pending) ** Command (smart-ptr frontend), which is not yet usable, being held within the CommandDef. @@ -167,7 +168,7 @@ namespace control { /** remove the given command registration. - * @return \c true if actually removed an entry + * @return `true` if actually removed an entry * @note existing command instances remain valid; * storage will be freed at zero use-count */ bool diff --git a/src/proc/control/command.cpp b/src/proc/control/command.cpp index 23bff8806..d99d1821f 100644 --- a/src/proc/control/command.cpp +++ b/src/proc/control/command.cpp @@ -188,7 +188,10 @@ namespace control { _Handle::activate (move (implFrame)); if (cmdID) - CommandRegistry::instance().track (cmdID, *this); + { + CommandRegistry::instance().track (cmdID, *this); + impl().cmdID = cmdID; + } TRACE (command, "%s defined OK", cStr(*this)); } @@ -386,17 +389,11 @@ namespace control { } - namespace { - const Symbol ANONYMOUS_CMD_SYMBOL("_anonymous_"); - } - Symbol - Command::getID() const + Command::getID() const noexcept { - ////////////////////////////////////////////////////////////////////TODO do we need no-throw guarantee here? - Symbol id = CommandRegistry::instance().findDefinition (*this); - return id? id - : ANONYMOUS_CMD_SYMBOL; + return isValid()? impl().cmdID + : Symbol::FAILURE; } diff --git a/src/proc/control/command.hpp b/src/proc/control/command.hpp index c888b27dc..9e9e60845 100644 --- a/src/proc/control/command.hpp +++ b/src/proc/control/command.hpp @@ -206,7 +206,7 @@ namespace control { void duplicate_detected (Symbol) const; - Symbol getID() const; + Symbol getID() const noexcept; bool isAnonymous() const; operator string() const; diff --git a/tests/45controller.tests b/tests/45controller.tests index b3121d233..22c6c2322 100644 --- a/tests/45controller.tests +++ b/tests/45controller.tests @@ -89,20 +89,20 @@ END TEST "Command argument binding" CommandBinding_test < -
+
Commands are separated in a handle (the {{{control::Command}}}-object), to be used by the client code, and an implementation level, which is managed transparently behind the stages. Client code is assumed to build a CommandDefinition at some point, and from then on to access the command ''by ID'', yielding the command handle.
 Binding of arguments, invocation and UNDO all are accessible through this frontend.
 
@@ -1542,6 +1542,12 @@ To support this handling scheme, some infrastructure is in place:
 ** a closure, implemented through an argument holder
 ** an undo state capturing mechanism, based on a capturing function provided on definition
 * performing the actual execution is delegated to a handling pattern object, accessed by name.
+;~Command-ID
+:this ID is the primary access key for stored command definitions within the registry. When a command is //activated,// the command implementation record is also tagged with that ID; this is done for diagnostic purposes, e.g. to find out what commands in the command log of the session can be undone.
+;prototypes
+:while, technically, any command record in the registry can be outfitted with arguments and executed right away, the standard usage pattern is to treat the //globally known, named entries// in this registry as prototype objects, from which the actual //instances for execution// are created by cloning. This is done to circumvent concurrency problems with argument binding.
+;named and anonymous instances
+:any command entry in the registry can be clone-copied. There are two flavours of this functionality: either, the new entry can be stored under a different name in the global registry, or alternatively just an unnamed copy can be created and returned. Since such an anonymous copy is not tracked in the registry, its lifetime is controlled solely by the ref-count of the handle returned from this {{{Command::newInstance()}}} call. Please note that the {{{CommandImpl}}} record managed by this handle still bears a copy of the original ~Command-ID, which helps with diagnostics when invoking such an instance. But the presence of this ID in the implementation record does not mean the command is known to the registry; to find out about that, use the {{{Command::isAnonymous()}}} predicate.
 
 !Definition and usage
 In addition to the technical specification regarding the command, memento and undo functors, some additional conventions are established
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index 31a7d5e30..22621e228 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -11742,7 +11742,7 @@
 
 
 
-
+
 
 
 
@@ -11817,7 +11817,7 @@
 
 
 
-
+
 
 
 
@@ -11883,8 +11883,8 @@
 
 
 
-
-
+
+
 
 
 
@@ -11955,8 +11955,8 @@
 
 
 
-
-
+
+
 
 
 
@@ -12051,11 +12051,15 @@
 
 
 
-
+
+
+
+
 
-
+
+
 
-
+
 
 
 
@@ -12192,8 +12196,8 @@
 
 
 
-
-
+
+
 
 
 
@@ -12264,7 +12268,7 @@
 
 
 
-
+
 
   
     
@@ -12463,27 +12467,50 @@
 
 
 
-
+
 
-
-
-
+
+
+
 
-
-
-
+
+
+
 
-
+
 
 
-
-
+
+
 
 
-
+
 
-
-
+
+
+
+
+
+
+
+
+
+
+  
+    
+  
+  
+    

+ allerdings, wenn man eine explizite Instanz-ID angibt, +

+

+ bleibt es bei der stringenten Fehlerbehandlung +

+ + +
+
+