From 82d66cef73c39198efce309c17624a4ae45a63e8 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 17 Apr 2017 18:21:52 +0200 Subject: [PATCH] CmdAccess: discard the InvocationTrail concept after extended analysis, it turned out to be a "placeholder concept" and introduces an indirection, which can be removed altogether - simple command invocation happens at gui::model::Tangible - it is based on the command (definition) ID - instance management happens automatically and transparently - the extended case of context-bound commands will be treated later, and is entirely self-contained --- src/gui/interact/cmd-access.hpp | 11 +- src/gui/interact/invocation-trail.hpp | 132 ----- src/gui/model/tangible.cpp | 6 - src/gui/model/tangible.hpp | 19 +- src/gui/ui-bus.hpp | 8 +- .../control/session-command-function-test.cpp | 1 - wiki/renderengine.html | 28 +- wiki/thinkPad.ichthyo.mm | 469 +++++++++++------- 8 files changed, 310 insertions(+), 364 deletions(-) delete mode 100644 src/gui/interact/invocation-trail.hpp diff --git a/src/gui/interact/cmd-access.hpp b/src/gui/interact/cmd-access.hpp index 2534904ae..1ae590841 100644 --- a/src/gui/interact/cmd-access.hpp +++ b/src/gui/interact/cmd-access.hpp @@ -32,9 +32,8 @@ ** - can handle context information related to a specific _control system_ (e.g mouse, keyboard, ** hardware controller, pen) ** - might handle changing contextual state and thus decide if a command can be invoked - ** From the InteractionState instance, it is possible to retrieve a concrete InvocationTrail for - ** this specific command instance about to be invoked. This InvocationTrail is an embedded command ID - ** and can be used, to bind arguments and finally trigger the command invocation. + ** From the InteractionState instance, it is possible to retrieve a notification when a specific, + ** context-bound command becomes executable by picking up suitable parameter values from this context. ** ** @todo as of 3/2017 this is a early design draft and WIP-WIP-WIP ** @@ -49,7 +48,6 @@ #include "lib/error.hpp" -#include "gui/interact/invocation-trail.hpp" //#include "gui/ctrl/bus-term.hpp" //#include "lib/idi/entry-id.hpp" #include "lib/symbol.hpp" @@ -79,11 +77,6 @@ namespace interact { public: ~CmdAccess(); ///< @todo do we need a VTable / virtual dtor? - template - InvocationTrail bind(ARGS...args); /////////////////////TODO half baked idea, can not work this way - - InvocationTrail execute(); - /* === access front-end === */ static Symbol to (Symbol cmdID, string ctxID); diff --git a/src/gui/interact/invocation-trail.hpp b/src/gui/interact/invocation-trail.hpp deleted file mode 100644 index 4e1ff6b5c..000000000 --- a/src/gui/interact/invocation-trail.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - INVOCATION-TRAIL.hpp - a tangible element of the user interface - - Copyright (C) Lumiera.org - 2015, Hermann Vosseler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - - -/** @file invocation-trail.hpp - ** A command in preparation of being issued from the UI. - ** The actual persistent operations on the session model are defined - ** as DSL scripts acting on the session interface, and configured as a - ** _command prototype_. Typically these need to be enriched with at least - ** the actual subject to invoke this command on; many commands require - ** additional parameters, e.g. some time or colour value. These actual - ** invocation parameters need to be picked up from UI elements, and the - ** process of preparing and outfitting a generic command with these - ** actual values is tracked by an [InvocationTrail] handle. When - ** ready, finally this handle can be issued on any [BusTerm]. - ** - ** @todo as of 11/2015 this is more of a concept draft - ** - ** @see ////TODO_test usage example - ** - */ - - -#ifndef GUI_INTERACT_INVOCATION_TRAIL_H -#define GUI_INTERACT_INVOCATION_TRAIL_H - - -#include "proc/control/command.hpp" -#include "lib/diff/gen-node.hpp" -#include "lib/symbol.hpp" - -#include -#include - - - - -namespace gui { -namespace interact { - - using lib::diff::GenNode; - using lib::diff::Rec; - using lib::Symbol; - using std::string; - - - /** - * A concrete command invocation in the state of preparation and argument binding. - * This value object is a tracking handle used within the UI to deal with establishing - * a command context, maybe to present the command within a menu or to picking up - * actual invocation parameters from the context. - * @remarks typically you don't create an InvocationTrail from scratch; rather you'll - * retrieve it through \ref CmdAccess, which basically involves a specific - * ["interaction state manager"](\ref InteractionState) to conduct the invocation. - * @todo as of 4/2017 the concept and usage pattern is not entirely worked out and clear - */ - class InvocationTrail - { - string cmdID_; - - public: - /** - * Build a "command-as-prepared-for-UI". - * @param prototype an _already existing_ command prototype definition within Proc-Layer - * @remarks we deliberately link InvocationTrail to the existence of an actual prototype. - * Invocation trails will be created in advance for various scenarios to invoke commands, - * and are in fact lightweight placeholder handles -- so we do not want placeholders to - * exist somewhere in the system and IDs to be sent over the bus, without the certainty - * of a real invocation site and a matching command operation to exist somewhere else - * within the system. - * @todo do we need an alternative ctor based on plain command-ID? ///////////////////////////TICKET #1060 : create a dedicated command-ID type? - */ - InvocationTrail(proc::control::Command prototype) - : cmdID_(prototype.getID()) - { } - - GenNode triggerMsg (Rec&& cmdArgs) const - { - return GenNode(cmdID_, std::forward(cmdArgs)); - } - - - /** @todo unused as of 11/2015 - * some additional instantiation metadata - * could be passed alongside with the invocation. */ - enum { DO_IT = 42 }; - - - - string - getID() const - { - return cmdID_; - } - - bool - canExec() const - { - return proc::control::Command::canExec (Symbol(cmdID_.c_str())); - } - - operator string() const - { - return "InvocationTrail cmd(\""+cmdID_+"\""; - } - - private: - }; - - - -}} // namespace gui::interact -#endif /*GUI_INTERACT_INVOCATION_TRAIL_H*/ diff --git a/src/gui/model/tangible.cpp b/src/gui/model/tangible.cpp index 04053f770..1c5f4de5e 100644 --- a/src/gui/model/tangible.cpp +++ b/src/gui/model/tangible.cpp @@ -200,12 +200,6 @@ namespace model { { uiBus_.act (GenNode{string{cmdID}, std::forward(arguments)}); } - /** @deprecated */ - void - Tangible::invoke (Cmd const& instance, Rec&& arguments) - { - uiBus_.act (instance.triggerMsg (std::forward(arguments))); - } diff --git a/src/gui/model/tangible.hpp b/src/gui/model/tangible.hpp index 8a1b6e65f..1167954a7 100644 --- a/src/gui/model/tangible.hpp +++ b/src/gui/model/tangible.hpp @@ -132,7 +132,6 @@ #include "lib/error.hpp" #include "gui/ctrl/bus-term.hpp" -#include "gui/interact/invocation-trail.hpp" #include "lib/diff/diff-mutable.hpp" #include "lib/idi/entry-id.hpp" #include "lib/symbol.hpp" @@ -170,9 +169,8 @@ namespace model { public: using ID = ctrl::BusTerm::ID; protected: + using Rec = lib::diff::Rec; using GenNode = lib::diff::GenNode; - using Cmd = interact::InvocationTrail; - using Rec = lib::diff::Rec; ctrl::BusTerm uiBus_; @@ -193,9 +191,6 @@ namespace model { template void invoke (Symbol cmdID, ARGS&&...); void invoke (Symbol cmdID, Rec&& arguments); - template - void invoke (Cmd const& prototype, ARGS&&...); - void invoke (Cmd const& prototype, Rec&& arguments); void slotExpand(); void slotCollapse(); @@ -249,18 +244,6 @@ namespace model { ,GenNodeIL{} ,GenNodeIL {std::forward (args)...})); } // not typed, no attributes, all arguments as children - /** @deprecated */ - template - inline void - Tangible::invoke (Cmd const& prototype, ARGS&&... args) - { - using GenNodeIL = std::initializer_list; - - invoke (prototype, - Rec (Rec::TYPE_NIL_SYM, GenNodeIL{} - ,GenNodeIL {std::forward (args)...})); - } // not typed, no attributes, all arguments as children - diff --git a/src/gui/ui-bus.hpp b/src/gui/ui-bus.hpp index f17360179..e1bdea9f6 100644 --- a/src/gui/ui-bus.hpp +++ b/src/gui/ui-bus.hpp @@ -67,9 +67,11 @@ ** with the [elementary UI-Element operations](tangible.hpp). ** ** - *act*: send a [GenNode] representing the action - ** - in a first step, a command prototype is [outfitted](\ref InvocationTrail::bind()) with actual - ** parameter values. -> see [InvocationTrail] - ** - the actual command invocation is triggered by a ["bang" message](\ref InvocationTrail::bang()) + ** - the ID is either a globally registered command-ID or an explicitly + ** ["opened"](proc::control::SessionCommand::cycle(Symbol,string)) command instance ID. + ** - the payload is a Record holding the actual command arguments + ** - on reception, an _instance_ (anonymous clone copy) of the command is created, bound + ** with the arguments and handed over to the ProcDispatcher to be enqueued for execution. ** - *note*: send a [GenNode] representing the _state mark;_ ** some (abstracted) presentation state manager is expected to listen to these messages, ** possibly recording state to be restored later. The contents of the _state mark_ message diff --git a/tests/core/proc/control/session-command-function-test.cpp b/tests/core/proc/control/session-command-function-test.cpp index d2e57d4ad..bf827c303 100644 --- a/tests/core/proc/control/session-command-function-test.cpp +++ b/tests/core/proc/control/session-command-function-test.cpp @@ -82,7 +82,6 @@ extern "C" { #include "proc/control/proc-dispatcher.hpp" #include "proc/control/command-def.hpp" #include "include/session-command-facade.h" -#include "gui/interact/invocation-trail.hpp" #include "backend/thread-wrapper.hpp" #include "lib/typed-counter.hpp" #include "lib/format-string.hpp" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index d595f506d..474dedfb5 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -2633,7 +2633,7 @@ The organisation of the Lumiera UI calls for a separation between immediate low- * access and use commands from UI code &rarr; GuiCommandAccess -
+
The question //how to connect the notion of an ''interface action'' to the notion of a ''command'' issued towards the [[session model|HighLevelModel]].//
 * actual design of command invocation in the UI &rarr; GuiCommandCycle
 * study of pivotal action invocation situations &rarr; CommandInvocationAnalysis
@@ -2666,8 +2666,8 @@ This contrastive approach attempts to keep knowledge and definition clustered in
 * we need to introduce a new abstraction, termed InteractionState. This is deliberately not a single entity, rather some distinct facility in charge for one specific kind of interaction, like gestures being formed by mouse, touch or pen input.
 * from the command definition site, we need to send a combination of //rules// and parameter accessors, which together define an invocation path for one specific flavour of a command
 * the InteractionState, driven by the state changes he observes, will evaluate those rules and determine the feasibility of specific command invocation paths
-* he sends the //enablement of a command invocation trail// as a preconfigured binding to the actual //trigger sites,// which in turn allows them to install actual reaction patterns &rarr; InvocationTrail
-* if finally some button is hit, the local event binding can issue the command right away, as preconfigured in this //enablement binding,// by accessing just any UI-Bus terminal at reach within that context
+* he sends the //enablement of a command invocation trail// as a preconfigured binding to the actual //trigger sites,// which in turn allows them to react to local user interactions properly
+* if finally some button is hit, the local event binding can issue the command right away, by accessing just any UI-Bus terminal at reach within that context
 
 ''Lumera decides to take the latter approach'' -- resulting in a separation between immediate low-level UI element reactions, and anything of relevance to the workings of the application as a whole. The widget code embodies the low-level UI element reactions and as such becomes more or less meaningless beyond local concerns of layout and presentation. If you want to find out about the //behaviour of the UI,// you need to know where to look, and you need to know how to read and understand those enablement rules. Another consequence is the build-up of dedicated yet rather abstract state tracking facilities, hooking like an octopus into various widgets and controllers, which might work counter to the intentions behind the design of common UI toolkit sets.
 &rarr; GuiCommandCycle
@@ -3530,15 +3530,13 @@ From experiences with other middle scale projects, I prefer having the test code
 [img[Example: Interfaces/Namespaces of the ~Session-Subsystems|uml/fig130053.png]]
 
-
-
//A command in preparation of being issued from the UI.//
-The actual persistent operations on the session model are defined through DSL scripts acting on the session interface, and configured as a //command prototype.// Typically these need to be enriched with at least the actual subject to invoke this command on; many commands require additional parameters, e.g. some time or colour value. These actual invocation parameters need to be picked up from UI elements, and the process of preparing and outfitting a generic command with these actual values is tracked by an ''InvocationTrail handle''. When ready, finally this handle can be issued on any bus terminal, i.e. on any [[tangible interface element|UI-Element]].
-
+
+
//one specific way to prepare and issue a ~Proc-Layer-Command from the UI.//
+The actual persistent operations on the session model are defined through DSL scripts acting on the session interface, and configured as a //command prototype.// Typically these need to be enriched with at least the actual subject to invoke this command on; many commands require additional parameters, e.g. some time or colour value. These actual invocation parameters need to be picked up from UI elements, sometimes even from the context of the triggering event. When all arguments are known, finally the command -- as identified by a command-ID -- can be issued on any bus terminal, i.e. on any [[tangible interface element|UI-Element]].
 &rarr; CommandInvocationAnalysis
 
-An invocation trail represents one specific path leading to the invocation of a command. It is a value object (handle), and it serves as the interface used by the UI-Element to retrieve or supply the arguments and finally to prepare the invocation message(s). But while the invocation trail is generic to some degree, the entity to trigger the command invocation needs explicit and concrete knowledge about the circumstances involved into this invocation. Simply, because in some cases, very specific information needs to be provided as argument. For example, a widget just happens to know that the setting of a specific slider will be what becomes a likewise specific argument.
-
-{{red{deprecated 4/2017}}} -- likely to be removed from the design
+Thus an invocation trail represents one specific path leading to the invocation of a command. In the current state of the design, this is a concept; initially it was meant to exist as object, but this approach turned out to be unnecessarily complex. We can foresee that there will be the somewhat tricky situation, where a command is ''context-bound''. In those cases, we rely on the InteractionState helper, which is to track {{red{planned 4/2017}}} an enablement entry for each possible invocation trail. Basically this means that some commands need to be prepared and bound explicitly into some context (e.g. the tracks within a sequence), while enabling and parameter binding happens automatically, driven by interaction events.
+&rarr; InteractionControl
 
@@ -9333,7 +9331,7 @@ For now, as of 6/10, we use specialised QueryResolver instances explicitly and d &rarr; QueryRegistration
-
+
Abstraction used in the Backbone of Lumiera's GTK User Interface
 The UI-Bus is a ''Mediator'' -- impersonating the role of the //Model// and the //Controler// in the [[MVC-Pattern|http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller]] in common UI architecture.
 
@@ -9357,7 +9355,7 @@ As far as the UI is concerned, »the application core« appears just as a node s
 The UI-Bus has a star shaped topology, with a central "bus master" hub, which maintains a routing table. Attachment and detachment of elements can be managed automatically, since all of the UI-Bus operations perform within the UI event thread. We distinguish between up-link messages, directed towards some central service (presentation state management or command invocation) and down-link messages, directed towards individual elements. The interactions at the bus are closely interrelated with the elementary UI-Element operations.
 ;act
 :send a GenNode representing the action
-:* a command prototype corresponding to the message's ID is outfitted with actual parameter values &rarr; InvocationTrail
+:* a command prototype corresponding to the message's ID is cloned and outfitted with actual parameter values
 :* the resulting command instance is handed over to the ProcDispatcher for execution
 ;note
 :send a GenNode representing the //state mark//
@@ -9368,7 +9366,7 @@ The UI-Bus has a star shaped topology, with a central "bus master" hub
 :direct a MutationMessage towards the designated UI-Element, causing the latter to build a TreeMutator to receive the embedded [[diff-sequence|TreeDiffModel]]
 
-
+
While our UI widgets are implemented the standard way as proposed by [[GTKmm|http://www.gtkmm.org/en/documentation.html]], some key elements -- which are especially relevant for the anatomy and mechanics of the interface at a whole -- are made to conform to a common interface and behaviour protocol. {{red{WIP 11/15 work out gradually what this protocol is all about}}}. #975
 As a starting point, we know
 * there is a backbone structure known as the UI-Bus
@@ -9433,8 +9431,8 @@ While the above definitions might seem more or less obvious and reasonable, ther
 &rarr; [[Command handling (Proc-Layer)|CommandHandling]]
 
 !!!actual implementation of command invocation
-A command's {{{InvocationTrail}}} is in fact just some tag object, wrapping the command instance ID. In simple cases, this is just a command ID and the command can be triggered right away. But there are more complicated cases, where invoking the command happens as a result of user interaction, and some of the actual arguments need to be picked up from the current context by suitable match. To deal with such cases, the InteractionState helper is used to pick up this contextual data. Anyway, at the end we send a message over the UI-Bus, indicating the command instance through the GenNode ID and providing the command arguments in the payload as {{{diff::Record<GenNode>}}}.
-{{red{warning 4/2017 mostly just a concept draft}}}
+In the simple standard case, an UI event (like pressing a button) leads directly to invocation of a known command with locally known arguments. In such cases, the command can be triggered right away, using the nearest UI-Bus connection available. But there are more complicated cases, where invoking the command happens as a result of user interaction, and some of the actual arguments need to be picked up from the current context by suitable match. To deal with such cases, the InteractionState helper is used to pick up this contextual data.
+Anyway, at the end we send a message over the UI-Bus, indicating the command instance through the GenNode ID and providing the command arguments in the payload as {{{diff::Record<GenNode>}}}.
 
 !Essential update {{red{WIP 9/2016}}}
 It is clear by now (9/2016) how shape and content changes are to be represented as diff message. Moreover, we have an implementation framework to build the concrete TreeMutator, which allows to target diff messages towards a (otherwise undisclosed) opaque implementation data structure.
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index cc4732577..00d4affef 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -788,7 +788,7 @@
 
 
 
-
+
 
   
     
@@ -1457,7 +1457,6 @@
     

-
@@ -1582,12 +1581,16 @@ - + - - - + + + + + + + @@ -1603,13 +1606,17 @@ wenn in der UI ein InvocationTrail angelegt wird.

-
+ +
+ + - + + @@ -1624,7 +1631,6 @@ - @@ -1662,7 +1668,7 @@ - + @@ -2055,8 +2061,22 @@ - - + + + + + + +

+ Njet +

+

+ InvocationTrail ist tot +

+ + +
+
@@ -2319,9 +2339,10 @@ - + + @@ -2360,7 +2381,6 @@ - @@ -10118,10 +10138,10 @@ - + - + @@ -10160,35 +10180,37 @@ - + - - + + + +

- besser: InvocationTrail + Idee: context-bound

-
+ + - - +
- + - + - + @@ -10196,7 +10218,7 @@ - + @@ -10214,13 +10236,13 @@ - + - + @@ -10228,9 +10250,8 @@ - - - + + @@ -10245,13 +10266,38 @@ + + - + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -10270,107 +10316,38 @@

- Das kann ich für die ersten Tests auslassen, und stattdessen einfach + Das ist ein erweiterter / komplexerer Anwendungsfall.

- den InvocationTrail manuell im Testcode binden + Der einfache Standard-Anwendungsfall ist, direkt die Command-ID zu senden +

+

+ das reicht für die erste Integrationsrunde völlig aus

-
+ +
- - - - - - - - + + +

- die Alternative wäre, den Record mit allen Argumenten in den InvocationTrail zu packen. -

-

- Dann würden wir diesen aber weiter versenden, um Aktivierungen zuzustellen. -

-

- Das würde bedeuten, die Argumente x-fach zu kopieren (oder mich zu einem ref-counting-Mechanismus zwingen) -

-

- -

-

- Daher ist es besser, einmal, wenn die Argumente bekannt werden, diese zum Prototypen zu schicken + Instanz-Management ist automatisch

-
-
- - - - - - - - - -

- gemeint, das Model-Element (Tangible) sollte einen solchen Overload anbieten, -

-

- der unimttelbar Datenwerte nimmt und sie in einen Argument-Record packt -

- -
- -
- - - -
- - - - - - - -

- Wichtig (offen): Instanz-Management -

- -
- - - - - - - - - -

- Regel: nur was sich parallel entwickeln kann, -

-

- muß auch geforkt werden -

- -
- -
- - - - - + + + + + @@ -10412,7 +10389,7 @@ - + @@ -10609,8 +10586,8 @@ - - + + @@ -10676,10 +10653,10 @@ - + - + @@ -10847,7 +10824,7 @@ - + @@ -10874,12 +10851,13 @@ - - + + + @@ -11131,25 +11109,29 @@ - - + + - - - + + + + + - + + + + - @@ -11215,7 +11197,8 @@ - + + @@ -11249,7 +11232,7 @@ - + @@ -11311,8 +11294,8 @@ - - + + @@ -11336,7 +11319,7 @@ - + @@ -11414,13 +11397,33 @@ + + + + + + + + + + + + +

+ aufruf direkt mit Command-ID -> erzeugt automatisch eine Klon-Kopie +

+ + +
+
+
- + @@ -11468,13 +11471,32 @@ + + - - - - + + + + + + + +

+ es könnte z.B. sein, daß man vom InteractionState +

+

+ direkt einen Record<GenNode> bezieht, und bei diesem Zugriff +

+

+ automatisch die Kontext-Accessor-Ausdrücke ausgewertet werden +

+ + +
+ +
@@ -11670,8 +11692,12 @@
- + + + + + @@ -12057,7 +12083,7 @@ - + @@ -12397,13 +12423,25 @@ - + + + - - - - - + + + + + + + + + + + + + + + @@ -12467,7 +12505,7 @@ - + @@ -12484,10 +12522,26 @@ - + - + + + + + + +

+ invocationTral wurde aufgegeben. +

+

+ Insofern löst sich dieser Knoten langsam +

+ + +
+ +
@@ -12555,12 +12609,33 @@ - - - + + + + + + +

+ ...ist jetzt geklärt. +

+

+ InteractionState == Kontext +

+

+ CommandID.KontextID == Instanz +

+ + +
+ + + + + + @@ -12586,14 +12661,14 @@ - - + + - + @@ -12602,10 +12677,6 @@ - - - - @@ -12709,8 +12780,9 @@ - + + @@ -12825,8 +12897,9 @@ - + + @@ -12867,15 +12940,21 @@ - - - - + + - + + + + + + + + + - + @@ -12947,8 +13026,12 @@ - - + + + + + + @@ -13069,13 +13152,31 @@ - - - + + + + + + +

+ ...eben! +

+

+ Diese Frage hat dann dazu geführt, +

+

+ daß ich das ganze Konzept "InvocationTrail" +

+

+ wieder komplett zurückgebaut habe +

+ + +
+
- @@ -13298,7 +13399,8 @@ - + + @@ -13345,6 +13447,13 @@ + + + + + + +