Timeline: draft the root attachment point where timelines are created by diff

This involves a fundamental decision about how to build structures in the Lumiera UI:
They shall be solely created in response to diff messages. Which leads us to
introduce a new (and quite challenging) concept: the »DiffConstituent«
This commit is contained in:
Fischlurch 2018-10-10 05:45:46 +02:00
parent 9894542bf9
commit 2adcabbef5
7 changed files with 232 additions and 16 deletions

View file

@ -41,6 +41,7 @@ namespace gui {
const Symbol ATTR_name{"name"};
const Symbol ATTR_fork{"fork"};
const Symbol ATTR_assets{"assets"};
/* ======== UI-Element protocol ======== */

View file

@ -42,6 +42,7 @@
#include "gui/ctrl/ui-state.hpp"
#include "gui/setting/asset-controller.hpp"
#include "gui/timeline/timeline-controller.hpp"
#include "include/ui-protocol.hpp"
#include "proc/mobject/session/root.hpp"
#include "proc/asset/sequence.hpp" ///////////////////////////////////////////////////////////TICKET #1096 : avoid direct inclusion to reduce compile times
#include "proc/mobject/session/fork.hpp" ///////////////////////////////////////////////////////////TICKET #1096 : avoid direct inclusion to reduce compile times
@ -61,6 +62,8 @@
using lib::idi::EntryID;
using lib::hash::LuidH;
using lib::diff::TreeMutator;
using lib::diff::collection;
using std::make_unique;
using util::toString;
@ -128,8 +131,30 @@ namespace interact {
{
buffer.create (
TreeMutator::build()
);
unimplemented ("create a sensible binding between root-controller and root-model element");
.attach (collection(timelines_)
.isApplicableIf ([&](GenNode const& spec) -> bool
{ // »Selector« : require object-like sub scope
return spec.data.isNested();
})
.matchElement ([&](GenNode const& spec, PTimelineCtrl const& elm) -> bool
{ // »Matcher« : how to know we're dealing with the right timeline object
return spec.idi == ID(elm);
})
.constructFrom ([&](GenNode const& spec) -> PTimelineCtrl
{ // »Constructor« : what to do when the diff mentions a new entity
return injectTimeline (spec);
})
.buildChildMutator ([&](PTimelineCtrl& targetTimeline, GenNode::ID const& subID, TreeMutator::Handle buff) -> bool
{ // »Mutator« : how to apply the diff recursively to a nested scope
if (ID(targetTimeline) != subID) return false;
targetTimeline->buildMutator (buff); // - delegate to child(Timeline) to build nested TreeMutator
return true;
}))
.mutateAttrib(ATTR_fork, [&](TreeMutator::Handle buff)
{ // »Attribute Mutator« : how enter an object field as nested scope
REQUIRE (assets_);
assets_->buildMutator(buff);
}));
}
@ -280,6 +305,15 @@ namespace interact {
{
return globalCtx_.windowLoc_.findActiveWindow();
}
/** @internal allocate a new TimelineWidget and attach it as child */
InteractionDirector::PTimelineCtrl
InteractionDirector::injectTimeline (GenNode const& spec)
{
unimplemented ("allocate a TimelineWidget in some TimelinePanel and attach it's controller as child entity");
}

View file

@ -80,6 +80,7 @@ namespace workspace {
}
namespace interact {
using lib::diff::GenNode;
//using std::string;
using std::unique_ptr;
@ -113,7 +114,8 @@ namespace interact {
unique_ptr<FocusTracker> tracker_;
// == Model globals ==
using Timelines = std::vector<unique_ptr<timeline::TimelineController>>;
using PTimelineCtrl = unique_ptr<timeline::TimelineController>;
using Timelines = std::vector<PTimelineCtrl>;
using Assets = unique_ptr<setting::AssetController>;
using State = unique_ptr<ctrl::UiState>;
@ -150,6 +152,7 @@ namespace interact {
private:
workspace::WorkspaceWindow& getWorkspaceWindow();
PTimelineCtrl injectTimeline (GenNode const&);
};

View file

@ -77,14 +77,14 @@ namespace setting {
: public model::Controller
{
///////TODO create UI representation for the asset subsections
/** content population and manipulation via UI-Bus */
void buildMutator (lib::diff::TreeMutator::Handle) override;
public:
AssetController (ID identity, ctrl::BusTerm& nexus);
~AssetController();
/** content population and manipulation via UI-Bus */
void buildMutator (lib::diff::TreeMutator::Handle) override;
private:
};

View file

@ -74,6 +74,7 @@ namespace gui {
extern const Symbol ATTR_name;
extern const Symbol ATTR_fork;
extern const Symbol ATTR_assets;
/* ======== UI-Element protocol ======== */

View file

@ -2082,6 +2082,10 @@ The Method of pushing frames to the Viewer widget is changed fundamentally durin
</pre>
</div>
<div title="DiffConstituent" creator="Ichthyostega" modifier="Ichthyostega" created="201810100342" tags="Model Concepts design draft" changecount="1">
<pre>//A self referential intermediary, used to collect and consolidate structural information about some element.//
This structural information can then be emanated as ''population diff'' and is thus the foundation to build a further representation of the same structure //&quot;elsewhere&quot;.// This //further representation// could be a model entity within the session's HighLevelModel, or it could be a widget tree in the UI. And, to close the circle, this other representation resulting from that diff could in turn again be a DiffConstituent.</pre>
</div>
<div title="DispatcherTables" creator="Ichthyostega" modifier="Ichthyostega" created="201305212334" tags="Player Rendering design draft" changecount="1">
<pre>The Dispatcher Tables are hosted within the [[Segmentation]] and serve as a ''strategy'' governing the play process.
For each [[calculation stream|CalcStream]] there is a concrete implementation of the [[dispatcher|FrameDispatcher]] interface, based on a specific configuration of dispatcher tables.</pre>
@ -3243,7 +3247,7 @@ More specifically, the integration is based on ''messaging''. To start with, the
----
In a preliminary attempt to establish an integration between the GUI and the lower layers, in 1/2009 we created an PlayerDummy, which &quot;pulls&quot; dummy frames from the (not yet existing) engine and displays them within an XV viewer widget. This highlighted the problems we're about to encounter and made us think about the more radically decoupled approach we followed thereafter...</pre>
</div>
<div title="GuiModel" creator="Ichthyostega" modifier="Ichthyostega" created="201410170142" modified="201808312301" tags="GuiIntegration design draft" changecount="24">
<div title="GuiModel" creator="Ichthyostega" modifier="Ichthyostega" created="201410170142" modified="201810100334" tags="GuiIntegration design draft" changecount="25">
<pre>Building a layered architecture is a challenge, since the lower layer //really// needs to be self-contained, while prepared for usage by the higher layer.
A major fraction of all desktop applications is written in a way where operational logic is built around the invocation from UI events -- what should be a shell turns into a backbone. One possible way to escape from this common anti pattern is to introduce a mediating entity, to translate between two partially incompatible demands and concerns: Sure, the &quot;tangible stuff&quot; is what matters, but you can not build any significant piece of technology if all you want is to &quot;serve&quot; the user.
@ -3258,6 +3262,11 @@ The whole Idea to have a &quot;UI model&quot; appears more questionable than eve
* {{red{as of 8/2018}}}, matters on a large scale converge towards a structure //without a classical UI model.// Seemingly we can do without...
* there is a working demonstration in {{{BusTerm_test}}}, which pushes mutation diffs against a mock UI-Element. The immediate response to receiving such a diff notification via the UI-Bus has now been coded; it incurs invoking a passed callback (functor), which performs within the originating context, but within the ~UI-Thread, and produces the actual diff //on-demand.// (&quot;pull principle&quot;)
!!!building the model structures
A fundamental decision within the Lumiera UI is to build every model-like structure as immediate response to receiving a diff message pushed up into the UI.
* either this happens when some change occured, which is directly reflected into the UI by a local diff
* or a whole subtree of elements is built up step wise in response to a ''population diff''. This is an systematic description of a complete sub-structure in current shape, and is produced as emanation from a DiffConstituent.
!synchronisation guarantees
We acknowledge that the gui model is typically used from within the GUI event dispatch thread. This is //not// the thread where any session state is mutated. Thus it is the responsibility of this proxying model within the GUI to ensure that the retrieved structure is a coherent snapshot of the session state. Especially the {{{gui::model::SessionFacade}}} ensures that there was a read barrier between the state retrieval and any preceding mutation command. Actually, this is implemented down in Proc-Layer, with the help of the ProcDispatcher.
@ -3425,7 +3434,7 @@ In accordance with the Lumiera application architecture in general, the UI is no
<pre>A specially configured LumieraPlugin, which actually contains or loads the complete code of the (GTK)GUI, and additionally is linked dynamically against the application core lib. During the [[UI startup process|GuiStart]], loading of this Plugin is triggered from {{{main()}}}. Actually this causes spawning of the GTK event thread and execution of the GTK main loop.
</pre>
</div>
<div title="GuiTimelineView" creator="Ichthyostega" modifier="Ichthyostega" created="201410160100" modified="201810071735" tags="GuiPattern design decision draft img" changecount="51">
<div title="GuiTimelineView" creator="Ichthyostega" modifier="Ichthyostega" created="201410160100" modified="201810100316" tags="GuiPattern design decision draft img" changecount="52">
<pre>Within the Lumieara GUI, the [[Timeline]] structure(s) from the HighLevelModel are arranged and presented according to the following principles and conventions.
Several timeline views may be present at the same time -- and there is not necessarily a relation between them, since »a Timeline« is the top-level concept within the [[Session]]. Obviously, there can also be several //views// based on the same »Timeline« model element, and in this latter case, these //coupled views// behave according to a linked common state. An entity »Timeline« as represented through the GUI, emerges from the combination of several model elements
* a root level [[Binding|BindingMO]] acts as framework
@ -3459,7 +3468,7 @@ This collapsed, expanded and possibly nested workspace structure is always exact
!!!lifecycle and instances
A given instance of the {{{TimelineWidget}}} is always dedicated to render the contents of //one specific timeline.// We never switch the data model while retaining the UI entities. This also means, a given instance is tied to one conversation with the core; it is created when the core tells us about this timeline with an initial population diff, and it lives until either this timeline is discarded in the core model, or the whole session is shut down.
The dockable ''timeline pannel'' holds onto the existing {{{TimelineWidget}}} instances, allowing to make one of them visible for interaction. Yet those instances are managed by the InteractionDirector, who incorporates the role of representing the [[model root|ModelRootMO]]. Aside of the timeline display, there is also an ''asset pannel''; display of and interaction with those asset views is handled by dedicated widgets, backed by the {{{AssetControler}}} -- which is also a child of and managed by the InteractionDirector, since assets are modelled as global part of the [[Session]].
The dockable ''timeline pannel'' holds onto the existing {{{TimelineWidget}}} instances, allowing to make one of them visible for interaction. Yet the timeline itself is represented by the {{{TimelineControler}}}, which lives //within this widget,// and is attached to and managed by the InteractionDirector, who incorporates the role of representing the [[model root|ModelRootMO]]. Aside of the timeline display, there is also an ''asset pannel''; display of and interaction with those asset views is handled by dedicated widgets, backed by the {{{AssetControler}}} -- which is also a child of and managed by the InteractionDirector, since assets are modelled as global part of the [[Session]].
In case the UI starts with no session present in the core, an //empty timeline placeholder// will be displayed, which provides UI for creating a new session...
@ -3471,7 +3480,7 @@ In the most general case, there can be per-track content and nested content at t
&amp;rarr; important question: how to [[organise the widgets|GuiTimelineWidgetStructure]]
</pre>
</div>
<div title="GuiTimelineWidgetStructure" creator="Ichthyostega" modifier="Ichthyostega" created="201410250002" modified="201810071821" tags="GuiPattern discuss decision impl" changecount="87">
<div title="GuiTimelineWidgetStructure" creator="Ichthyostega" modifier="Ichthyostega" created="201410250002" modified="201810100337" tags="GuiPattern discuss decision impl" changecount="89">
<pre>The Timeline is probably the most prominent place in the GUI where we need to come up with a custom UI design.
Instead of combining standard components in one of the well-known ways, here we need to come up with our own handling solution -- which also means to write one or several custom GTK widgets. Thus the question of layout and screen space division and organisation becomes a crucial design decision. The ~GTK-2 Gui, as implemented currently, did already take some steps along this route, yet this kind of decision should be cast and documented explicitly (be it after the fact).
@ -3510,6 +3519,12 @@ Here, the &quot;component&quot; relevant for such structural changes is always t
From these observations we can draw the conclusion, that we'll build a ''local structural model'', to reflect the logical relations between the parts comprising the timeline display. More precisely, these structuring components are not mere model objects, rather they are mediating entities used to guide and organise the actual view entities, which in turn are passive. They are more like a view model, while also bearing some local controller responsibilities. For this reason, we prefer to term these as ''presenters'' -- i.e. TrackPresenter and ClipPresenter. And each of these local representation components holds onto a display context, which generally links it into two different display widget stacks in the two parts of the actual timeline display. Adding a child component thus becomes a rather tricky operation, involving to link possibly two child widgets into two disjoint parent widgets, thereby forming a similar display context for the child presenter. Overall, the guiding idea is that of self similarity: on each level, we have to reproduce the same relations and collaborations as present in the parent level.
!!!building the timeline representation structure
It is a fundamental decision within the Lumiera UI that any structure as to be injected as diff by the core. We do not hold a structure or data model within some UI entity and then &quot;interpret&quot; that model into a widget structure -- rather we build the widget structure itself in response to a diff message describing the structure. Especially in the case of timelines, the receiver of those messages is the InteractionDirector, which corresponds to the model root. On being prompted to set up a timeline, it will allocate a {{{TimelineWidget}}} within a suitable timeline docking panel and then attach to the {{{TimelineController}}} embedded within the widget.
{{red{Problem 10/2018}}} how can the InteractionDirector //manage// a timeline while the timeline widget physically resides within the panel? Can we exploit a simliar structure as we did for the error log?
The diff describing and thus assembling the UI representation of a timeline is typically a ''population diff'' -- which means, it is a consolidated complete description of the whole sub-structure rooted below that timeline. Such a population diff is generated as emanation from the respective DiffConstituent.
!!!interplay with diff mutation
Applying a diff changes the structure, that is, the structure of the local model, not the structure of the display widgets. Because the latter are an entirely private concern of the UI and their structure is controlled by the model components in conjunction with the display manager. And since diff application effects the contents of the model such as to make the intended structural changes happen (indirectly), we are well advised to tie the display control and the widgets very closely to those local model elements, such as to //adjust the display automatically.//
* when a new model element is added, it has to inject something automatically into the display

View file

@ -45,7 +45,7 @@
<node CREATED="1501940632871" ID="ID_189611570" MODIFIED="1518487921039" TEXT="Dummy Proc-Command"/>
<node CREATED="1501940639479" ID="ID_1314787910" MODIFIED="1518487921039" TEXT="komplettes Ping-Pong"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1481320590214" ID="ID_635303062" MODIFIED="1538939700299" TEXT="#1042 DummySessionConnection">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1481320590214" ID="ID_635303062" MODIFIED="1539135672542" TEXT="#1042 DummySessionConnection">
<arrowlink COLOR="#f9b709" DESTINATION="ID_1343270939" ENDARROW="Default" ENDINCLINATION="-36;-73;" ID="Arrow_ID_1867016690" STARTARROW="None" STARTINCLINATION="-34;70;"/>
<arrowlink COLOR="#f9b709" DESTINATION="ID_330280074" ENDARROW="Default" ENDINCLINATION="-37;-88;" ID="Arrow_ID_779644313" STARTARROW="None" STARTINCLINATION="-34;70;"/>
<arrowlink COLOR="#f9b709" DESTINATION="ID_791449946" ENDARROW="Default" ENDINCLINATION="-842;-559;" ID="Arrow_ID_1347689482" STARTARROW="None" STARTINCLINATION="-81;124;"/>
@ -5246,6 +5246,10 @@
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1538940061190" ID="ID_1231562526" MODIFIED="1538942179606" TEXT="Timeline Panel bauen">
<arrowlink COLOR="#fec680" DESTINATION="ID_712786561" ENDARROW="Default" ENDINCLINATION="-1077;-98;" ID="Arrow_ID_433721169" STARTARROW="None" STARTINCLINATION="860;206;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1538940061190" ID="ID_1375216048" MODIFIED="1539141015314" TEXT="verankern im InteractonDirector">
<arrowlink COLOR="#fec680" DESTINATION="ID_810032444" ENDARROW="Default" ENDINCLINATION="-451;-531;" ID="Arrow_ID_1378803021" STARTARROW="None" STARTINCLINATION="335;22;"/>
<icon BUILTIN="pencil"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1538941158698" ID="ID_513093052" MODIFIED="1538941168250" TEXT="vorl&#xe4;ufiger Allokator">
<icon BUILTIN="flag-yellow"/>
</node>
@ -5256,7 +5260,7 @@
<arrowlink COLOR="#fec680" DESTINATION="ID_1992201258" ENDARROW="Default" ENDINCLINATION="-784;-81;" ID="Arrow_ID_126634995" STARTARROW="None" STARTINCLINATION="651;0;"/>
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1538940061190" ID="ID_977311190" MODIFIED="1538942745433" TEXT="Aktion re-Populate">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1538940061190" ID="ID_977311190" MODIFIED="1539140874752" TEXT="Aktion re-Populate">
<arrowlink COLOR="#fec680" DESTINATION="ID_501539344" ENDARROW="Default" ENDINCLINATION="-1280;-81;" ID="Arrow_ID_938812574" STARTARROW="None" STARTINCLINATION="335;22;"/>
<icon BUILTIN="flag-yellow"/>
</node>
@ -16475,7 +16479,62 @@
<node CREATED="1488566452538" ID="ID_1569803797" MODIFIED="1518487921075" TEXT="werden transient gebilet"/>
</node>
</node>
<node CREATED="1486763376960" ID="ID_1618020758" MODIFIED="1518487921075" TEXT="Zugang zu den Timelines"/>
<node CREATED="1486763376960" ID="ID_1618020758" MODIFIED="1518487921075" TEXT="Zugang zu den Timelines">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1480694550601" ID="ID_810032444" MODIFIED="1539140992471" TEXT="Timeline injizieren">
<linktarget COLOR="#fec680" DESTINATION="ID_810032444" ENDARROW="Default" ENDINCLINATION="-451;-531;" ID="Arrow_ID_1378803021" SOURCE="ID_1375216048" STARTARROW="None" STARTINCLINATION="335;22;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1539141031692" ID="ID_224638279" MODIFIED="1539141042494" TEXT="Aufruf aus dem TreeMutator-Binding"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1539141043842" ID="ID_1475393315" MODIFIED="1539141098932" TEXT="brauche Allocator f&#xfc;r Timelines">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1539141064760" ID="ID_807914812" MODIFIED="1539141075481" TEXT="wo Service ansiedeln">
<icon BUILTIN="help"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1539141076630" ID="ID_399959646" MODIFIED="1539141095892" TEXT="Auspr&#xe4;gung / Platzierung festlegen">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1539141115961" ID="ID_50363803" MODIFIED="1539141166595" TEXT="TimelineWidget installieren">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1539141131742" ID="ID_1557130599" MODIFIED="1539141165195" TEXT="von diesem den Controller beziehen (WLink)">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1539141189855" ID="ID_1121710933" MODIFIED="1539141214858" TEXT="Problem: wenn WLink inaktiv wird">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1539141846463" ID="ID_1385425726" MODIFIED="1539141861324" TEXT="Design-Problem">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1539141862533" ID="ID_122593910" MODIFIED="1539141927201">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
how can the InteractionDirector <i>manage</i>&#160;a timeline
</p>
<p>
&#160;while the timeline widget physically resides within the panel?
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Can we exploit a simliar structure as we did for the error log?
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="help"/>
</node>
</node>
</node>
</node>
<node CREATED="1486763385591" ID="ID_6651258" MODIFIED="1518487921076" TEXT="Zugang zum Asset-Management"/>
<node CREATED="1486763391862" ID="ID_1568245541" MODIFIED="1518487921076" TEXT="Zugang zur Konfiguration"/>
<node CREATED="1486763408780" ID="ID_520762274" MODIFIED="1518487921076" TEXT="Zugang zum persistenten Interface-State"/>
@ -19857,12 +19916,103 @@
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1531423784657" ID="ID_1434932428" MODIFIED="1531423792205" TEXT="Inhalts-Empfang wieder deaktivieren">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1480694550601" ID="ID_501539344" MODIFIED="1538942745433" TEXT="re-populate Content">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1480694550601" ID="ID_501539344" MODIFIED="1539140884766" TEXT="re-populate Content">
<linktarget COLOR="#fec680" DESTINATION="ID_501539344" ENDARROW="Default" ENDINCLINATION="-1280;-81;" ID="Arrow_ID_938812574" SOURCE="ID_977311190" STARTARROW="None" STARTINCLINATION="335;22;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1538942086509" ID="ID_1492693885" MODIFIED="1538942121013" TEXT="wenn ein UI-Element f&#xfc;r eine bestehende Entit&#xe4;t wiederaufgebaut wird">
<icon BUILTIN="info"/>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1539134153912" ID="ID_311986051" MODIFIED="1539134172715" TEXT="Grundsatzentscheidung: re-populate">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
<node CREATED="1539134197011" ID="ID_1798515652" MODIFIED="1539134282852" TEXT="m&#xf6;gliche Modelle">
<icon BUILTIN="idea"/>
<node CREATED="1539134201394" ID="ID_1071210666" MODIFIED="1539134350067" TEXT="UI-Komponente realisiert sich selbst">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<ul>
<li>
Komponente hat eine interne Struktur-Repr&#228;sentation
</li>
<li>
traversiert diese Struktur-Beschreibung
</li>
<li>
und &#252;bersetzt sie in UI-Widgets
</li>
</ul>
</body>
</html>
</richcontent>
<icon BUILTIN="button_cancel"/>
</node>
<node CREATED="1539134224759" ID="ID_766070060" MODIFIED="1539134461591" TEXT="Struktur und Realisierung gemeinsam gepusht">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<ul>
<li>
jedes Teilelement wird per Push injiziert
</li>
<li>
es wird in dem Moment sofort und ausschlie&#223;lich als Widget realisiert
</li>
</ul>
</body>
</html>
</richcontent>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1539134474262" ID="ID_1194066582" MODIFIED="1539134609868" TEXT="Begr&#xfc;ndung">
<icon BUILTIN="yes"/>
<node CREATED="1539134479525" ID="ID_11375493" MODIFIED="1539134499526" TEXT="Selbst-&quot;Verdoppelung&quot; vermeiden"/>
<node CREATED="1539134556931" ID="ID_876466376" MODIFIED="1539134566101" TEXT="Widgets selber sind &quot;die Struktur&quot;"/>
</node>
</node>
<node CREATED="1539134621210" ID="ID_1536657208" MODIFIED="1539134646091" TEXT="Konsequenz: &#xbb;populier-mich&#xab;">
<icon BUILTIN="forward"/>
<node CREATED="1539134702831" ID="ID_250983627" MODIFIED="1539134713209" TEXT="Objekt als leere H&#xfc;lle vorausgesetzt"/>
<node CREATED="1539134713846" ID="ID_1404883972" MODIFIED="1539134732663" TEXT="schickt alle Details und Inhalte als Diff"/>
<node CREATED="1539134733747" ID="ID_353086867" MODIFIED="1539135903394">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Basis: <b>DiffConstituent</b>
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<ul>
<li>
ein selbstbez&#252;glicher substanzloser Strukturkern
</li>
<li>
DiffConstituent -&gt; emanation as diff
</li>
</ul>
</body>
</html>
</richcontent>
<arrowlink COLOR="#4e31e2" DESTINATION="ID_1189184036" ENDARROW="Default" ENDINCLINATION="-767;-123;" ID="Arrow_ID_156898929" STARTARROW="None" STARTINCLINATION="-1608;-84;"/>
<node CREATED="1539138549468" ID="ID_1203696589" MODIFIED="1539138556062" TEXT="existiert &quot;irgendwo&quot;"/>
<node CREATED="1539138556651" ID="ID_1265568834" MODIFIED="1539138562997" TEXT="per Command ansprechbar"/>
<node CREATED="1539138563657" ID="ID_1727875453" MODIFIED="1539138578875" TEXT="antwortet mit Emanation in Diff-Form"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1477784813895" ID="ID_791449946" MODIFIED="1538939608849">
<richcontent TYPE="NODE"><html>
@ -34875,7 +35025,19 @@
</node>
</node>
<node CREATED="1482524498822" ID="ID_431883229" MODIFIED="1518487921096" TEXT="Datenstrom"/>
<node CREATED="1482524516371" ID="ID_396707258" MODIFIED="1518487921096" TEXT="Event-Sourcing"/>
<node CREATED="1482524516371" ID="ID_396707258" MODIFIED="1518487921096" TEXT="Event-Sourcing">
<node CREATED="1539135156755" ID="ID_1302245670" MODIFIED="1539135342488" TEXT="vermittelnder Tr&#xe4;ger">
<node CREATED="1539134733747" ID="ID_1189184036" MODIFIED="1539135710166" TEXT="DiffConstituent">
<linktarget COLOR="#4e31e2" DESTINATION="ID_1189184036" ENDARROW="Default" ENDINCLINATION="-767;-123;" ID="Arrow_ID_156898929" SOURCE="ID_353086867" STARTARROW="None" STARTINCLINATION="-1608;-84;"/>
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<node CREATED="1539134841549" ID="ID_818387120" MODIFIED="1539134847147" TEXT="neues Konzept">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1539134848420" ID="ID_4911843" MODIFIED="1539134870669" TEXT="ein selbstbez&#xfc;glicher substanzloser Strukturkern"/>
<node CREATED="1539134911707" ID="ID_847488848" MODIFIED="1539134930189" TEXT="DiffConstituent -&gt; emanation as diff"/>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1482524530842" FOLDED="true" ID="ID_606738640" MODIFIED="1538868972458" TEXT="Dependency-Injection">
<icon BUILTIN="wizard"/>
<node CREATED="1515975589922" ID="ID_367021032" MODIFIED="1538868806804" TEXT="Architektur">
@ -37790,7 +37952,7 @@
<icon BUILTIN="hourglass"/>
<node CREATED="1538939499138" ID="ID_367201519" MODIFIED="1538939505629" TEXT="open Session">
<node CREATED="1538939507425" ID="ID_389830085" MODIFIED="1538939511341" TEXT="new Session">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1477784813895" ID="ID_1478381189" MODIFIED="1538939638255">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1477784813895" ID="ID_1478381189" MODIFIED="1539135672542">
<richcontent TYPE="NODE"><html>
<head>