Invocation: connect remaining operations for the ParamAgentBuilder

This is some quite technical and redundant code, which largely maps
the configured elements from the Builder-DSL level down into the delegate
builder functors. For the ''Param Agent Node,'' most of the structure
is already embedded deep into the `ParamWeavingPattern`, by virtue of a
tuple of parameter-functors, which are supplied to the builder-API
as a `ParamBuildSpec` (which in fact is in itself a builder and will be
used on a higher level to fill in suitable parameter-functors)

This changeset is assumed to complete the definition of a builder and
weaving pattern for a ''Param Agent Scheme'' — yet only the tests to be
elaborated next will show the extent to which this is true....
This commit is contained in:
Fischlurch 2025-01-04 01:56:37 +01:00
parent 4e0af307fa
commit 79f365df67
3 changed files with 231 additions and 17 deletions

View file

@ -300,7 +300,12 @@ namespace engine {
return move(*this);
}
/** connect the next input slot to existing lead-node given by index */
/** connect the next input slot to existing lead-node given by index
* @note the port to use on this lead is implicitly defaulted to use the same port-number
* as the port which is currently about to be built; this is a common pattern, since
* when a top-level node exposes N different flavours, its predecessors will very
* likely also be configured to produce the pre-product for these flavours.
*/
PortBuilder
connectLead (uint idx)
{
@ -341,8 +346,7 @@ namespace engine {
_Par::addLead (leadNode);
ENSURE (knownEntry < _Par::leads_.size());
weavingBuilder_.attachToLeadPort (knownEntry, port);
return move(*this);
return connectLeadPort (knownEntry, port);
}
/** use given port-index as default for all following connections */
@ -468,6 +472,7 @@ namespace engine {
/**
* Nested sub-Builder analogous to \ref PortBuilder, but for building a _»Param Agent Node«._
* This will compute additional parameters and make them temporarily accessible through the
@ -491,6 +496,72 @@ namespace engine {
uint defaultPortNr_;
public:
/** use a lead node designated by ID as delegate to invoke with the extended parameters.
* @note the port to use on this lead is implicitly defaulted to use the same port-number
* as the port which is currently about to be built; this is a common pattern, since
* when a top-level node exposes N different flavours, its predecessors will very
* likely also be configured to produce the pre-product for these flavours.
*/
ParamAgentBuilder
delegateLead (uint idx)
{
return delegateLeadPort (idx, defaultPortNr_);
}
/** use the given node as delegate, but also possibly register it as lead node */
ParamAgentBuilder
delegateLead (ProcNode& leadNode)
{
return delegateLeadPort (leadNode, defaultPortNr_);
}
/** use a lead node and specific port as delegate to invoke with extended parameters */
ParamAgentBuilder
delegateLeadPort (uint idx, uint port)
{
if (idx >= _Par::leads_.size())
throw err::Logic{_Fmt{"Builder refers to lead-node #%d, yet only %d are currently defined."}
% idx % _Par::leads_.size()
,LERR_(INDEX_BOUNDS)
};
delegatePort_ = & _Par::leads_[idx].getPort (port);
return move(*this);
}
/** use the specific port on the given node as delegate,
* while possibly also registering it as lead node. */
ParamAgentBuilder
delegateLeadPort (ProcNode& leadNode, uint port)
{
uint knownEntry{0};
for (auto& lead : lib::IndexIter{_Par::leads_})
if (util::isSameObject (leadNode, lead))
break;
else
++knownEntry;
if (knownEntry == _Par::leads_.size())
_Par::addLead (leadNode);
ENSURE (knownEntry < _Par::leads_.size());
return delegateLeadPort (knownEntry, port);
}
/**
* Install a post-processing function for the parameters.
* This functor will be invoked after the individual parameter values have been created
* by invoking their respective parameter-functor; furthermore, the parameter data block
* in current scope has already been linked with the TurnoustSystem, and thus the new
* parameters are already accessible through this front-end and can be manipulated.
* @remark the purpose is to enable coordinated adjustments on all parameters together,
* immediately before delegating to the nested node evaluation with these parameters.
*/
ParamAgentBuilder
installPostProcessor(PostProcessor pp)
{
postProcessor_ = move(pp);
}
/*********************************************************************//**
* Terminal: complete the Param-Agent wiring and return to the node level.
@ -541,6 +612,36 @@ namespace engine {
};
/** @remarks
* - this is an advanced setup for generating a complex set of _derived parameters,_
* which can then be used by all nodes within a complete subtree of the node-graph.
* - such a setup is not necessary for simple parameters based on nominal timeline time.
* - the purpose is either to avoid redundancy or to draw from additional contextual
* parameter sources (which must be accessible with the help of the processKey or
* some global service or plug-in)
* - another special scenario could be to synthesise further data based on the consolidated
* set of current automation values, possibly together with contextual data; basically
* some kind of _parameter fusion_ that can not reasonably be pre-defined in the
* High-level-Model, but must really be computed late, directly from the render process.
* - this function enters a nested port-builder, which will setup a »Param Weaving Pattern«
* - at Node invocation time, this _Weaving Pattern_ will first evaluate all parameter-funcors,
* then consolidate the generated parameters into a local data block on the stack and link
* this data block into the TurnoutSystem of this invocation; after establishing this
* quite tricky and fragile setup, the invocation will recursively delegate to another
* Node-Port, which thus performs in this extended scope and can refer to all the
* additional parameters.
* - To define the set of parameter-functors, you need to use a helper-builder based on
* \ref steam::engine::ParamBuildSpec, starting with \ref steam::engine::buildParamSpec().
* - this generates a _Param Spec,_ which especially provides _accessor functors_ for each
* of the additional parameters; you need to bind these accessor functors into the
* parameter-functors of nested nodes which want to access the additional parameters.
* - it is thus necessary first to build the _Param Spec,_ then to build the complete
* subtree of processing nodes for the actual processing (aka the _delegate tree_),
* and then finally create a _Param Agent Node_ with this builder, referring to the
* entry point into the processing tree as _delegate lead_ (see \ref ParamAgentBuilder)
* @return a nested \ref ParamAgentBuilder to set up the desired wiring and delegate
* @see NodeFeed_test::feedParamNode()
*/
template<class POL, class DAT>
template<class SPEC>
auto
@ -550,6 +651,9 @@ namespace engine {
return ParamAgentBuilder<POL,DAT,ParamBuildSpec>{spec.makeBlockBuilder()};
}
/**
* Entrance point for building actual Render Node Connectivity (Level-2)
* @note when using a custom allocator, the first follow-up builder function

View file

@ -4774,7 +4774,7 @@ Moreover, the design of coordinate matching and resolving incurs a structure sim
In the most general case the render network may be just a DAG (not just a tree). Especially, multiple exit points may lead down to the same node, and following each of this possible paths the node may be at a different depth on each. This rules out a simple counter starting from the exit level, leaving us with the possibility of either employing a rather convoluted addressing scheme or using arbitrary ID numbers.{{red{...which is what we do for now}}}
</pre>
</div>
<div title="NodeOperationProtocol" modifier="Ichthyostega" created="200806010251" modified="202412221642" tags="Rendering operational rewrite" changecount="9">
<div title="NodeOperationProtocol" modifier="Ichthyostega" created="200806010251" modified="202501040403" tags="Rendering operational rewrite" changecount="10">
<pre>{{red{⚠ In-depth rework underway as of 12/2024...}}}
The [[Render Nodes|ProcNode]] are wired to form a &quot;Directed Acyclic Graph&quot; ([[DAG|https://en.wikipedia.org/wiki/Directed_acyclic_graph]]); each node knows its predecessor(s), but not its successor(s). The RenderProcess is organized according to the ''pull principle''. This implies that there is no central entity to „activate and apply“ nodes consecutively. Rather, the ExitNode is prompted to produce results -- and since the nodes are interconnected in accordance to their required prerequisite, the calculation plan works itself out recursively. However, some prerequisite resources must be provided before any calculation can start. Notably, loading source media data is an I/O-intensive task and can not be precisely timed. The actual calculation is broken down thus into atomic chunks of work, resulting in a 2-phase invocation scheme for generating data:
;planning phase
@ -4782,6 +4782,7 @@ The [[Render Nodes|ProcNode]] are wired to form a &quot;Directed Acyclic Graph&q
:# the planning is initiated by issuing an &quot;get me output&quot; request, finally resulting in a JobTicket
:# recursively, the ticket propagates &quot;get me output&quot; requests for its prerequisites
:# after retrieving the planning information for these prerequisites, the JobPlanning pipeline generates [[job definitions|RenderJob]] for each frame and exit node involed, as well as I/O-jobs for preparing the prerequisites
:# this involves an //integration step// to arrange the order and the timings, so that the overall calculation can be carried out successfully; depending on the [[render or playback mode|NonLinearPlayback]], the planning works either backwards from a known deadline (for realtime playback), or forwards from »now+x« for a quality render to use //whatever it takes// to complete the computation
:# finally, all these jobs are handed over to the [[Scheduler]].
;pull phase
:now the actual node invocation is embedded within a job, activated through the scheduler to deliver //just in time.//
@ -4813,6 +4814,12 @@ some points to note:
&amp;rarr; more fine grained [[implementation details|RenderImplDetails]]
</pre>
</div>
<div title="NodePort" creator="Ichthyostega" modifier="Ichthyostega" created="202501040435" modified="202501040448" tags="Rendering def draft" changecount="2">
<pre>//The actual processing units within a Render Node.//
At a conceptual level, a »Node« represents a distinct processing functionality. But when it comes down to actually invoking the processing code, the operation is typically exposed in several flavours or configuration variations typically related to data format. E.g. a sound filtering node can be able to process stereo sound, but also deliver the filtering on the left or right channel in isolation. Or video image processing can be provided to work on various image resolutions, each requiring a different buffer layout. Any such processing variants are exposed as »''ports''« of the node.
This seemingly redundant configuration is based on //fundamental reasoning:// The Lumiera Render Engine performs //pre-arranged primitive operations,// which are -- to the extent this is even possible -- deprived of active decision logic. Instead of letting the invocation „work out“ some technical details like buffer-sizes on-the-fly, there is a pre-canned set of ports, each with a viable pre-configuration, so that data elements can be passed ''without any further checks'' and adaptation steps. In this respect, the [[»Render Node Network«|LowLevelModel]] is similar to //assembly code:// It proceeds into processing of low-level data right away and takes compatibility of all data types, buffer sizes and invoked functors for granted</pre>
</div>
<div title="NonLinearPlayback" modifier="Ichthyostega" created="201301132217" modified="201402161739" tags="def Player Rendering draft" changecount="3">
<pre>The calculations for rendering and playback are designed with a base case in mind: calculating a linear sequence of frames consecutive in time.
But there are several important modes of playback, which violate that assumption...
@ -6320,7 +6327,7 @@ In 2018, the middle Layer was renamed into &amp;rarr; Steam-Layer
</pre>
</div>
<div title="ProcNode" modifier="Ichthyostega" created="200706220409" modified="202412220556" tags="def spec" changecount="23">
<div title="ProcNode" modifier="Ichthyostega" created="200706220409" modified="202501040420" tags="def spec" changecount="24">
<pre>//A data processing node within the Render Engine.// Its key feature is the ability to pull a [[Frame]] of calculated data -- which may involve the invocation of //predecessor nodes// and the evaluation of [[Parameter Providers|ParamProvider]]. Together, those nodes form a »node-network«, a ''D''irected ''A''cyclic ''G''raph (DAG) known as the LowLevelModel, which is //explicit// to the degree that it can be //performed// to generate or process media. As such it is an internal structure and //compiled// by evaluating and interpreting the HighLevelModel within the [[Session]], which is the symbolic or logical representation of »the film edit« or »media product« established and created by the user.
So each node and all interconnections are //oriented.// Calculation starts from the output side and propagates to acquire the necessary inputs, thereby invoking the predecessor nodes (also known as »leads«). This recursive process leads to performing a sequence of calculations -- just to the degree necessary to deliver the desired result. And since the Render Node Network is generated by a compilation step, which is conducted repeatedly and on-demand by the part of the Lumiera application known as the [[Builder]], all node connectivity can be assumed to be adequate and fitting, each predecessor can be assumed to deliver precisely the necessary data into buffers with the correct format to be directly consumed for the current calculation step. The actual processing algorithm working on these buffers is provided by an ''external Media-processing-library'' -- the LowLevelModel can thus be seen as a pre-determined organisation and orchestration structure to enact externally provided processing functionality.
@ -6341,6 +6348,12 @@ A {{{steam::engine::ProcNode}}} is an arrangement of descriptors, connectivity a
:each Media-processing-library entails a very specific protocol how to invoke processing functionality, which becomes embedded into an individual adaptor object, including the {{{FeedManifold}}}. Typically, the actual invocation will be bound into a λ-closure, and thus the whole compound can be aggressively optimised.
;Weaving Pattern
:while each processing variant is materialised into an individual {{{Turnout}}} instance, some more generic wiring- and invocation schemes come to play when adapting the processing functions of any given Media-processing-library. The {{{WeavingPattern}}} thus defines a distinct scheme how to arrange and connect inputs and outputs and how to actually invoke the processing function. Notably, some operations allow for in-place processing, where the input-buffer is also the output-buffer and data is directly manipulated in-place, while other libraries require some elaborate layout scheme for the data buffers to work efficiently. And while Lumiera provides a set of //building blocks for weaving patterns,// each Media-processing-library actually must be adapted through a Lumiera plug-in, which entails using those building blocks or even completely different yet compatible weaving patterns as appropriate. In the end, each instantiation of such a weaving pattern becomes embedded into the render node as a {{{Turnout}}} instance and can be invoked through the {{{Port}}} interface.
&amp;rarr; [[Port / Turnout|NodePort]]
&amp;rarr; [[Turnout-System|TurnoutSystem]]
&amp;rarr; [[Weaving pattern|NodeWeavingPattern]]
&amp;rarr; [[Feed manifold|NodeFeedManifold]]
&amp;rarr; [[Parameters|RenderParamHandling]]
!Building a Render Node
!The render invocation
@ -6960,10 +6973,11 @@ Prerequisite data for the media calculations can be considered just part of that
* all it needs to know is the ''effective nominal time'' and an ''invocation instance ID''
</pre>
</div>
<div title="RenderMechanics" modifier="Ichthyostega" created="200806030230" modified="202412221601" tags="Rendering operational rewrite" changecount="6">
<pre>{{red{⚠ In-depth rework underway as of 12/2024...}}}
<div title="RenderMechanics" modifier="Ichthyostega" created="200806030230" modified="202501040430" tags="Rendering operational rewrite" changecount="9">
<pre>At architecure level, the render process is sufficiently characterized by the ''pull principle'', regarding dependencies, processing function and the [[»Render Node operation protocol«|NodeOperationProtocol]]. Yet at the level of actual operations and interactions, several intricate details become relevant, especially //how to manage the buffers// and where to provide additional storage for working data.
{{red{⚠ In-depth rework underway as of 12/2024...}}}
^^┅┅┅┅┅┅the following text is ''superseded''┅┅┅┅┅┅┅┅┅^^
While the render process, with respect to the dependencies, the builder and the processing function is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &amp;mdash; for actually get it coded we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent at the inner pixel loop within these functions. But my guess is (as of 5/08), that the overall number of data moving and copying operations //will be//&amp;nbsp; of importance.
It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent at the inner pixel loop within these functions. But my guess is (as of 5/08), that the overall number of data moving and copying operations //will be//&amp;nbsp; of importance.
{{red{WIP as of 9/11 -- need to mention the planning phase more explicitly}}}
!requirements

View file

@ -82326,6 +82326,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1735353545681" ID="ID_532492491" MODIFIED="1735353570163" TEXT="Tr&#xe4;ger-Strukturen ben&#xf6;tigt">
<node CREATED="1735353572081" ID="ID_1577179744" MODIFIED="1735416204610" TEXT="ParamBuildSpec">
<arrowlink COLOR="#bb1f2e" DESTINATION="ID_736958022" ENDARROW="Default" ENDINCLINATION="-25;-162;" ID="Arrow_ID_44922252" STARTARROW="None" STARTINCLINATION="32;153;"/>
<linktarget COLOR="#516a87" DESTINATION="ID_1577179744" ENDARROW="Default" ENDINCLINATION="-646;109;" ID="Arrow_ID_1337495041" SOURCE="ID_559444595" STARTARROW="None" STARTINCLINATION="266;-28;"/>
<node CREATED="1735353649862" ID="ID_1195888823" MODIFIED="1735353669151" TEXT="mu&#xdf; statisch (&#xbb;aus dem Nichts&#xab;) erzeugbar sein">
<node CREATED="1735353859329" ID="ID_115937743" MODIFIED="1735353870651" TEXT="also von dem default-TurnoutSystem"/>
<node CREATED="1735353871759" ID="ID_982996300" MODIFIED="1735353886009" TEXT="alternativ: als Erweiterung zu einer bestehenden Chain"/>
@ -82580,6 +82581,15 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<arrowlink COLOR="#482c86" DESTINATION="ID_329885446" ENDARROW="Default" ENDINCLINATION="-553;-36;" ID="Arrow_ID_1024921689" STARTARROW="None" STARTINCLINATION="598;1114;"/>
<linktarget COLOR="#9c47c5" DESTINATION="ID_921902157" ENDARROW="Default" ENDINCLINATION="-472;-1106;" ID="Arrow_ID_1849846169" SOURCE="ID_874513800" STARTARROW="None" STARTINCLINATION="-130;9;"/>
<icon BUILTIN="hourglass"/>
<node CREATED="1735858270404" ID="ID_559444595" MODIFIED="1735858405764" TEXT="Einstieg von einer ParamBuildSpec">
<arrowlink COLOR="#516a87" DESTINATION="ID_1577179744" ENDARROW="Default" ENDINCLINATION="-646;109;" ID="Arrow_ID_1337495041" STARTARROW="None" STARTINCLINATION="266;-28;"/>
<node CREATED="1735858342258" ID="ID_1387359881" MODIFIED="1735858353193" TEXT="die man vorher im lokalen Scope aufbauen mu&#xdf;"/>
<node CREATED="1735858377206" ID="ID_211964115" MODIFIED="1735862286860" TEXT="au&#xdf;erdem wird ein bereits konstruierter delegate-Port ben&#xf6;tigt"/>
</node>
<node CREATED="1735862289560" ID="ID_1280182429" MODIFIED="1735862434597" TEXT="nested ParamAgentBuilder">
<node CREATED="1735862444187" ID="ID_1429806835" MODIFIED="1735862455069" TEXT="connectLead ... analog zum PortBuilder"/>
<node CREATED="1735862464720" ID="ID_694664172" MODIFIED="1735862471381" TEXT="Terminal: completePort()"/>
</node>
</node>
<node CREATED="1720178543387" ID="ID_1839001807" MODIFIED="1720178576252" TEXT="adaptInvocation&lt;ADA&gt;">
<node CREATED="1720178577432" ID="ID_438090694" MODIFIED="1720178597453" TEXT="ADA &#x2261; Typ der Invocation-Adapter Klasse"/>
@ -94584,7 +94594,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node CREATED="1735354094901" ID="ID_357401280" LINK="#ID_1484484879" MODIFIED="1735416065935" TEXT="Grundstruktur / Schrittfolge">
<node COLOR="#435e98" CREATED="1735354094901" ID="ID_357401280" LINK="#ID_1484484879" MODIFIED="1735858145608" TEXT="Grundstruktur / Schrittfolge">
<linktarget COLOR="#754f56" DESTINATION="ID_357401280" ENDARROW="Default" ENDINCLINATION="-105;9;" ID="Arrow_ID_1575727839" SOURCE="ID_311986134" STARTARROW="None" STARTINCLINATION="-339;19;"/>
<icon BUILTIN="yes"/>
<node CREATED="1735354099466" ID="ID_1086019960" MODIFIED="1735354156573" TEXT="mount : Feed-Frame erzeugen"/>
<node CREATED="1735354158273" ID="ID_1400465949" MODIFIED="1735839974225" TEXT="pull : Param-Funktor aufrufen und Param-Daten generieren"/>
<node CREATED="1735354209348" ID="ID_1189493104" MODIFIED="1735354256129" TEXT="shed : Chain-Block erstellen und nachverarbeiten">
@ -94599,16 +94611,13 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1735841184088" ID="ID_1956237484" MODIFIED="1735841195299" TEXT="im Besonderen die Aufruf-Parameter passen nicht">
<node CREATED="1735842992849" ID="ID_255773054" MODIFIED="1735843139194" TEXT="....dann sollte man diese angleichen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
mit dem Ziel, die Einteilung des Weaving-Schemas zu erhalten und universeller nutzbar zu machen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<linktarget COLOR="#dae6f4" DESTINATION="ID_255773054" ENDARROW="Default" ENDINCLINATION="121;149;" ID="Arrow_ID_1145206955" SOURCE="ID_1242855477" STARTARROW="None" STARTINCLINATION="68;7;"/>
</node>
</node>
@ -94628,7 +94637,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1735841057608" ID="ID_1138290614" MODIFIED="1735841067182" TEXT="und das ist auch wieder schlecht"/>
<node CREATED="1735841068719" ID="ID_706216251" MODIFIED="1735841081018" TEXT="da noch ein weiterer Extension-Point / Freiheits-Grad"/>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1735842777063" ID="ID_311986134" MODIFIED="1735842960627" TEXT="es handelt sich um eine architektonische Ordnung">
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1735842777063" ID="ID_311986134" MODIFIED="1735858145608" TEXT="es handelt sich um eine architektonische Ordnung">
<arrowlink COLOR="#754f56" DESTINATION="ID_357401280" ENDARROW="Default" ENDINCLINATION="-105;9;" ID="Arrow_ID_1575727839" STARTARROW="None" STARTINCLINATION="-339;19;"/>
<linktarget COLOR="#fefde2" DESTINATION="ID_311986134" ENDARROW="Default" ENDINCLINATION="-14;-140;" ID="Arrow_ID_974408569" SOURCE="ID_1751038926" STARTARROW="None" STARTINCLINATION="-42;3;"/>
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
@ -98062,13 +98072,17 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<node CREATED="1735434522544" ID="ID_686486120" LINK="#ID_1295659864" MODIFIED="1735434554616" TEXT="brauche Zeit-Quantisierung"/>
<node CREATED="1735434579728" ID="ID_1335340741" LINK="#ID_276802280" MODIFIED="1735434603176" TEXT="brauche Accessor in TurnoutSystem"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1735962572153" ID="ID_600039329" MODIFIED="1735962606991" TEXT="dann exakt das gleiche Setup per ParamAgentBuilder konstruieren">
<linktarget COLOR="#a9b4c1" DESTINATION="ID_600039329" ENDARROW="Default" ENDINCLINATION="-387;16;" ID="Arrow_ID_1024063898" SOURCE="ID_373701114" STARTARROW="None" STARTINCLINATION="-156;-13;"/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1735416494813" ID="ID_329885446" MODIFIED="1735417263442" TEXT="Builder f&#xfc;r dedizierte ParamNode">
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1735416494813" ID="ID_329885446" MODIFIED="1735962384703" TEXT="Builder f&#xfc;r dedizierte ParamNode">
<linktarget COLOR="#482c86" DESTINATION="ID_329885446" ENDARROW="Default" ENDINCLINATION="-553;-36;" ID="Arrow_ID_1024921689" SOURCE="ID_921902157" STARTARROW="None" STARTINCLINATION="598;1114;"/>
<linktarget COLOR="#5747d2" DESTINATION="ID_329885446" ENDARROW="Default" ENDINCLINATION="-844;-25;" ID="Arrow_ID_1824926310" SOURCE="ID_1257939291" STARTARROW="None" STARTINCLINATION="-633;42;"/>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="pencil"/>
<node CREATED="1735416968791" HGAP="28" ID="ID_1420751527" MODIFIED="1735417275282" STYLE="bubble" VSHIFT="20">
<richcontent TYPE="NODE"><html>
<head/>
@ -98084,6 +98098,88 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<edge COLOR="#3495a4"/>
<arrowlink COLOR="#53a3b5" DESTINATION="ID_1559115287" ENDARROW="Default" ENDINCLINATION="-116;8;" ID="Arrow_ID_35370272" STARTARROW="None" STARTINCLINATION="-39;-6;"/>
</node>
<node COLOR="#338800" CREATED="1735862492660" HGAP="33" ID="ID_1597168085" MODIFIED="1735962375206" TEXT="ParamAgentBuilder aufbauen" VSHIFT="11">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1735862512753" ID="ID_851179462" MODIFIED="1735961868580" TEXT="funktioniert wie der PortBuilder">
<icon BUILTIN="yes"/>
<node CREATED="1735956196021" ID="ID_1195729716" MODIFIED="1735956205757" TEXT="also Subklasse von PortBuilderRoot"/>
<node CREATED="1735956220132" ID="ID_630293698" MODIFIED="1735956271817" TEXT="produziert eine &#xbb;dropper closure&#xab;">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...die dann sp&#228;ter den eigentlichen Turnout produziert und in den DataBuilder f&#252;r die Node-Ports &#8222;abwirft&#8220;
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1735956206934" ID="ID_994628798" MODIFIED="1735956218424" TEXT="und sliced sich selbst am Ende weg"/>
</node>
<node CREATED="1735862535880" ID="ID_1087061656" MODIFIED="1735862604277" TEXT="verwendet aber keinen nested WeavingBuilder">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
diese zus&#228;tzliche Komplexit&#228;t ist hier &#252;berfl&#252;ssig (auch wenn das nicht ganz symmetrisch ist...)
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1735862522248" ID="ID_414613779" MODIFIED="1735862534482" TEXT="mu&#xdf; am Ende ebenfalls eine kompatible Closure erzeugen"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1735961886318" HGAP="8" ID="ID_770824594" MODIFIED="1735962364095" STYLE="bubble" TEXT="&#xd83d;&#xddf2; ist leider ziemlich technischer Code &#xd83d;&#xddf2;" VSHIFT="11">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...aber was will man schon machen; das liegt in der Natur des Builder-Ansatzes, da&#223; der Builder selber aus relativ inhaltsleerem <i>mapping</i>&#160;und <i>forwarding</i>&#160;besteht, und man zudem die Builder-Struktur im Kopf haben mu&#223;, um sich im Code zurecht zu finden, da aus jeder Sub-Klausel ein ganzer Sub-Builder wird. Und zu allem &#220;berflu&#223; kommt hier noch die Komplikation mit dem Memory-Management hinzu, die man &#252;berhaupt nur mit einem solchen Builder-Ansatz noch beherrschen kann.
</p>
<p>
</p>
<p>
<font color="#900020" size="4"><i>Ich f&#252;rchte, dieser Code ist nun nahezu undurchdringbar f&#252;r jeden Leser au&#223;er mir </i></font>
</p>
<ul>
<li>
<font color="#900020" size="4"><i>ich wei&#223; mir aber nicht anders zu helfen</i></font>
</li>
<li>
<font color="#900020" size="4"><i>die Komplexit&#228;t bringt auch mich nahezu um</i></font>
</li>
<li>
<font color="#900020" size="4"><i>und das, was oberhalb dieses Builders aufsetzen wird, ist ebenfalls sehr komplex und dringend auf die Abstraktionsleistung der DSL angewiesen</i></font>
</li>
</ul>
</body>
</html></richcontent>
<edge COLOR="#aa0303"/>
<font NAME="SansSerif" SIZE="13"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1735962403144" ID="ID_141428542" MODIFIED="1735962413554" TEXT="Zusammenspiel mit dem ParamWeavingPattern">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1735962417830" ID="ID_1920831768" MODIFIED="1735962446968">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
rein nach Definition <i>sollte es bereits funktionieren</i>
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="idea"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1735962448890" ID="ID_72580990" MODIFIED="1735962486906" TEXT="aber das kann ich nicht recht glauben">
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="smiley-oh"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1735962498796" ID="ID_373701114" MODIFIED="1735962606991" TEXT="brauche nun Tests als Treiber">
<arrowlink DESTINATION="ID_600039329" ENDARROW="Default" ENDINCLINATION="-387;16;" ID="Arrow_ID_1024063898" STARTARROW="None" STARTINCLINATION="-156;-13;"/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
</node>
</node>