DOC: decision about where to home the SessionCommandService

After some consideration, it became clear that this service implementation
is closely tied to the DispatcherLoop -- which will consequently be
responsible to run and expose this service implementation
This commit is contained in:
Fischlurch 2016-12-15 05:07:40 +01:00
parent eb73242113
commit 1ec883787a
6 changed files with 6374 additions and 31 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -0,0 +1,95 @@
/*
COMMAND-DISPATCH.hpp - Interface to enqueue and dispatch command messages
Copyright (C) Lumiera.org
2009, Hermann Vosseler <Ichthyostega@web.de>
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 command-dispatch.hpp
** Interface to abstract the DispatcherLoop's ability to handle command messages.
** //TODO
**
** @see proc-dispatcher.hpp
** @see session-command-service.hpp
** @see DispatcherLoop
**
*/
#ifndef PROC_CONTROL_COMMAND_DISPATCH_H
#define PROC_CONTROL_COMMAND_DISPATCH_H
//#include "lib/symbol.hpp"
#include "common/subsys.hpp"
#include "lib/depend.hpp"
#include "lib/sync.hpp"
#include <memory>
//#include <functional>
namespace proc {
namespace control {
// using lib::Symbol;
using std::unique_ptr;
// using std::bind;
using lumiera::Subsys;
class DispatcherLoop;
/**
* @todo Type-comment
*/
class ProcDispatcher
: public lib::Sync<>
{
unique_ptr<DispatcherLoop> runningLoop_;
bool active_{false};
public:
static lib::Depend<ProcDispatcher> instance;
bool start (Subsys::SigTerm);
bool isRunning();
void requestStop();
void activate();
void deactivate();
void clear();
/* == diagnostics == */
// size_t size() const ;
bool empty() const ;
};
////////////////TODO currently just fleshing out the API....
}} // namespace proc::control
#endif /*PROC_CONTROL_COMMAND_DISPATCH_H*/

View file

@ -32,8 +32,8 @@
#ifndef CONTROL_PROC_DISPATCHER_H
#define CONTROL_PROC_DISPATCHER_H
#ifndef PROC_CONTROL_PROC_DISPATCHER_H
#define PROC_CONTROL_PROC_DISPATCHER_H
//#include "lib/symbol.hpp"
#include "common/subsys.hpp"
@ -91,4 +91,4 @@ namespace control {
}} // namespace proc::control
#endif
#endif /*PROC_CONTROL_PROC_DISPATCHER_H*/

File diff suppressed because it is too large Load diff

View file

@ -6071,7 +6071,7 @@ The concurrent nature of the problem is what makes this simple task somewhat mor
* referrals to already known sequence points might be added later, and also from different threads ({{red{WIP 3/14}}} not sure if we need to expand on this observation -- see CalcStream &amp;hArr; Segment)
This structure looks like requiring a message passing approach: we can arrange for determining the actual dependencies and fulfillment state late, within a single consumer, which is responsible for invoking the triggers. The other clients (threads) just pass messages into a possibly lock-free messageing channel.</pre>
</div>
<div title="Session" modifier="Ichthyostega" created="200712100525" modified="201612140358" tags="def SessionLogic" changecount="3">
<div title="Session" modifier="Ichthyostega" created="200712100525" modified="201612150345" tags="def SessionLogic" changecount="4">
<pre>The Session contains all information, state and objects to be edited by the User. From a users view, the Session is synonymous to the //current Project//. It can be [[saved and loaded|SessionLifecycle]]. The individual Objects within the Session, i.e. Clips, Media, Effects, are contained in one (or several) collections within the Session, which we call [[Sequence]].
&amp;rarr; [[Session design overview|SessionOverview]]
&amp;rarr; Structure of the SessionInterface
@ -6089,7 +6089,7 @@ The Session object is a singleton &amp;mdash; actually it is a »~PImpl«-Facade
!Session lifecycle
The session lifecycle need to be distinguished from the state of the //session subsystem.// The latter is one of the major components of Lumiera, and when it is brought up, the {{{SessionCommandFacade}}} is opened and the ProcDispatcher started. On the other hand, the session as such is a data structure and pulled up on demand, by the {{{SessionManager}}}. Whenever the session is fully populated and configured, the ProcDispatcher is instructed to //actually allow dispatching of commands towards the session.// This command dispatching mechanism is the actual access point to the session for clients outside Proc-Layer; when dispatching is halted, commands can be enqueued non the less, which allows for a reactive UI.
The session lifecycle need to be distinguished from the state of the [[session subsystem|SessionSubsystem]]. The latter is one of the major components of Lumiera, and when it is brought up, the {{{SessionCommandFacade}}} is opened and the ProcDispatcher started. On the other hand, the session as such is a data structure and pulled up on demand, by the {{{SessionManager}}}. Whenever the session is fully populated and configured, the ProcDispatcher is instructed to //actually allow dispatching of commands towards the session.// This command dispatching mechanism is the actual access point to the session for clients outside Proc-Layer; when dispatching is halted, commands can be enqueued non the less, which allows for a reactive UI.
</pre>
</div>
<div title="SessionConfigurationAttachment" modifier="Ichthyostega" created="201112222242" tags="SessionLogic draft">
@ -6371,6 +6371,13 @@ And last but not least: the difficult part of this whole concept is encapsulated
{{red{WIP ... draft}}}</pre>
</div>
<div title="SessionSubsystem" creator="Ichthyostega" modifier="Ichthyostega" created="201612150347" modified="201612150359" tags="def impl SessionLogic img" changecount="8">
<pre>//A subsystem within Proc-Layer, responsible for lifecycle and access to the editing [[Session]].//
[img[Structure of the Session Subsystem|uml/Session-subsystem.png]]
!Structure
The ProcDispatcher is at the heart of the //Session Subsystem.// Because the official interface for working on the session, the {{{SessionCommand}}} façade, is expressed in terms of sending command messages to invoke predefined [[commands|CommandHandling]] to operate on the SessionInterface, the actual implementation of such a {{{SessionCommandService}}} needs a component actually to enqueue and dispatch those commands -- which is the {{{DispatcherLoop}}} within the ProcDispatcher. As usual, the ''lifecycle'' is controlled by a subsystem descriptor, which starts and stopps the whole subsystem; and this starting and stopping in turn translates into starting/stopping of the dispatcher loop. On the other hand, //activation of the dispatcher,// which means actively to dispatch commands, is controlled by the lifecycle of the session proper. The latter is just a data structure, and can be loaded / saved and rebuilt through the ''session manager''.</pre>
</div>
<div title="SideBarOptions" modifier="CehTeh" created="200706200048">
<pre>&lt;&lt;search&gt;&gt;&lt;&lt;closeAll&gt;&gt;&lt;&lt;permaview&gt;&gt;&lt;&lt;newTiddler&gt;&gt;&lt;&lt;saveChanges&gt;&gt;&lt;&lt;slider chkSliderOptionsPanel OptionsPanel &quot;options »&quot; &quot;Change TiddlyWiki advanced options&quot;&gt;&gt;</pre>
</div>

View file

@ -212,10 +212,201 @@
<node COLOR="#338800" CREATED="1481320843596" ID="ID_7225903" MODIFIED="1481509899511" TEXT="definieren">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1481320847724" ID="ID_545146501" MODIFIED="1481320850327" TEXT="wo ansiedeln">
<node CREATED="1481509901926" ID="ID_1612540786" MODIFIED="1481509907305" TEXT="in proc::control"/>
<node CREATED="1481509908527" ID="ID_1079488123" MODIFIED="1481509915351" TEXT="wo implementieren">
<node CREATED="1481767553542" ID="ID_1936508244" MODIFIED="1481768787560" TEXT="Eigenschaften">
<icon BUILTIN="info"/>
<node CREATED="1481768183970" ID="ID_1887870402" MODIFIED="1481768197029" TEXT="ist offizielle Session-Schnittstelle"/>
<node CREATED="1481768211951" ID="ID_287828489" MODIFIED="1481768529260">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
setzt <i>aktivierten</i>&#160;Dispatcher <font color="#6e080d">zwingend</font>&#160;voraus
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
es gen&#252;gt definitiv nicht, nur die Dispatcher-Komponente(Schnittstelle) erreichen zu k&#246;nnen.
</p>
<p>
Jede Operation, die &#252;ber dieses externe Interface bereitsteht, ben&#246;tigt zur Implementierung
</p>
<p>
eine aktiv laufende Dispatcher-Queue.
</p>
<p>
</p>
<p>
Daher macht es Sinn, den Interface-Lebenszyklus ganz starr an den Disspatcher zu binden
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1481768341149" ID="ID_1200042703" MODIFIED="1481768435704" TEXT="implizite Bindung an eine Session-Instanz">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...und zwar wirklich sehr implizit,
</p>
<p>
n&#228;mlich &#252;ber die Identit&#228;t (IDs) der Command-Parameter.
</p>
<p>
Das hei&#223;t, ein eingehendes Command pa&#223;t nur zu einer bestimmten Session-Instanz,
</p>
<p>
was zwar jederzeit (via statisches/internes Session-API) verifizierbar ist, jedoch nicht offensichtlich
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1481768566167" ID="ID_702026185" MODIFIED="1481768669948" TEXT="kann jederzeit asynchron geschlossen werden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
das folgt einfach aus den logischen Eigenschaften der beteiligten Komponenten,
</p>
<p>
welche eben autonom sind.
</p>
<p>
</p>
<p>
Das hei&#223;t im Klartext, alle Clients m&#252;ssen darauf vorbereitet sein, da&#223; diese Schnittstelle
</p>
<p>
<i>jederzeit</i>&#160;wegbrechen kann, was dann hei&#223;t, da&#223; irgend ein Aufruf eine Exception wirft
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1481320847724" HGAP="42" ID="ID_545146501" MODIFIED="1481768822574" TEXT="wo ansiedeln" VSHIFT="-5">
<icon BUILTIN="help"/>
<node CREATED="1481509901926" ID="ID_1612540786" MODIFIED="1481509907305" TEXT="in proc::control"/>
<node CREATED="1481767522123" ID="ID_789146708" MODIFIED="1481768757494">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
wer besitzt die
</p>
<p>
Implementierung
</p>
</body>
</html></richcontent>
<icon BUILTIN="help"/>
<node CREATED="1481767563781" ID="ID_1894117297" MODIFIED="1481768160140" TEXT="Subsystem">
<icon BUILTIN="button_cancel"/>
<node CREATED="1481767649426" ID="ID_1806364059" MODIFIED="1481767651421" TEXT="pro">
<node CREATED="1481767653785" ID="ID_65381960" MODIFIED="1481767658028" TEXT="offensichtlich"/>
<node CREATED="1481767700299" ID="ID_1163247183" MODIFIED="1481767705134" TEXT="logisch"/>
</node>
<node CREATED="1481767665231" ID="ID_141423591" MODIFIED="1481767666891" TEXT="con">
<node CREATED="1481767681797" ID="ID_1133339398" MODIFIED="1481768995389" TEXT="fragiler Lebenszyklus">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
meint: zwei gekoppelte Statusvariable
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1481767706906" ID="ID_815807707" MODIFIED="1481767710581" TEXT="bekomme dort Zustand"/>
<node CREATED="1481767720576" ID="ID_714877064" MODIFIED="1481767729611" TEXT="mu&#xdf; dort Locking verwenden"/>
<node CREATED="1481767711033" ID="ID_232055384" MODIFIED="1481767716628" TEXT="bekomme dort Fehlerbehandlung"/>
</node>
</node>
<node CREATED="1481767579130" ID="ID_191292506" MODIFIED="1481769033192" TEXT="Dispatcher">
<icon BUILTIN="help"/>
<node CREATED="1481767748180" ID="ID_549036367" MODIFIED="1481767757831" TEXT="pro">
<node CREATED="1481767761027" ID="ID_949448369" MODIFIED="1481767771781" TEXT="ist die offizielle Schnittstelle"/>
<node CREATED="1481767864069" ID="ID_47595319" MODIFIED="1481767874567" TEXT="kann Service-Impl direkt verdrahten"/>
</node>
<node CREATED="1481767758347" ID="ID_1773256683" MODIFIED="1481767759439" TEXT="con">
<node CREATED="1481767797062" ID="ID_1542908203" MODIFIED="1481768960633">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
mu&#223; alle Operationen durchschleifen
</p>
<p>
oder mu&#223; PImpl als Interface exponieren
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1481767831105" ID="ID_1351930491" MODIFIED="1481768989667" TEXT="fragiler Lebenszyklus">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
meint: zwei gekoppelte Statusvariable
</p>
</body>
</html>
</richcontent>
</node>
</node>
</node>
<node CREATED="1481767581619" ID="ID_1364443356" MODIFIED="1481769116830" TEXT="DispatcherLoop">
<linktarget COLOR="#4aff51" DESTINATION="ID_1364443356" ENDARROW="Default" ENDINCLINATION="10;30;" ID="Arrow_ID_870320696" SOURCE="ID_1152351588" STARTARROW="Default" STARTINCLINATION="-221;-88;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1481767877379" ID="ID_1139131626" MODIFIED="1481767879351" TEXT="pro">
<node CREATED="1481767893969" ID="ID_1688865092" MODIFIED="1481767911170" TEXT="kann dort dediziertes Interface nutzen"/>
<node CREATED="1481767924909" ID="ID_438801896" MODIFIED="1481767931359" TEXT="alle Operationen passieren dort"/>
<node CREATED="1481767961616" ID="ID_1097715033" MODIFIED="1481769012774" TEXT="Lebenszyklus == RAII">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<node CREATED="1481769041800" ID="ID_1026761428" MODIFIED="1481769059178" TEXT="ausschlaggebend">
<icon BUILTIN="yes"/>
</node>
<node CREATED="1481769052246" ID="ID_628010771" MODIFIED="1481769055002" TEXT="gutes Design"/>
</node>
<node CREATED="1481768131609" ID="ID_600248646" MODIFIED="1481768139171" TEXT="Locking schon da"/>
</node>
<node CREATED="1481768014089" ID="ID_1260583976" MODIFIED="1481768019020" TEXT="con">
<node CREATED="1481768019848" ID="ID_1155187340" MODIFIED="1481768032040">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Shutdown <i>tricky</i>
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1481768075481" ID="ID_795971368" MODIFIED="1481768083275" TEXT="in der Implementierung versteckt"/>
</node>
</node>
</node>
</node>
<node CREATED="1481320850779" ID="ID_1632600003" MODIFIED="1481320854143" TEXT="hochfahren">
@ -310,6 +501,12 @@
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1481510231986" ID="ID_45803267" MODIFIED="1481510243425" TEXT="TODO: dort SessionCommandService instantiieren">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1481769089234" ID="ID_1152351588" MODIFIED="1481769124140" TEXT="lebt in der DispatcherLoop">
<arrowlink COLOR="#4aff51" DESTINATION="ID_1364443356" ENDARROW="Default" ENDINCLINATION="10;30;" ID="Arrow_ID_870320696" STARTARROW="Default" STARTINCLINATION="-221;-88;"/>
</node>
<node CREATED="1481769144226" ID="ID_1609251574" MODIFIED="1481769153389" TEXT="mu&#xdf; Service-API extrahieren">
<icon BUILTIN="pencil"/>
</node>
</node>
<node CREATED="1481510244184" ID="ID_1521406724" MODIFIED="1481510260635" TEXT="kann dann in CoreService einfach &#xfc;ber die .facade() zugreifen">
<icon BUILTIN="idea"/>