Nexus/CoreService: consider handling of bus connections.

Now I've realised that there are two degrees of connectedness.
It is very much possible to have a "free standing" BusTerm, which
only allows to send uplink messages. In fact, this is how CoreService
is implemented, and probably it should also the way how to connect
the GuiNotification service...
This commit is contained in:
Fischlurch 2017-01-20 01:54:49 +01:00
parent cb31b145c3
commit 06a61773fa
6 changed files with 205 additions and 85 deletions

View file

@ -34,14 +34,23 @@
** which it will be wired. Moreover, each BusTerm bears a distinct
** [identity](\ref ::endpointID_), which is used as _implicit subject_
** for emanating messages, or as explicit destination for routing.
** The whole [UI-Bus](\ref BusController) is built to perform within the
** The whole [UI-Bus](\ref ui-bus.hpp) is built to perform within the
** UI event thread and thus is _not threadsafe_. For that reason,
** the automatic detachment built into each BusTerm's dtor is
** sufficient to ensure sane connectivity.
**
** @todo as of 11/2015 this is complete WIP-WIP-WIP
** @note BusTerm *disconnects itself automatically* on destruction.
** However, it is *not attached automatically*. It _does require_
** a reference to the bus on construction, which by default places
** the BusTerm instance into a _semi connected_ state: the BusTerm
** is able to send messages to the bus, but the Nexus (hub) does
** not know the BusTerm by ID and thus is not able to direct
** messages towards this BusTerm. Contrast this to a Tangible,
** which is constructed in a way to ensure it is always has a
** bidirectional communication link to the Nexus.
**
** @see [BusTerm_test]
** @see Tangible
**
*/
@ -51,8 +60,6 @@
#include "lib/error.hpp"
//#include "lib/symbol.hpp"
//#include "lib/util.hpp"
#include "lib/idi/entry-id.hpp"
#include "lib/diff/gen-node.hpp"
@ -69,8 +76,6 @@ namespace ctrl{
class MutationMessage;
// using lib::HashVal;
// using util::isnil;
using lib::idi::EntryID;
using lib::diff::GenNode;
using std::string;
@ -127,7 +132,10 @@ namespace ctrl{
/** may be moved, but not copied,
* due to the embedded identity */
BusTerm(BusTerm&&) = default;
BusTerm(BusTerm&&) = default;
BusTerm(BusTerm const&) = delete;
BusTerm& operator= (BusTerm const&) = delete;
protected:
/**
@ -150,7 +158,7 @@ namespace ctrl{
};
/** record state mark from this subject */
inline void

View file

@ -39,6 +39,37 @@
** both CoreService and Nexus are mutually interdependent from an operational
** perspective, since they exchange messages in both directions.
**
** ## Bus connection and topology
** The CoreService plays a central role within the UI, since it represents
** _»the application core«_ from the UI layer's viewpoint. But it is not
** the bus manager or central router, a role fulfilled by ctrl::Nexus,
** the central UI-Bus hub. Every node which has been added into the
** routing table in Nexus, can be addressed as a _first class citizen,_
** that is, we're able to direct messages towards such an element, knowing
** only it's ID. But there is a twist: all connections to the Bus are made
** from [bus terminals](ctrl::BusTerm), and each _node_, i.e. each
** [tangible model element](model::Tangible) has a BusTerm member and
** thus inherits the ability to talk to the bus. But only when _actively_
** connected to the bus, a full link and entry in the routing table is
** established. The constructor of model::Tangible indeed makes such
** a connection right away, while any "free standing" BusTerm just
** knows how to talk to the Bus _upstream,_ without establishing
** a full link to receive also _downstream_ messages.
**
** And _the fine point to note is_ that CoreService just incorporates
** a free standing BusTerm, without registering it with the Nexus.
** Doing so would be pointless, since CoreService in fact is not a
** regular Tangible, rather it fulfils a very special purpose within
** the UI. Most of the UI-Bus messages would not make much sense when
** directed towards the CoreService. Rather, CoreService _acts as upstream_
** for the Nexus, and thus gains the ability to respond to those few special
** messages, which can not be handled in a generic way on the Nexus:
** - *act* handles command invocation within the Session core, and
** is treated by [forwarding](command-handler.hpp) it over the
** SessionCommand facade to the [Proc-Dispatcher](proc-dispatcher.hpp)
** - *note* observes and captures presentation state note messages, which
** are to be handled by a central presentation state manager (TODO 1/17).
**
** @see AbstractTangible_test
** @see BusTerm_test
**
@ -80,15 +111,6 @@ namespace ctrl{
Nexus uiBusBackbone_;
NotificationService activateNotificationService_;
/**
* This service establishes some hard wired connections to the UI-Bus.
* Because baseclass BusTerm automatically disconnects at destruction,
* the member NotificationService and this object (CoreService) are
* still connected to the nexus, when the sanity check in our dtor runs.
* But all other UI elements outside of the scope of this should already
* be disconnected at that point...
*/
enum { NUMBER_OF_CONNECTED_DIRECT_MEMBERS = 2 };//!< NUMBER_OF_CONNECTED_DIRECT_MEMBERS
virtual void
act (GenNode const& command) override
@ -114,13 +136,6 @@ namespace ctrl{
{
INFO (gui, "UI-Backbone operative.");
}
~CoreService()
{
if (uiBusBackbone_.size() > NUMBER_OF_CONNECTED_DIRECT_MEMBERS)
ERROR (gui, "Some UI components are still connected to the backbone.");
}
};

View file

@ -182,6 +182,12 @@ namespace ctrl{
Nexus (BusTerm& uplink_to_CoreService, ID identity =lib::idi::EntryID<Nexus>())
: BusTerm(identity, uplink_to_CoreService)
{ }
~Nexus()
{
if (0 < size())
ERROR (gui, "Some UI components are still connected to the backbone.");
}
};

View file

@ -173,7 +173,7 @@ namespace model {
Tangible(ID identity, ctrl::BusTerm& nexus)
: uiBus_(nexus.attach(identity, *this))
: uiBus_{nexus.attach(identity, *this)}
{ }
public:

View file

@ -1721,6 +1721,12 @@ This is an very important external Interface, because it links together all thre
</pre>
</div>
<div title="CoreService" creator="Ichthyostega" modifier="Ichthyostega" created="201701200045" modified="201701200052" tags="def spec GuiIntegration" changecount="2">
<pre>''special service connected to the UI-Bus to handle all messages touching core concerns''
Especially this service handles the {{{act}}} messages to deal with commands [[operating on the Session|CommandHandling]]. And it deals with &quot;uplink&quot; {{{note}}} messages to record ongoing PresentationState changes. For all the other UI-Element nodes connected to the bus, CoreService is just assumed to be there, yet it is not known by ID, nor can it be addressed directly, like regular ~UI-Elements can.
On an operational level, CoreService additionally serves as lifecycle manager for the whole UI backbone, insofar it maintains the central bus hub, the Nexus. CoreService is instantiated (as a PImpl) when the UI subsystem starts up, and it is destroyed when leaving the UI main loop. At this point, the automatic registration and deregistration mechanism for bus terminals and ~UI-Elements must have cleared all connections in the central routing table (within Nexus).</pre>
</div>
<div title="CurrentSession" modifier="Ichthyostega" created="200709272057" modified="200709272058" tags="decision design">
<pre>The question is where to put all the state-like information [[associated with the current session|SessionOverview]]. Because this is certainly &quot;global&quot;, but may depend on the session or need to be configured differently when loading another session. At the moment (9/07) Ichthyo considers the following solution:
* represent all configuration as [[Asset]]s
@ -9026,7 +9032,7 @@ For now, as of 6/10, we use specialised QueryResolver instances explicitly and d
&amp;rarr; QueryRegistration
</pre>
</div>
<div title="UI-Bus" creator="Ichthyostega" modifier="Ichthyostega" created="201501061115" modified="201610011941" tags="GuiPattern Concepts def design draft" changecount="17">
<div title="UI-Bus" creator="Ichthyostega" modifier="Ichthyostega" created="201501061115" modified="201701200043" tags="GuiPattern Concepts def design draft" changecount="20">
<pre>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.
@ -9036,6 +9042,16 @@ The ~MVC-Pattern as such is fine, and probably the best we know for construction
This way, we separate between immediate local control of UI state and the more global, generic [[interaction control|InteractionControl]] and [[command binding|GuiCommandBinding]].
And we arrive at a backbone like structure, which can be wired, programmed and reasoned about while abstracting from the local concerns and the state management related to the UI toolkit set in use. Any element //of more than local relevance// -- be it a controller or be it a widget, representing some entity from the model -- will be attached to the UI-Bus by virtue of a ''bus terminal'', establishing a bi-directional connection. This enables any UI element to invoke commands and persist presentation state (by sending //&quot;state mark&quot; mesages//), and in turn this allows the session and engine core to &quot;cast&quot; state updates towards the UI, without precisely knowing where and how to reach the relevant presentation entities.
!!!topology
The UI-Bus has a simple star shaped topology without hierarchical nesting and forwarding. It is not necessarily connected this way, since protocol and contracts do not assume any topology explicitly -- and the topology may be subject to change without further notice. We'll only assume there is a central hub somewhere in the bus, which maintains a routing table. Actually this hub represents the centre of the star and is known as ''Nexus''. Whenever an UI element connects to the bus, a routing entry is added, which allows the element to be directly invoked to receive messages. For that reason, every element connected this way must be at a fixed memory location.
!!!degree of connectedness
A connection point to the UI-Bus is called a ''Bus Terminal'' and implemented by class {{{BusTerm}}}. In fact, this class is the foundation of the ~UI-Bus network, with the Nexus being a specialisation. The //contract// involved with this connection requires the connected entity to respond to several messages, which effectively also means that this connected entity is a tangible UI-Element ({{{gui::model::Tangible}}} implements the necessary functions). But this pertains only to fully bidirectional bus connections, where the connected entity can receive messages addressed by it's ID. Beyond that, it is very much possible to operate a &quot;free standing&quot; bus terminal, which allows just to send &quot;uplink&quot; messages into the bus, without the need to add this terminal itself to the central routing table.
!!!core services
As far as the UI is concerned, »the application core« appears just as a node somehow connected to the bus. In fact there is a special backbone entity known as CoreService to fulfil that role. Even more, this service manages the lifecycle of the UI-Bus as a whole, insofar it incorporates the Nexus as a member, and is responsible for exposing the external interfaces of the GUI. And the CoreService is responsible for actually handling the {{{act}}} and {{{note}}} messages at one central location.
!Bus interactions
The UI-Bus has a star shaped topology, with a central &quot;bus master&quot; 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

View file

@ -128,6 +128,40 @@
<node CREATED="1481338408983" ID="ID_516483369" MODIFIED="1481338438364" TEXT="k&#xf6;nnte sp&#xe4;ter sogar eine Exception sein">
<icon BUILTIN="help"/>
</node>
<node CREATED="1484871442777" ID="ID_492545805" MODIFIED="1484871538161">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
CoreService hat <i>keine volle</i>&#160;Bus-Connection
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...das hab ich mir jetzt explizit so &#252;berlegt und es ist sinnvoll.
</p>
<p>
Nur ein Tangible kann eine volle Bus-Connection haben, und das hei&#223;t,
</p>
<p>
es kann downlink-Nachrichten bekommen. Dagegen hat CoreService lediglich ein &quot;freistehendes&quot;
</p>
<p>
BusTerm, das damit Nachrichten an den Nexus schicken kann.
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1481320699056" ID="ID_728332859" MODIFIED="1481338454729" TEXT="wo kommen die CoreServices hin">
@ -187,7 +221,8 @@
<icon BUILTIN="idea"/>
</node>
<node CREATED="1484793113472" ID="ID_221612387" MODIFIED="1484793120867" TEXT="Lebenszyklus nochmal pr&#xfc;fen">
<node CREATED="1484797307376" ID="ID_842106541" MODIFIED="1484797309705" TEXT="Abfolge">
<node CREATED="1484797307376" ID="ID_842106541" MODIFIED="1484871289966" TEXT="Abfolge">
<icon BUILTIN="info"/>
<node CREATED="1484797311008" ID="ID_424744338" MODIFIED="1484797318947" TEXT="GuiFacade::start"/>
<node CREATED="1484797337516" ID="ID_750979034" MODIFIED="1484797361213" TEXT="erzeugt unique_ptr&lt;GuiRunner&gt;"/>
<node CREATED="1484797370352" ID="ID_622906815" MODIFIED="1484797377059" TEXT="dieser hat GuiHandle als member">
@ -209,14 +244,63 @@
<node CREATED="1484797557383" ID="ID_637078214" MODIFIED="1484797568569" TEXT="Gtk-Kit::run()"/>
</node>
<node CREATED="1484797573701" ID="ID_162958920" MODIFIED="1484797576384" TEXT="UiBus">
<node CREATED="1484797576972" ID="ID_1159570219" MODIFIED="1484797584063" TEXT="erzeugt CoreService"/>
<node CREATED="1484797576972" ID="ID_1159570219" MODIFIED="1484797584063" TEXT="erzeugt CoreService">
<node CREATED="1484871312594" ID="ID_1351400025" MODIFIED="1484871320837" TEXT="erbt zwar von BusTerm"/>
<node CREATED="1484871321473" ID="ID_112216780" MODIFIED="1484871392585" TEXT="hat aber keine connection">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
gemeint ist: keine volle bidirektionale Connection,
</p>
<p>
denn CoreService ist kein Tangible. Das macht Sinn so, habe dar&#252;ber nachgedacht.
</p>
<p>
</p>
<p>
Anmerkung: ein &quot;frestehendes&quot; BusTerm ist valide und zugelassen, es hat halt nur eine uplink-Connection.
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1484871556194" ID="ID_1978811406" MODIFIED="1484871610834" TEXT="macht Sinn so">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
nur ein Tangible kann downlink-Nachrichten sinnvoll empfangen;
</p>
<p>
es mu&#223; dazu auch jede Menge Methoden implementieren.
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node CREATED="1484797584483" ID="ID_290592673" MODIFIED="1484797619642" TEXT="dieser hat Member ">
<node CREATED="1484797623574" ID="ID_277189073" MODIFIED="1484797625783" TEXT="Nexus"/>
<node CREATED="1484797620495" ID="ID_1793464076" MODIFIED="1484797620495" TEXT="GuiNotificationService"/>
</node>
</node>
</node>
<node CREATED="1484797253856" ID="ID_226245696" MODIFIED="1484797260091" TEXT="GUI start sauber"/>
<node COLOR="#338800" CREATED="1484797253856" ID="ID_226245696" MODIFIED="1484871281624" TEXT="GUI start sauber">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1484871163902" ID="ID_274722396" MODIFIED="1484871283455" TEXT="closeGuiModule (PImpl) hat Lock">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1484871188635" ID="ID_1922412139" MODIFIED="1484871285111" TEXT="Storage/Lebenzyklus des Term-Funktors (jetzt) OK">
<arrowlink COLOR="#a9b4c1" DESTINATION="ID_375871642" ENDARROW="Default" ENDINCLINATION="-164;-16;" ID="Arrow_ID_896120556" STARTARROW="None" STARTINCLINATION="345;-16;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node CREATED="1481502251450" HGAP="96" ID="ID_1125529151" MODIFIED="1484797644569" TEXT="m&#xf6;glicher Race" VSHIFT="16">
@ -257,10 +341,23 @@
<icon BUILTIN="help"/>
<node CREATED="1484797872109" ID="ID_1877007933" MODIFIED="1484797877960" TEXT="Controller ist Tangible"/>
<node CREATED="1484797878364" ID="ID_93289471" MODIFIED="1484797887414" TEXT="hat damit automatisch BusTerm"/>
<node CREATED="1484799525344" ID="ID_640788614" MODIFIED="1484799536484" TEXT="mu&#xdf; sauber vom Nexus disconnecten">
<node CREATED="1484799604429" ID="ID_1141687282" MODIFIED="1484799616681" TEXT="Design-Problem: sinnvolles Diff">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1484799538686" ID="ID_1136883698" MODIFIED="1484799594552" TEXT="tut es nicht">
<icon BUILTIN="flag-pink"/>
<node CREATED="1484799625306" ID="ID_443020211" MODIFIED="1484799632496" TEXT="aus den Fingern saugen">
<icon BUILTIN="help"/>
</node>
<node CREATED="1484799634233" ID="ID_1600517820" MODIFIED="1484799642178" TEXT="nur implementation-reuse">
<icon BUILTIN="help"/>
</node>
<node CREATED="1484799675388" HGAP="29" ID="ID_228932182" MODIFIED="1484799693431" TEXT="Idee: Attribute?" VSHIFT="18">
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node CREATED="1484799525344" ID="ID_640788614" MODIFIED="1484871642690" TEXT="mu&#xdf; sauber vom Nexus disconnecten">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1484799538686" ID="ID_1136883698" MODIFIED="1484866524904" TEXT="tut es nicht">
<icon BUILTIN="pencil"/>
</node>
<node CREATED="1484799551220" ID="ID_496503271" MODIFIED="1484799585260" TEXT="Fehlermeldung + Segfault">
<richcontent TYPE="NOTE"><html>
@ -275,8 +372,8 @@
Speicherzugriffsfehler
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1484800480472" ID="ID_1441013524" MODIFIED="1484800529641" TEXT="Sanity-Check in CoreService anpassen">
<richcontent TYPE="NOTE"><html>
<head>
@ -295,38 +392,12 @@
</li>
</ul>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1484800531361" ID="ID_1483426067" MODIFIED="1484800543445" TEXT="Segfault bleibt aufzukl&#xe4;ren">
<icon BUILTIN="pencil"/>
<node CREATED="1484801095326" ID="ID_1423080714" MODIFIED="1484801173709" TEXT="beobachte re-entranten dtor-Aufruf">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
das scheint einen virtuellen dtor aufzurufen, der den dtor von NotificationService aktiviert
</p>
<p>
?
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1484801174579" ID="ID_1403729721" MODIFIED="1484801189578" TEXT="wirklich? oder ist das der Member-dtor">
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="help"/>
</node>
<node CREATED="1484801103716" ID="ID_111329243" MODIFIED="1484801112319" TEXT="Instancehandle -&gt; Interfaceproxy"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1484802736906" ID="ID_635595401" MODIFIED="1484802744322" TEXT="AUA">
<icon BUILTIN="flag-pink"/>
<node CREATED="1484802745625" ID="ID_375871642" MODIFIED="1484802749686" TEXT="Heisenbug">
<node CREATED="1484802745625" FOLDED="true" ID="ID_375871642" MODIFIED="1484871220212" TEXT="Heisenbug">
<linktarget COLOR="#a9b4c1" DESTINATION="ID_375871642" ENDARROW="Default" ENDINCLINATION="-164;-16;" ID="Arrow_ID_896120556" SOURCE="ID_1922412139" STARTARROW="None" STARTINCLINATION="345;-16;"/>
<icon BUILTIN="smily_bad"/>
</node>
<node CREATED="1484802752728" ID="ID_634426848" MODIFIED="1484802766354" TEXT="passiert beim Aufruf des TerminationHandle"/>
<node CREATED="1484802766966" ID="ID_370736554" MODIFIED="1484802805848">
<richcontent TYPE="NODE"><html>
@ -347,19 +418,21 @@
Und noch schlimmer: im Debugger gibts keinen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
</node>
<node COLOR="#c80e33" CREATED="1484862058589" ID="ID_1640490030" MODIFIED="1484862079387" TEXT="Locking">
<icon BUILTIN="help"/>
<node CREATED="1484865203945" ID="ID_1990023724" MODIFIED="1484865221554" TEXT="Locking in der GuiFacade ist korrekt"/>
<node COLOR="#338800" CREATED="1484865203945" ID="ID_1990023724" MODIFIED="1484866438758" TEXT="Locking in der GuiFacade ist korrekt">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1484865231878" ID="ID_1054093321" MODIFIED="1484865240952" TEXT="im Gui-Thread kein Locking notwendig"/>
<node CREATED="1484865243724" ID="ID_617730067" MODIFIED="1484865273473" TEXT="HA! das Lambda vom Threadstart">
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1484865278999" ID="ID_1656236909" MODIFIED="1484865283979" TEXT="aufgekl&#xe4;rt">
<node COLOR="#338800" CREATED="1484865278999" ID="ID_1656236909" MODIFIED="1484865631538" TEXT="aufgekl&#xe4;rt">
<icon BUILTIN="button_ok"/>
<node CREATED="1484865298093" ID="ID_1797078596" MODIFIED="1484865314802">
<richcontent TYPE="NODE"><html>
<head>
@ -370,8 +443,7 @@
die <i>Closure</i>&#160;eines Lambdas h&#228;ngt am Kontext
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1484865316147" ID="ID_687373412" MODIFIED="1484865348826" TEXT="wenn ich den Thread mit Lambda starte..."/>
<node CREATED="1484865349366" ID="ID_652410738" MODIFIED="1484865350930" TEXT="betrifft das den term-Functor"/>
@ -403,9 +475,7 @@
terminiert und dann tats&#228;chlich den Fuktor aufrufen m&#246;chte
</p>
</body>
</html>
</richcontent>
</node>
</html></richcontent>
</node>
</node>
</node>
@ -419,26 +489,31 @@
Debug: nur <b>ein</b>&#160;Element connected
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="bell"/>
<node CREATED="1484800781408" ID="ID_183164357" MODIFIED="1484800786931" TEXT="n&#xe4;mlich der NotificationService"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1484800787590" ID="ID_1262993877" MODIFIED="1484800791287" TEXT="AUA!">
<icon BUILTIN="flag-pink"/>
<node CREATED="1484801095326" ID="ID_1423080714" MODIFIED="1484801173709" TEXT="beobachte re-entranten dtor-Aufruf">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
das scheint einen virtuellen dtor aufzurufen, der den dtor von NotificationService aktiviert
</p>
<p>
?
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
</node>
<node CREATED="1484799604429" ID="ID_1141687282" MODIFIED="1484799616681" TEXT="Design-Problem: sinnvolles Diff">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1484799625306" ID="ID_443020211" MODIFIED="1484799632496" TEXT="aus den Fingern saugen">
<node CREATED="1484801174579" ID="ID_1403729721" MODIFIED="1484801189578" TEXT="wirklich? oder ist das der Member-dtor">
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="help"/>
</node>
<node CREATED="1484799634233" ID="ID_1600517820" MODIFIED="1484799642178" TEXT="nur implementation-reuse">
<icon BUILTIN="help"/>
</node>
<node CREATED="1484799675388" HGAP="29" ID="ID_228932182" MODIFIED="1484799693431" TEXT="Idee: Attribute?" VSHIFT="18">
<icon BUILTIN="idea"/>
<node CREATED="1484801103716" ID="ID_111329243" MODIFIED="1484801112319" TEXT="Instancehandle -&gt; Interfaceproxy"/>
</node>
</node>
</node>