Commands: code up implementation of CommandInstanceManager
interesting new twist: we do not even need to decorate with a running number, since we'll get away with an anonymous command instance, thanks to Command being a smart-handle
This commit is contained in:
parent
ce71ae1ae4
commit
97e42f75ee
6 changed files with 123 additions and 20 deletions
|
|
@ -58,6 +58,7 @@
|
|||
//#include "proc/common.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
|
@ -79,6 +80,7 @@ namespace control {
|
|||
: boost::noncopyable
|
||||
{
|
||||
CommandDispatch& dispatcher_;
|
||||
std::unordered_map<Symbol,Command> table_;
|
||||
|
||||
public:
|
||||
CommandInstanceManager (CommandDispatch&);
|
||||
|
|
|
|||
|
|
@ -144,7 +144,9 @@ namespace control {
|
|||
|
||||
|
||||
/** register a command (Frontend) under the given ID.
|
||||
* Any previously existing registration is detached from the index
|
||||
* @throw error::Logic when a registration already exists,
|
||||
* either under this ID or for the same concrete implementation
|
||||
* record but with a different ID.
|
||||
*/
|
||||
void
|
||||
track (Symbol cmdID, Command const& commandHandle)
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@
|
|||
#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 "lib/symbol.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
|
@ -53,9 +53,8 @@ using std::move;
|
|||
using lib::Symbol;
|
||||
using lumiera::LifecycleHook;
|
||||
using lumiera::ON_GLOBAL_INIT;
|
||||
//using std::string;
|
||||
//using util::cStr;
|
||||
//using util::_Fmt;
|
||||
using std::string;
|
||||
using util::_Fmt;
|
||||
|
||||
|
||||
namespace proc {
|
||||
|
|
@ -157,26 +156,51 @@ namespace control {
|
|||
|
||||
CommandInstanceManager::CommandInstanceManager (CommandDispatch& dispatcher)
|
||||
: dispatcher_{dispatcher}
|
||||
, table_{2 * Command::definition_count()}
|
||||
{ }
|
||||
|
||||
|
||||
/* more to come here...*/
|
||||
/** @todo more to come here...*/
|
||||
Symbol
|
||||
CommandInstanceManager::newInstance (Symbol prototypeID, string invocationID)
|
||||
{
|
||||
UNIMPLEMENTED ("CommandInstanceManager::newInstance");
|
||||
Symbol instanceID{lib::internedString (string{prototypeID}+"."+invocationID)};
|
||||
Command& instance = table_[instanceID];
|
||||
if (not instance)
|
||||
{ // create new clone from the prototype
|
||||
table_[instanceID] = move (Command::get(prototypeID).newInstance());
|
||||
ENSURE (instance, "cloning of command prototype failed");
|
||||
}
|
||||
return instanceID;
|
||||
}
|
||||
|
||||
|
||||
/** */
|
||||
void
|
||||
CommandInstanceManager::dispatch (Symbol instanceID)
|
||||
{
|
||||
UNIMPLEMENTED ("CommandInstanceManager::dispatch");
|
||||
Command& instance = table_[instanceID];
|
||||
if (not instance)
|
||||
throw error::Logic (_Fmt{"attempt to dispatch command instance '%s' "
|
||||
"without creating a new instance from prototype beforehand"}
|
||||
% instanceID
|
||||
, LUMIERA_ERROR_INVALID_COMMAND);
|
||||
if (not instance.canExec())
|
||||
throw error::State (_Fmt{"attempt to dispatch command instance '%s' "
|
||||
"without binding all arguments properly beforehand"}
|
||||
% instanceID
|
||||
, LUMIERA_ERROR_UNBOUND_ARGUMENTS);
|
||||
|
||||
REQUIRE (instance and instance.canExec());
|
||||
dispatcher_.enqueue(move (instance));
|
||||
ENSURE (not instance);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CommandInstanceManager::contains (Symbol instanceID) const
|
||||
{
|
||||
UNIMPLEMENTED ("CommandInstanceManager::contains");
|
||||
return util::contains (table_, instanceID);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ namespace control {
|
|||
|
||||
/** @internal make a command ready for use. Typically to be invoked
|
||||
* through CommandDef during the definition stage, but also used
|
||||
* for activating clone instances.
|
||||
* for activating (anonymous) clone instances.
|
||||
* @param cmdID new ID for creating a separate command registration when provided
|
||||
* @throw error::Logic when \c this is already activated. */
|
||||
void
|
||||
|
|
@ -191,7 +191,7 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
/** create independent clone copy of this command */
|
||||
/** create independent (anonymous) clone copy of this command */
|
||||
Command
|
||||
Command::newInstance () const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2604,7 +2604,7 @@ This contrastive approach attempts to keep knowledge and definition clustered in
|
|||
&rarr; CommandSetup
|
||||
</pre>
|
||||
</div>
|
||||
<div title="GuiCommandCycle" creator="Ichthyostega" modifier="Ichthyostega" created="201703031817" modified="201703180039" tags="design operational GuiPattern GuiIntegration draft discuss img" changecount="53">
|
||||
<div title="GuiCommandCycle" creator="Ichthyostega" modifier="Ichthyostega" created="201703031817" modified="201703312352" tags="design operational GuiPattern GuiIntegration draft discuss img" changecount="54">
|
||||
<pre>//the process of issuing a session command from the UI//
|
||||
Within the Lumiera UI, we distinguish between core concerns and the //local mechanics of the UI.// The latter is addressed in the usual way, based on a variation of the [[MVC-Pattern|http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller]]. The UI toolkit set, here the GTK, affords ample ways to express actions and reactions within this framework, where widgets in the presentation view are wired with the corresponding controllers vice versa (GTK terms these connections as //"signals"//, we rely on {{{libSigC++}}} for implementation).
|
||||
A naive approach would extend these mature mechanisms to also cover the actual functionality of the application. This compelling solution allows quickly to get "something tangible" up and running, yet -- on the long run -- inevitably leads to core concerns being tangled into the presentation layer, which in turn becomes hard to maintain and loaded with "code behind". Since we are here "for the long run", we immediately draw the distinction between UI mechanics and core concerns. The latter are, by decree and axiom, required to perform without even an UI layer running. This decision gives rise to the challenge how to form and integrate the invocation of ''core commands'' into the presentation layer.
|
||||
|
|
@ -2643,10 +2643,11 @@ from these use cases, we can derive the //crucial activities for command handlin
|
|||
* when a command is completely parametrised, it can be invoked. The managing {{{InteractionStateManager}}} knows about this
|
||||
* on invocation, the ID of the instance is sent via UI-Bus to the {{{CmdInstanceManager}}}
|
||||
* which in turn removes the instance handle from its registration table and hands it over into the ProcDispatcher
|
||||
* only the {{{CmdInstanceManager}}} need to know about this actual command instance; there is no global registration
|
||||
[<img[Access to Session Commands from UI|uml/Command-ui-access.png]]
|
||||
An immediate consequence is that command instances will be formed //per instance// of InteractionStateManager. Each distinct kind of control system has its own instances, which are kept around, until they are ready for invocation. Each invocation "burns" an instance -- on next access, a new instance ID will be allocated, and the next command invocation cycle starts...
|
||||
|
||||
Command instances are like prototypes -- thus each additional level of differentiation will create a clone copy and decorate the basic command ID. Yet this extension process is delegated into multiple stages. Already when a specific InvocationTrail is established, the bare command prototype is specialised, and additionally combined with specific context access rules and maybe even a accessor to retrieve some argument value. The {{{CmdInstanceManager}}} internally maintains and tracks a prepared command instance, supplying a distinct instance number to keep concurrently existing instances apart; instances might be around for an extended period, because commands are enqueued with the ProcDispatcher.
|
||||
Command instances are like prototypes -- thus each additional level of differentiation will create a clone copy and decorate the basic command ID. Yet this extension process is delegated into multiple stages. Already when a specific InvocationTrail is established, the bare command prototype is specialised, and additionally combined with specific context access rules and maybe even a accessor to retrieve some argument value. The {{{CmdInstanceManager}}} internally maintains and tracks a prepared anonymous command instance within a local registration table. The //smart-handle//-nature of command instance is enough to keep concurrently existing instances apart; instances might be around for an extended period, because commands are enqueued with the ProcDispatcher.
|
||||
|
||||
''command definition'':
|
||||
&rarr; Command scripts are defined in translation units in {{{proc/cmd}}}
|
||||
|
|
|
|||
|
|
@ -11706,6 +11706,14 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1491005426763" ID="ID_1575553505" MODIFIED="1491005475262" TEXT="zu klären: duplikate Instanz">
|
||||
<arrowlink COLOR="#ca978d" DESTINATION="ID_1805144008" ENDARROW="Default" ENDINCLINATION="594;0;" ID="Arrow_ID_191915626" STARTARROW="None" STARTINCLINATION="594;0;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1491005509448" ID="ID_709599195" MODIFIED="1491005512147" TEXT="Fehler?"/>
|
||||
<node CREATED="1491005514015" ID="ID_66770459" MODIFIED="1491005526578" TEXT="bestehende Instanz überbügeln">
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1489191252503" ID="ID_1621107057" MODIFIED="1489191308469" TEXT="#1090 Command access for UI-Elements">
|
||||
<arrowlink COLOR="#758ba4" DESTINATION="ID_827179653" ENDARROW="Default" ENDINCLINATION="173;83;" ID="Arrow_ID_57938013" STARTARROW="None" STARTINCLINATION="550;-93;"/>
|
||||
|
|
@ -11788,6 +11796,23 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1491005020528" ID="ID_1665806173" MODIFIED="1491005024747" TEXT="zu klären">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1491005025928" ID="ID_1805144008" MODIFIED="1491005470990" STYLE="fork" TEXT="duplikate Instanzen">
|
||||
<linktarget COLOR="#ca978d" DESTINATION="ID_1805144008" ENDARROW="Default" ENDINCLINATION="594;0;" ID="Arrow_ID_191915626" SOURCE="ID_1575553505" STARTARROW="None" STARTINCLINATION="594;0;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1491005039414" ID="ID_378645276" MODIFIED="1491005470990" TEXT="mehrfach newInstance() mit gleicher ID"/>
|
||||
<node CREATED="1491005054595" ID="ID_1987692266" MODIFIED="1491005470990" TEXT="zwei Möglichkeiten">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1491005058931" ID="ID_1108733153" MODIFIED="1491005470990" TEXT="mit neuem Klon überschreiben"/>
|
||||
<node CREATED="1491005066706" ID="ID_1990482123" MODIFIED="1491005470990" TEXT="Fehler auslösen"/>
|
||||
</node>
|
||||
<node CREATED="1491005071634" ID="ID_178338289" MODIFIED="1491005470990" TEXT="zur Klärung">
|
||||
<icon BUILTIN="bell"/>
|
||||
<node CREATED="1491005078409" ID="ID_1515823316" MODIFIED="1491005470990" TEXT="...muß ich wissen, wie newInstance verwendet wird"/>
|
||||
<node CREATED="1491005491226" ID="ID_1986906306" MODIFIED="1491005499069" TEXT="und das hängt von InvocationTrail ab"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#252298" CREATED="1489546623162" HGAP="-24" ID="ID_1622574347" MODIFIED="1489778039083" TEXT="was wird gebraucht" VSHIFT="21">
|
||||
<linktarget COLOR="#352c7d" DESTINATION="ID_1622574347" ENDARROW="Default" ENDINCLINATION="39;-3322;" ID="Arrow_ID_1512127407" SOURCE="ID_1401258681" STARTARROW="None" STARTINCLINATION="2000;0;"/>
|
||||
|
|
@ -11812,10 +11837,16 @@
|
|||
<node CREATED="1489715248861" ID="ID_999876408" MODIFIED="1489715252392" TEXT="brauche">
|
||||
<node CREATED="1489715276057" ID="ID_878658276" MODIFIED="1489715279093" TEXT="Basis-ID"/>
|
||||
<node CREATED="1489715297406" ID="ID_601143379" MODIFIED="1489715305201" TEXT="dekoriert durch Invocation-Trail"/>
|
||||
<node CREATED="1489715320435" ID="ID_1521007439" MODIFIED="1489715325174" TEXT="dekoriert durch laufende Nr"/>
|
||||
<node CREATED="1489715320435" ID="ID_1521007439" MODIFIED="1491003112168" TEXT="dekoriert durch laufende Nr">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node CREATED="1489715326210" ID="ID_1820734132" MODIFIED="1489715331310" TEXT="guten Hash von diesen"/>
|
||||
<node CREATED="1489715461992" ID="ID_115322523" MODIFIED="1489715479858" TEXT=""leere" Basis-ID ohne lfdNr"/>
|
||||
<node CREATED="1489715591582" ID="ID_256884690" MODIFIED="1489715597393" TEXT="inkrement der lfdNr"/>
|
||||
<node CREATED="1489715461992" ID="ID_115322523" MODIFIED="1491003142993" TEXT=""leere" Basis-ID ohne lfdNr">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node CREATED="1489715591582" ID="ID_256884690" MODIFIED="1491003145193" TEXT="inkrement der lfdNr">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1489716825126" HGAP="38" ID="ID_969368347" MODIFIED="1489717783561" TEXT="Ansätze" VSHIFT="-1">
|
||||
<node CREATED="1489716845980" ID="ID_816994670" MODIFIED="1489718875217" TEXT="Command-ID-Token">
|
||||
|
|
@ -11847,6 +11878,25 @@
|
|||
<node CREATED="1489717807872" ID="ID_1209104496" MODIFIED="1489717818826" TEXT="wir bauen ohnehin den Command-Cycle fest ein"/>
|
||||
<node CREATED="1489717844003" ID="ID_97055123" MODIFIED="1489717853605" TEXT="letztgenannte Lösung ist auf den Punkt"/>
|
||||
<node CREATED="1489717927279" ID="ID_845301501" MODIFIED="1489717959263" TEXT="Command-ID erfüllt keine regulierende Funktion"/>
|
||||
<node CREATED="1491003369611" ID="ID_854080320" MODIFIED="1491003437055" TEXT="Instanz-Management funktioniert anonym">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...weil es zu jedem InvocationPath
|
||||
</p>
|
||||
<p>
|
||||
zu jeder Zeit nur eine "offene" Instanz gibt.
|
||||
</p>
|
||||
<p>
|
||||
Also genügt es, einen anonymen Klon dieser Instanz zu halten
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1489717960331" ID="ID_1849715968" MODIFIED="1489717991603" TEXT="viel wichtiger sind die Aktivierungs-Regeln"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -11923,7 +11973,12 @@
|
|||
</node>
|
||||
<node CREATED="1489781392694" ID="ID_1312397991" MODIFIED="1489781396114" TEXT="Festlegungen">
|
||||
<node CREATED="1489781404925" ID="ID_1918933171" MODIFIED="1489781408881" TEXT="Command-ID">
|
||||
<node CREATED="1489781409876" ID="ID_1973020417" MODIFIED="1489781419119" TEXT="Bais-ID ist ein string"/>
|
||||
<node CREATED="1489781409876" ID="ID_1973020417" MODIFIED="1491003215267" TEXT="Basis-ID ist ein Symbol"/>
|
||||
<node CREATED="1491003215783" ID="ID_1537560721" MODIFIED="1491003227609" TEXT="es wird mit einer Invocation-ID dekoriert"/>
|
||||
<node CREATED="1491003228101" ID="ID_661472357" MODIFIED="1491003254161" TEXT="wir brauchen keine laufende Nummer">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1491003237108" ID="ID_1167308664" MODIFIED="1491003252150" TEXT="Instance-Management funktioniert anonym"/>
|
||||
</node>
|
||||
<node CREATED="1489781426978" ID="ID_1543445405" MODIFIED="1490985671060" TEXT="konkrete Definition">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -12057,7 +12112,8 @@
|
|||
<node CREATED="1490985710963" ID="ID_447657694" MODIFIED="1490985717974" TEXT="keinerlei Lifecycle-Magie"/>
|
||||
<node CREATED="1490985720722" ID="ID_1386937508" MODIFIED="1490985736292" TEXT="ist nur eine Registry mit etwas Funktionalität">
|
||||
<node CREATED="1490986294710" ID="ID_558020871" MODIFIED="1490986301601" TEXT="Comand-IDs dekorieren"/>
|
||||
<node CREATED="1490986302197" ID="ID_1305641719" MODIFIED="1490986308216" TEXT="fortlaufenden Zähler verwalten">
|
||||
<node CREATED="1490986302197" ID="ID_1305641719" MODIFIED="1491004967731" TEXT="fortlaufenden Zähler verwalten">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1490986345879" ID="ID_1736956933" MODIFIED="1490986393723" TEXT="denn: Dispatch bedeutet Verzögerung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -12092,11 +12148,29 @@
|
|||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1491004971039" ID="ID_329531567" MODIFIED="1491004978482" TEXT="anonyme Instanz verwalten">
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1491004982341" ID="ID_1956457610" MODIFIED="1491005001237" TEXT="offene Frage: Duplikat überschreiben?">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node CREATED="1491005133794" ID="ID_1003096513" MODIFIED="1491005393601" TEXT="vorläufig überschreibe ich stillschweigend">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1490986309084" ID="ID_1432845924" MODIFIED="1490986319583" TEXT="sicher Übergabe an Dispatch">
|
||||
<node CREATED="1490986320434" ID="ID_1807848022" MODIFIED="1490986324558" TEXT="Dispatch als Closure"/>
|
||||
<node CREATED="1490986325626" ID="ID_167499115" MODIFIED="1490986333421" TEXT="Exception-Safety!"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1491003278638" ID="ID_516679033" MODIFIED="1491003300696" TEXT="Instanz-Management">
|
||||
<node CREATED="1491003301379" ID="ID_997022970" MODIFIED="1491003305671" TEXT="funktioniert fast von selbst"/>
|
||||
<node CREATED="1491003306451" ID="ID_1812101347" MODIFIED="1491003314278" TEXT="Command == smart-Handle"/>
|
||||
<node CREATED="1491003314746" ID="ID_850841535" MODIFIED="1491003350337" TEXT="instanz kann anonym bleiben">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1491003323585" ID="ID_719524765" MODIFIED="1491003347758" TEXT="die lokale Registry hällt sie am Leben">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1490985696821" ID="ID_564026288" MODIFIED="1490985706464" TEXT="wird vom SessionCommandService betrieben"/>
|
||||
</node>
|
||||
<node CREATED="1490985748207" ID="ID_1314513556" MODIFIED="1490985751457" TEXT="Instanzbildung">
|
||||
|
|
|
|||
Loading…
Reference in a new issue