Invocation: work out solution for a precisely fitting allocation

Conduct in-depth analysis to handle a secondary, implementation-related
(and frankly quite challenging) concern regarding the placement of node
and port connectivity data in memory. The intention is for the low-level
model to use a custom data structure based on `lib::Several`, allowing for
flexible and compact arrangement of the connectivity descriptors within
tiled memory blocks, which can then later be discarded in bulk, whenever
a segment of the render graph is superseded. Yet since the generated
descriptors are heterogeneous and, due to virtual functions, can not be
trivially copied, the corresponding placement invocations on the
data builder API must not be mixed, but rather given in ordered strikes
and preceded by a dimensioning call to pre-reserve a bulk of storage

However, doing so directly would jeopardise the open and flexible nature
of the node builder API, thereby creating a dangerous coupling between
the implementation levels of the node graph and of prospective library
wrapper plug-ins in charge of controlling details of the graph layout.

The solution devised here entails a functional helper data structure
created temporarily within the builder API stack frames; the detailed
and local type information provided from within the library plug-in
can thereby be embedded into opaque builder functors, allowing to
delay the actual data generation up until the final builder step,
at which point the complete number and size requirements of
connectivity data is known and can be used for dimensioning.
This commit is contained in:
Fischlurch 2024-10-20 21:51:34 +02:00
parent 634df743f0
commit b4aee6fba8
3 changed files with 536 additions and 66 deletions

View file

@ -614,7 +614,7 @@ namespace lib {
,Policy::ALLOC_LIMIT)
,overhead)
,max (2*buffSiz, cnt*spread));
// round down to an even number of elements
// round down to an straight number of elements
size_t newCnt = expandAlloc / spread;
expandAlloc = newCnt * spread;
if (expandAlloc < demand)

View file

@ -22,7 +22,7 @@
/** @file weaving-pattern-builder.hpp
** Construction kit for establishing an invocation scheme for media calculations.
** Construction kit to establish an invocation scheme for media calculations.
**
** @see turnout.hpp
** @see node-builder.hpp
@ -49,7 +49,7 @@
//#include "lib/iter-adapter.hpp"
//#include "lib/meta/function.hpp"
//#include "lib/itertools.hpp"
//#include "lib/util.hpp"
#include "lib/util.hpp"
//#include <utility>
#include <functional>
@ -63,6 +63,7 @@ namespace engine {
using std::forward;
using lib::Several;
using lib::Depend;
using util::max;
namespace {// Introspection helpers....
@ -225,6 +226,45 @@ namespace engine {
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Prototyping: how to assemble a Turnout
/**
* Recursive functional data structure to collect weaving pattern data
* and finally to emplace a Turnout instance into the data storage
* for each port, as specified by preceding builder-API invocations.
* @tparam PAR recursive layering for preceding entries
* @tparam BUILD a builder functor to emplace one Turnout instance,
* opaquely embedding all specific data typing.
* @tparam siz storage in bytes to hold data produced by \a BUILD
*/
template<class PAR, class BUILD, uint siz>
struct PatternData
: PAR
{
BUILD buildEntry;
template<class DAB>
void
collectEntries (DAB& dataBuilder, uint cntElm =0, uint maxSiz =0)
{
PAR::collectEntries (dataBuilder, cntElm+1, max (siz,maxSiz));
buildEntry (dataBuilder);
}
};
/**
* Data recursion end: prime the port data storage
* by reserving appropriate storage to hold all known Turnout elements.
*/
struct DimData
{
template<class DAB>
void
collectEntries (DAB& dataBuilder, uint cntElm, uint maxSiz)
{
dataBuilder.reserve (cntElm, maxSiz);
}
};
template<uint N, class FUN>
using SimpleDirectInvoke = SimpleWeavingPattern<Conf_DirectFunctionInvocation<N,FUN>>;

View file

@ -8719,9 +8719,7 @@
<node CREATED="1511227994153" ID="ID_1055820971" MODIFIED="1511228200056" TEXT="nicht jede Kombi ist valide"/>
<node CREATED="1511228014599" ID="ID_817679403" MODIFIED="1511572072623" TEXT="&quot;Zugriff auf Core&quot; kann nicht abstrahiert werden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
weil...
@ -8875,9 +8873,7 @@
</node>
<node CREATED="1511482393172" ID="ID_1538766965" MODIFIED="1511572072839" TEXT="das w&#xe4;re dann: den Iterator zu verwenden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
denn das ist der sinnvollste Fall f&#252;r ein generisches Lambda
@ -9397,9 +9393,7 @@
<node CREATED="1512951807371" ID="ID_1239289160" MODIFIED="1512951840907" TEXT="mu&#xdf; f&#xfc;r diesen Fall selbst&#xe4;ndig terminieren"/>
<node CREATED="1512951841703" ID="ID_815720383" MODIFIED="1512951903322" TEXT="&quot;komplett entfaltet&quot; wird zur Invariante">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...also Programmierung analog zum Filter
@ -10376,9 +10370,7 @@
</node>
<node CREATED="1512349405280" ID="ID_1121668073" MODIFIED="1512349446256" TEXT="war nachweislich eine echte Fehlfunktion">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
habs mit FormatUtils_test bewiesen
@ -11896,9 +11888,7 @@
</node>
<node COLOR="#338800" CREATED="1517508915741" ID="ID_974516393" MODIFIED="1518750409200">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Support f&#252;r <i>elided</i>&#160;element
@ -13768,9 +13758,7 @@
</node>
<node COLOR="#338800" CREATED="1517507566761" FOLDED="true" ID="ID_839496495" MODIFIED="1561827483831">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Anwendung <i>delegiert</i>&#160;an einen Serivce
@ -16989,9 +16977,7 @@
<node CREATED="1487472730667" ID="ID_1826692985" MODIFIED="1518487921076" TEXT="k&#xf6;nnen aber noch Fenster existieren"/>
<node CREATED="1487472757439" ID="ID_977443666" MODIFIED="1518487921076">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
wird der Link zwischen CoreService und UI-State <i>dangling</i>
@ -22105,9 +22091,7 @@
</node>
<node COLOR="#338800" CREATED="1678383001172" ID="ID_1151442798" MODIFIED="1678383448071" TEXT="Konzept inzwischen grunds&#xe4;tzlich klar">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
und funktioniert gut f&#252;r Clip-Widgets auf der Timeline
@ -50369,9 +50353,7 @@
<icon BUILTIN="go"/>
<node CREATED="1453545875627" ID="ID_1411740156" MODIFIED="1576282358001" TEXT="Definition &#xbb;Zentral-Dienste&#xab;">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Dienste im UI, erreichbar &#252;ber den Bus.
@ -50708,9 +50690,7 @@
</node>
<node CREATED="1488674528035" ID="ID_1084922722" MODIFIED="1576282358000">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
<i>mu&#223;</i>&#160;Instanzen einsetzen
@ -50874,9 +50854,7 @@
<node CREATED="1488677350640" ID="ID_901346570" MODIFIED="1488677370377" TEXT="Ausf&#xfc;hrung im Dispatcher erst sp&#xe4;ter"/>
<node COLOR="#338800" CREATED="1488677418087" ID="ID_644949863" MODIFIED="1576282357998" TEXT="ist doch kein Problem">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...denn das GUI l&#228;uft ja synchron.
@ -50940,9 +50918,7 @@
<icon BUILTIN="yes"/>
<node CREATED="1488936938742" ID="ID_1388901840" MODIFIED="1488939645006">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
GUI: <b>CmdAccessor</b>
@ -50986,9 +50962,7 @@
<node CREATED="1488940435601" ID="ID_1906295137" MODIFIED="1492442861300" TEXT="InteractionState befriedigt die Parameter aus dem aktuellen Interaktions-Kontext"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1488940469365" ID="ID_130562988" MODIFIED="1576282357997" TEXT="TODO: wie werden die Parameter konkret &#xfc;bergeben?">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
es k&#246;nnte z.B. sein, da&#223; man vom InteractionState
@ -89593,8 +89567,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,void(array&lt;char*,1&gt;,array&lt;char*,1&gt;) &gt;&gt;&gt;</font>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1728912494851" MODIFIED="1728912494851" TEXT="I = steam::engine::Port"/>
<node CREATED="1728912494851" MODIFIED="1728912494851" TEXT="E = steam::engine::Port"/>
@ -89624,8 +89597,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
insofern verh&#228;lt sich hier der Compiler<i>&#160;formal</i>&#160;und auch<i>&#160; inhaltlich</i>&#160;<b>logisch korrekt</b>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1728913695699" ID="ID_1603489656" MODIFIED="1728913965774">
<richcontent TYPE="NODE"><html>
@ -89638,8 +89610,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<font color="#7407d7">MoveOnly</font>&#160;&#9665;&#8212; CONF&#160;&#160;&#9665;&#8212;&#160;SimpleWeavingPattern&#160;&#160;&#9665;&#8212; <b>Turnout</b>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="info"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1728914001593" ID="ID_290756970" MODIFIED="1728914402212" TEXT="an Realloc hatte ich bisher nicht gedacht">
@ -89657,8 +89628,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
indem man die Parameter in diesem Zweig voided
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<linktarget COLOR="#a9b4c1" DESTINATION="ID_852271835" ENDARROW="Default" ENDINCLINATION="19;47;" ID="Arrow_ID_495667234" SOURCE="ID_230526713" STARTARROW="None" STARTINCLINATION="69;8;"/>
<icon BUILTIN="button_ok"/>
</node>
@ -89678,8 +89648,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Da ProcNodes regelm&#228;&#223;ig auf ihre Leads per direkter Referenz zugreifen, m&#252;ssen sie sofort mit der Erzeugung im Speicher festgesetzt werden. Das war auch der Grund, warum ich den Builder in dieser limitierten Form aufgebaut habe: man mu&#223; sich zwangsl&#228;ufig von den Quellen durch den Graphen aufw&#228;rts bewegen.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1728914795559" ID="ID_1052546340" MODIFIED="1728914842396" TEXT="&#x27f9; aber alles was im Builder auftritt ist potentiell gef&#xe4;hrlich">
@ -89707,8 +89676,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
&#187;one-shot&#171;-Konstruktor, Objekte werden nur in den Definitionslisten erzeugt. Das erfordert entweder, extrem viele Detail-Konstruktorparameter durchzureichen (Problem der Verkopplung), oder eben ganze Teilkomponenten per RValue-Ref entgegenzunehmen und an den Zielpunkt zu schieben
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1728918821443" ID="ID_1466886872" MODIFIED="1728918825494" TEXT="Ausweg">
<node CREATED="1728918826658" ID="ID_1610131618" MODIFIED="1728918837787" TEXT="Builder der per Seiteneffekt generiert"/>
@ -89727,8 +89695,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Aufgrund der Komplexit&#228;t der aufgebauten Strukturen ist nicht ersichtlich, ob der Compiler sich korrekt verh&#228;lt; jedenfalls versucht er, den <b>Copy-Konstruktor</b>&#160;von engine::Turnout zu verwenden
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="broken-line"/>
<node CREATED="1728921691001" ID="ID_369047782" MODIFIED="1728921712680" TEXT="er beseht darauf, f&#xfc;r Port den Copy-Konstruktor aufzurufen"/>
<node CREATED="1728921713967" ID="ID_840072193" MODIFIED="1728921744509" TEXT="selbst wenn ich explizit in Turnout einen Move-Konstruktor anschreibe"/>
@ -89779,12 +89746,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
man m&#252;&#223;te lediglich der build()-Methode explizit einen SeveralBuilder &#252;bergeben; das lie&#223;e sich sogar generalisieren auf etwas Generisches, das eine emplace()-Methode bietet; in erster N&#228;herung (C++17) w&#228;re das ein offener Template-Parameter
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1728919724334" ID="ID_1429006329" MODIFIED="1728919748503" TEXT="Bleibt aber das Problem mit realloc()">
<arrowlink COLOR="#eb3d5e" DESTINATION="ID_1149896689" ENDARROW="Default" ENDINCLINATION="-34;-33;" ID="Arrow_ID_1718389433" STARTARROW="None" STARTINCLINATION="-192;14;"/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1728919780226" ID="ID_459933288" MODIFIED="1728920202861" TEXT="die &#xbb;Hintert&#xfc;r&#xab; funktioniert nur f&#xfc;r die aktuell neueste Allokation">
<richcontent TYPE="NOTE"><html>
@ -89794,8 +89761,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
mit &#187;Hintert&#252;r&#171; meine ich die F&#228;higkeit zum dynamischen Wachsen der Allokation speziell im Allocation-Cluster; das ist leicht m&#246;glich, aber nur indem wir die aktuell neueste Allokation im Rahmen eines Bucket nachjustieren
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1728920206175" ID="ID_1988845099" MODIFIED="1728920273724" TEXT="aber der nested-Builder bewirkt verschachtelte Allokations-Anforderungen"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728920314192" ID="ID_147357026" MODIFIED="1728920324731" TEXT="L&#xf6;sungen">
@ -89831,7 +89797,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</html></richcontent>
</node>
<node CREATED="1728920871071" ID="ID_358330215" MODIFIED="1728920885026" TEXT="das ganze Builder-Schema bleibt so wie es ist"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1728920893861" ID="ID_563974492" MODIFIED="1728920908958" TEXT="Port w&#xfc;rde man sich dann am Abgrund bewegen">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1728920893861" ID="ID_563974492" MODIFIED="1728920908958" TEXT="Port w&#xfc;rde sich dann am Abgrund bewegen">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1728920911699" ID="ID_226962231" MODIFIED="1728920927731" TEXT="es geht, weil Port-Referenzen sich stets auf bereits gebaute Nodes beziehen"/>
<node CREATED="1728920928976" ID="ID_1711841513" MODIFIED="1728920975557" TEXT="das mu&#xdf; man aber wissen...">
@ -89842,8 +89808,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
jedermann k&#246;nnte jederzeit Port-Referenzen in anderen Umgst&#228;nden erzeugen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
</node>
@ -89860,15 +89825,441 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1728921193764" ID="ID_690402795" MODIFIED="1728921344029" TEXT="der Several-Builder arbeitet mit I &#x2261; E &#x2254; Port">
<linktarget COLOR="#eb115c" DESTINATION="ID_690402795" ENDARROW="Default" ENDINCLINATION="11;-7;" ID="Arrow_ID_983406969" SOURCE="ID_1600081549" STARTARROW="None" STARTINCLINATION="-5;9;"/>
<icon BUILTIN="broken-line"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1728921314268" ID="ID_1057362951" MODIFIED="1728921323407" TEXT="warum eigentlich?">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#320f69" CREATED="1728921314268" ID="ID_1057362951" MODIFIED="1729301518983" TEXT="warum eigentlich?">
<icon BUILTIN="help"/>
<node CREATED="1728921407026" ID="ID_1988539921" MODIFIED="1728921416272" TEXT="WeavingBuilder::build() ist auto"/>
<node CREATED="1728921417310" ID="ID_1211882082" MODIFIED="1728921449333" TEXT="&#x201e;sollte doch&#x201c; einen Turnout liefern"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1728921453763" ID="ID_1928466246" MODIFIED="1728921475471" TEXT="ich h&#xe4;tte erwartet, da&#xdf; SeveralBuilder das aufgreift">
<node COLOR="#5b280f" CREATED="1728921453763" ID="ID_1928466246" MODIFIED="1729302438858" TEXT="ich h&#xe4;tte erwartet, da&#xdf; SeveralBuilder das aufgreift">
<arrowlink COLOR="#89384e" DESTINATION="ID_426682280" ENDARROW="Default" ENDINCLINATION="12;-28;" ID="Arrow_ID_899602642" STARTARROW="None" STARTINCLINATION="-289;15;"/>
<icon BUILTIN="flag-pink"/>
<icon BUILTIN="smily_bad"/>
</node>
<node CREATED="1729298610689" ID="ID_230016512" MODIFIED="1729298665431" TEXT="I &#x2254; Port &#x2014; aber E w&#xfc;rde in der DataBuilder-Definition gesetzt">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1729301399630" HGAP="36" ID="ID_1796030895" MODIFIED="1729301469234" TEXT="kann also niemals &#x201e;aufgegriffen werden&#x201c;" VSHIFT="3">
<linktarget COLOR="#764652" DESTINATION="ID_1796030895" ENDARROW="Default" ENDINCLINATION="-1;32;" ID="Arrow_ID_316765865" SOURCE="ID_1966937335" STARTARROW="None" STARTINCLINATION="100;4;"/>
<font NAME="SansSerif" SIZE="11"/>
<icon BUILTIN="broken-line"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1729298531025" ID="ID_1966937335" MODIFIED="1729301490964" TEXT="&#xbb;Turnout&#xab; ist essentiell generisch mit jeweils passender Manifold-size">
<arrowlink COLOR="#764652" DESTINATION="ID_1796030895" ENDARROW="Default" ENDINCLINATION="-1;32;" ID="Arrow_ID_316765865" STARTARROW="None" STARTINCLINATION="100;4;"/>
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#e9c296" COLOR="#a02740" CREATED="1728921324643" ID="ID_1723172951" MODIFIED="1729300672973" TEXT="das kann doch gar nicht funktionieren!">
<icon BUILTIN="clanbomber"/>
<node CREATED="1729299779943" ID="ID_416592787" MODIFIED="1729300026695">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
Turnout ist <b>sicher nicht</b>&#160;<i>trivially copyable</i>
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<ul>
<li>
und zwar allein schon wegen dem virtuellen Destruktor
</li>
<li>
au&#223;erdem aus konzeptionellen Gr&#252;nden: es soll ja ein Extension-Point sein, also k&#246;nnen wir eigentlich nichts &#252;ber diesen Typ sagen
</li>
</ul>
</body>
</html></richcontent>
</node>
<node CREATED="1729300229244" ID="ID_1033505516" MODIFIED="1729300559466" TEXT="&#x27f9; bereits das erste Element bewirkt lock_move"/>
<node CREATED="1729300518732" ID="ID_735942887" MODIFIED="1729300563498" TEXT="&#x27f9; das erste Element legt auch endg&#xfc;ltig den Spread fest"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1729301557825" ID="ID_1149896689" MODIFIED="1729303056446" TEXT="zwei distinkte Probleme">
<linktarget COLOR="#eb3d5e" DESTINATION="ID_1149896689" ENDARROW="Default" ENDINCLINATION="-34;-33;" ID="Arrow_ID_1718389433" SOURCE="ID_1429006329" STARTARROW="None" STARTINCLINATION="-192;14;"/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1729301581058" ID="ID_1531670870" MODIFIED="1729302527972" TEXT="spread in der Array-Storage mu&#xdf; sofort ausreichend bestimmt sein">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
wenn sp&#228;ter in der Sequenz eine gr&#246;&#223;ere FeedManifold gebraucht wird, l&#228;&#223;t sich der Spread nicht mehr durch Verschieben bereits bestehender Elemente korrigieren
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1729301616771" ID="ID_181067554" MODIFIED="1729301957992" TEXT="die Allokation mu&#xdf; sofort ausreichend dimensioniert sein">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...weil kein realloc() m&#246;glich ist; zudem mu&#223; auch die Extent-Gr&#246;&#223;e des AllocationCluster bedacht werden (was sich jetzt hier, im Prototyp-Code noch gar nicht auswirkt, da wir ja Heap-Allokationen machen); <i>wenn es der letzte aktive Builder ist und alle Anforderungen am St&#252;ck kommen,</i>&#160; dann k&#246;nnte man im AllocationCluster dynamisch justieren (nicht aber bei Heap-Allokation)
</p>
</body>
</html></richcontent>
</node>
</node>
<node COLOR="#5b280f" CREATED="1729301987263" HGAP="6" ID="ID_426682280" MODIFIED="1729302426810" STYLE="bubble" VSHIFT="15">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p style="text-align: center">
die erhoffte &#187;dynamische Belegung&#171;
</p>
<p style="text-align: center">
ist unter den vorgegebenen Beschr&#228;nkungen
</p>
<p style="text-align: center">
so nicht realisierbar
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
<u>Vorgabe</u>:
</p>
<ul>
<li>
es ist eine Performance-kritische Datenstruktur
</li>
<li>
wir m&#252;ssen eine Bulk-Allokation machen
</li>
<li>
Datenwerte sollen kompakt liegen (cache locality)
</li>
</ul>
</body>
</html></richcontent>
<edge COLOR="#b75454"/>
<linktarget COLOR="#89384e" DESTINATION="ID_426682280" ENDARROW="Default" ENDINCLINATION="12;-28;" ID="Arrow_ID_899602642" SOURCE="ID_1928466246" STARTARROW="None" STARTINCLINATION="-289;15;"/>
<icon BUILTIN="stop-sign"/>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1729302196298" ID="ID_1847553313" MODIFIED="1729303144999" TEXT="eine pa&#xdf;genaue Allokation ist eigens sicherzustellen">
<arrowlink COLOR="#a33264" DESTINATION="ID_1966477380" ENDARROW="Default" ENDINCLINATION="16;-35;" ID="Arrow_ID_1870774816" STARTARROW="None" STARTINCLINATION="-112;6;"/>
<icon BUILTIN="yes"/>
<node CREATED="1729302235086" ID="ID_1925341713" MODIFIED="1729302359360" TEXT="die Diskussion btr. Non-copyable vs. movable ist peripher">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...denn beide L&#246;sungen unterliegen den strengeren Beschr&#228;nkungen bez&#252;glich der Allokation; das hat aber auch den Vorteil, da&#223; man diese Entscheidung rein auf Basis der sonstigen Vor- und Nachteile abw&#228;gen und treffen kann
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1729302635570" ID="ID_1269287328" MODIFIED="1729302815670" TEXT="Ma&#xdf;gabe: die Offenheit des Builders ist zu erhalten">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Es besteht die Gefahr, da&#223; f&#252;r diese genau abgezirkelte Allokation ein festes Belegungsschema notwendig wird, und damit die Idee eines Builder-API im Kern negiert ist; denn in einem solchen Fall w&#252;rde es zu einer Verkopplung zwischen der Logik in der Domain-Ontology und dem Datenlayout im Modell kommen
</p>
</body>
</html></richcontent>
<node CREATED="1729302835709" ID="ID_1141329891" MODIFIED="1729302933054" TEXT="Ziel sollte sein, die Freiheit des Nutzers zu erhalten">
<icon BUILTIN="yes"/>
</node>
<node CREATED="1729302877288" ID="ID_1127038030" MODIFIED="1729302925317" TEXT="damit scheidet die L&#xf6;sung aus, da&#xdf; der Client die ben&#xf6;tigten Daten &#xbb;vordimensioniert&#xab;">
<icon BUILTIN="closed"/>
</node>
<node CREATED="1729302940255" ID="ID_1001603416" MODIFIED="1729302987650" TEXT="der Build-Vorgang mu&#xdf; kompakt in der terminalen Operation stattfinden">
<icon BUILTIN="forward"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1729303081050" ID="ID_1966477380" MODIFIED="1729303127596" TEXT="Ausarbeiten einer pa&#xdf;genauen Implementierung">
<linktarget COLOR="#a33264" DESTINATION="ID_1966477380" ENDARROW="Default" ENDINCLINATION="16;-35;" ID="Arrow_ID_1870774816" SOURCE="ID_1847553313" STARTARROW="None" STARTINCLINATION="-112;6;"/>
<icon BUILTIN="flag-pink"/>
<node CREATED="1729303163506" ID="ID_1888134179" MODIFIED="1729303172498" TEXT="Zielvorgaben">
<icon BUILTIN="yes"/>
<node CREATED="1729303190542" ID="ID_1157491975" MODIFIED="1729303371888">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
f&#252;r alle <i>problematischen Daten-Builder</i>&#160;gilt.....
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
&#187;problematisch&#171; sind alle Daten-Builder, die
</p>
<ul>
<li>
mit heterogenen Objekten belegt werden
</li>
<li>
und f&#252;r die die Objekte nicht<i>&#160;trivially copyable</i>&#160;sind
</li>
</ul>
</body>
</html></richcontent>
</node>
<node CREATED="1729303223690" ID="ID_1668152159" MODIFIED="1729303249893" TEXT="vor Belegen des ersten Datenelements mu&#xdf; eine automatische Dimensionierung erfolgen"/>
</node>
<node CREATED="1729305640248" ID="ID_1661765820" MODIFIED="1729305648785" TEXT="Analyse der Einzelvorg&#xe4;nge">
<node CREATED="1729305727202" ID="ID_957838756" MODIFIED="1729305731853" TEXT="NodeBuilder">
<node CREATED="1729305733399" ID="ID_1044493689" MODIFIED="1729305839911" TEXT="die LeadRefs sind relativ unproblematisch">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
es kommt hier nur zu einer gewissen Speicher-Verschwendung, wenn ein realloc() mit Umkopieren gemacht wird, da der AllocationCluster die alte Allokation einfach tot mitschleppt
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1729305849578" ID="ID_1804465000" MODIFIED="1729305947409" TEXT="aber alle Port-Eintr&#xe4;ge(&#x2259;Turnouts) m&#xfc;ssen zuletzt in einem Schwung generiert werden"/>
</node>
<node CREATED="1729306153609" ID="ID_1286730537" MODIFIED="1729306158101" TEXT="PortBuilder">
<node CREATED="1729306159967" ID="ID_78233270" MODIFIED="1729306284918" TEXT="zu kl&#xe4;ren: wo werden die Weaving-Pattern-Parameter zwischengespeichert?"/>
<node CREATED="1729306296341" ID="ID_1639896665" MODIFIED="1729306365760" TEXT="bisherige L&#xf6;sung: PortBuilder als eine tempor&#xe4;r erzeugte Subklasse auf dem Stack halten"/>
</node>
<node CREATED="1729306878831" ID="ID_1351726919" MODIFIED="1729306883218" TEXT="WeavingBuilder">
<node CREATED="1729306885960" ID="ID_1794659252" MODIFIED="1729306913167" TEXT="leadPort und outTypes sind relativ unproblematisch"/>
<node CREATED="1729306923281" ID="ID_665043448" MODIFIED="1729306938419" TEXT="es gibt aber noch zwei Vectors mit Arbeitsdaten"/>
<node CREATED="1729307009348" ID="ID_1344032375" MODIFIED="1729307029655" TEXT="die Belegung von leadPort und outTypes findet bereits entflochten statt"/>
<node CREATED="1729307034959" ID="ID_982363236" MODIFIED="1729307066852" TEXT="man m&#xfc;&#xdf;te lediglich das Several f&#xfc;r die leadPorts in die build()-Funktion schieben"/>
</node>
<node CREATED="1729307297963" ID="ID_943373598" MODIFIED="1729307309144" TEXT="abschlie&#xdf;ender Schritt">
<node CREATED="1729307313017" ID="ID_1049380221" MODIFIED="1729307344813" TEXT="demnach m&#xfc;&#xdf;te das Konstruieren des Turnout auf sp&#xe4;ter verschoben werden"/>
<node CREATED="1729307349538" ID="ID_377799822" MODIFIED="1729307371229" TEXT="damit ist aber weitere Storage notwendig f&#xfc;r die Dateninhalte">
<node CREATED="1729307384804" ID="ID_1867864484" MODIFIED="1729307391302" TEXT="Several&lt;PortRef&gt;"/>
<node CREATED="1729307392664" ID="ID_1001735525" MODIFIED="1729307415447" TEXT="Several&lt;BuffDescr&gt;"/>
<node CREATED="1729307446488" ID="ID_457436977" MODIFIED="1729307460312" TEXT="N (Gr&#xf6;&#xdf;e der Manifold)"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1729307494039" ID="ID_1819511988" MODIFIED="1729307810896" TEXT="Idee: Tail-rekursiver Builder-Aufruf?">
<icon BUILTIN="help"/>
<node CREATED="1729307525576" ID="ID_1617175155" MODIFIED="1729307576310" TEXT="man w&#xfc;rde damit die Dateninhalte auf dem Stack sammeln"/>
<node CREATED="1729307669041" ID="ID_1469484154" MODIFIED="1729307806096" TEXT="allerdings mu&#xdf; dann auch die Port-Erzeugung Tail-rekursiv geschrieben werden">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Man w&#252;rde sich damit von dem vertrauten und klaren Builder-API verabschieden, und stattdessen ein Aufrufmuster verwenden, welches von mindestens der H&#228;lfte aller Programmierer als &#8222;schwierig&#8220; empfunden wird. Und zwar rein aus Gr&#252;nden der Implementierungs-Mechanik; nach der inhaltlichen Logik w&#228;re das nicht notwendig
</p>
</body>
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1729307854949" ID="ID_556427565" MODIFIED="1729307889585" TEXT="Alternative: Dateninhalte auf dem Stack sammeln?">
<icon BUILTIN="help"/>
<node CREATED="1729307896503" ID="ID_195478436" MODIFIED="1729307957714" TEXT="ein Tupel (Several&lt;PortRef&gt;,Several&lt;BuffDescr&gt;, std::function, N)"/>
<node CREATED="1729307966587" ID="ID_1262034001" MODIFIED="1729308011601" TEXT="man kann dann in einem Pass das max(N) finden und damit dimensionieren"/>
<node CREATED="1729308038392" ID="ID_663527415" MODIFIED="1729308053721" TEXT="oder besser: einen Pass machen, der schon mal die Typen konstruiert"/>
<node CREATED="1729434301737" ID="ID_1528648390" MODIFIED="1729434407555" TEXT="die Function kann nur eine Builder-Function sein, mit Type-Erasure">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
es kann nicht die eigentliche Processing-Function sein, denn die ist generisch. Sondern in dem Functor steckt eigentlich die verz&#246;gerte terminal-build-Operation
</p>
</body>
</html></richcontent>
</node>
<node COLOR="#5b280f" CREATED="1729434345618" ID="ID_31768721" MODIFIED="1729434364792" TEXT="damit wird diese L&#xf6;sung ih&#xe4;rent redundant">
<icon BUILTIN="stop-sign"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1729308176710" ID="ID_70235871" MODIFIED="1729308532647" TEXT="Wichtig: am Ende des PortBuilder&apos; bereits eine Type-Erasure machen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
denn der konkrete Funktionstyp und das N (&#8793;Manifold-Gr&#246;&#223;e), sowie ggfs. ein alternativer &#187;InvocationAdapter&#171;-Typ sind zun&#228;chst im konkreten Typ des PortBuilders angelegt (als Typ-Kontext); das bedeutet, das Parameter-Tupel mu&#223; aus lauter Wrappern bestehen, die die konkreten Typen bereits materialisiert und virtualisiert enthalten. F&#252;r lib::Several ist das definitiv der Fall (das verweist auf einen Extent, in dem die Metadaten und das Daten-Array liegen). Auch std::function ist eine Abstraktion. Also w&#228;re wohl noch ein weiterer Generator-Functor notwendig, in dem man den konkreten InvocationAdapter versteckt
</p>
</body>
</html></richcontent>
<icon BUILTIN="yes"/>
</node>
</node>
</node>
<node CREATED="1729379380389" ID="ID_1826146255" MODIFIED="1729379767284" TEXT="Feststellen der Aufgabe">
<icon BUILTIN="forward"/>
<node CREATED="1729379393219" ID="ID_162735050" MODIFIED="1729379802830" TEXT="die bestehende Implementierung ist logisch gradlinig">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...wichtig: Wartbarkeit
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1729379408767" ID="ID_1384384815" MODIFIED="1729379780804" TEXT="sie soll (und kann) komplett erhalten bleiben wie sie ist"/>
<node CREATED="1729379433780" ID="ID_26064200" MODIFIED="1729379761461" TEXT="im WeavingBuilder ist nur eine minimale Umordnung der Data-Builder-Aufrufe notwendig">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1729379729417" ID="ID_1951268337" MODIFIED="1729379757592" TEXT="zum Abschlu&#xdf; des Build-Vorganges ist lediglich eine Verz&#xf6;gerung per Closure notwendig">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1729380002560" ID="ID_1790648194" MODIFIED="1729380024816" TEXT="Erasure der Weaving-Pattern-Konfiguration">
<icon BUILTIN="yes"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1729385699535" ID="ID_1823720040" MODIFIED="1729385709180" TEXT="Umstellung der Implementierung">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1729385821879" ID="ID_562398626" MODIFIED="1729385850635" TEXT="neues Interface f&#xfc;r Build-Ergebnis schaffen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1729385860586" ID="ID_1726006228" MODIFIED="1729385872581" TEXT="Zweck...">
<node CREATED="1729385873337" ID="ID_1712688191" MODIFIED="1729385886298" TEXT="erzeuge eine Deque mit function-Objekten"/>
<node CREATED="1729385887568" ID="ID_44692572" MODIFIED="1729385917344" TEXT="diese nehmen eine DataBuilder-Referenz als Argument"/>
<node CREATED="1729385918479" ID="ID_1138214516" MODIFIED="1729385963867">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
und im <i>getypten Kontext im Funktor </i>wird das Ergebnis &#187;abgeworfen&#171;
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1729386058095" ID="ID_1670829732" MODIFIED="1729386065330" TEXT="Bedingungen">
<node CREATED="1729386066793" ID="ID_559318620" MODIFIED="1729386488849" TEXT="mu&#xdf; genau auf den konkreten PortData-Builder im NodeBuilder passen"/>
<node CREATED="1729386116639" ID="ID_1942564674" MODIFIED="1729386143654" TEXT="kann aber erst im WeavingBuilder konstruiert werden, wegen POL(Allocator+Context-Poiicy)"/>
</node>
<node CREATED="1729386535588" ID="ID_288497913" MODIFIED="1729386568518" TEXT="ist lediglich eine Typedef + ein Consumer-Functor"/>
</node>
<node CREATED="1729386797044" ID="ID_1761275309" MODIFIED="1729386814097" TEXT="Builder-Closure vom WeavingBuilder entkoppeln">
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1729386815675" ID="ID_1416710632" MODIFIED="1729386828903" TEXT="WeavingBuilder lebt nur tempor&#xe4;r auf dem Stack">
<icon BUILTIN="messagebox_warning"/>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1729434130348" ID="ID_1796646662" MODIFIED="1729434165322" TEXT="mu&#xdf; size-Info weitergeben &#x27f9; Funktor allein gen&#xfc;gt nicht">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1729435375920" ID="ID_232356982" MODIFIED="1729435650306" TEXT="damit bleibt nur eine rekursive funktionale Datenstruktur &#xfc;brig">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...zwar k&#246;nnte man jetzt wieder ein Tupel machen, in das den Builder-Functor legen und zus&#228;tzliche Steuer-Infos; diese Tupel w&#252;rden dann in eine Collection auf dem Heap gehen und dort iteriert. Das w&#228;re (scheinbar) simpel, aber nicht einfach und klar. Deshalb bleibt f&#252;r mich als einzige Alternative, die notwendigen Schrite unmittelbar in eine verkettete Aufrufstruktur zu packen. Das ist dann zwar zun&#228;chst fordernd f&#252;r den Leser (aber das ist die Implementierung des Builders sowiso schon); aber immerhin erschlie&#223;t sich der Sinn unmittelbar lokal im jeweiligen Aufruf &#8212; genauer gesagt, man kann direkt beim lokalen Aufruf den Sinn in einem Kommentar erl&#228;utern, und zwar komplett
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1729435659564" ID="ID_1514339739" MODIFIED="1729435870550">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
diese Datenstruktur ist die <b>Sequenz der Builder</b>&#160;selber
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Builder sind generisch, d.h. tragen Typ-Parameter, und die konkreten Typen in diesen durchlaufen eine Sequenz, in welcher sich schrittweise die Datenstruktur aufbaut. Effektiv liegen die Daten in dem &#228;u&#223;eren Stack-Frame, welcher das Builder-API aufruft; sie werden jeweils f&#252;r einen Aufruf in den n&#228;chsten Stack-Frame geschoben, und dann wieder zur&#252;ck geschoben, allerdings wie in einer russischen Puppe immer weiter verpackt
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1729435872741" ID="ID_965396577" MODIFIED="1729436935433" TEXT="am Ende entsteht ein Kokon aus verschachtelten Funktoren">
<arrowlink COLOR="#4a3bce" DESTINATION="ID_578956741" ENDARROW="Default" ENDINCLINATION="38;-27;" ID="Arrow_ID_757260520" STARTARROW="None" STARTINCLINATION="-301;14;"/>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1729436890414" ID="ID_578956741" MODIFIED="1729436925222" TEXT="Konstruktion">
<linktarget COLOR="#4a3bce" DESTINATION="ID_578956741" ENDARROW="Default" ENDINCLINATION="38;-27;" ID="Arrow_ID_757260520" SOURCE="ID_965396577" STARTARROW="None" STARTINCLINATION="-301;14;"/>
<icon BUILTIN="yes"/>
<node CREATED="1729436998673" ID="ID_346385163" MODIFIED="1729437009163" TEXT="ein PortBuilder-Aufruf...">
<node CREATED="1729437015821" ID="ID_1827103976" MODIFIED="1729437036910" TEXT="sammelt Parametrisierungs-Infos auf dem Heap"/>
<node CREATED="1729437072118" ID="ID_1502318976" MODIFIED="1729437092951" TEXT="erzeugt daraus am Ende einen frei stehenden Funktor"/>
<node CREATED="1729437157938" ID="ID_51881375" MODIFIED="1729437164285" TEXT="dieser Funktor....">
<node CREATED="1729437165393" ID="ID_1808951610" MODIFIED="1729437203258" TEXT="&#xfc;bernimmt die Parameter-Daten (Heap) in seine Closure"/>
<node CREATED="1729437400601" ID="ID_652398308" MODIFIED="1729437468463">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
bekommt (sp&#228;ter, zum Aufruf) einen <font face="Monospaced" color="#521102">DataBuilder</font><font face="Monospaced">&lt;</font><font color="#6512a3" face="Monospaced">Port</font><font face="Monospaced">&gt; </font><font color="#a00101" face="Monospaced">&amp;</font>
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1729437541143" ID="ID_1903771115" MODIFIED="1729437573712" TEXT="erzeugt die Several&lt;PortRef&gt; und Several&lt;BuffDescr&gt;"/>
<node CREATED="1729437575851" ID="ID_1476804159" MODIFIED="1729437614689" TEXT="baut daraus mit der ihm bekannten Processing-Function das Port-Objekt"/>
<node CREATED="1729437598455" ID="ID_1843090117" MODIFIED="1729437611869" TEXT="und zwar direkt per emplace in den ihm &#xfc;bergebenen DataBuilder"/>
</node>
</node>
<node CREATED="1729439566002" ID="ID_276705747" MODIFIED="1729439571179" TEXT="Aufruf-Verkettung">
<node CREATED="1729439577574" ID="ID_336716581" MODIFIED="1729439711347" TEXT="Trennung von Build-Funktor und Aufruf-Verkettung erscheint angezeigt">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...und zwar vor allem zur besseren Verst&#228;ndlichkeit und Wartbarkeit; da es sich um lauter nicht-virtuelle, direkte Aufrufe bekannter Funktionsdefinitionen handelt, kann der Optimiser jedweden Overhead problemlos entfernen
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1729440369548" ID="ID_1393003281" MODIFIED="1729445949689" TEXT="Es wird ein PatternData-Typ nach dem Zwiebelschalen-Prinzip aufgebaut">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
jeder sp&#228;tere Aufruf legt sich oben &#252;ber eine Vererbungs-Kette, wobei lokal ermittelte Gr&#246;&#223;en-Parameter der ben&#246;tigten Datenstruktur mit eingebettet werden; damit l&#228;&#223;t sich dann sp&#228;ter auch die erforderliche Gesamt-Gr&#246;&#223;e der Storage bestimmen, bevor das die Several-Collection selber gebaut wird (und das ist der Zweck des ganzen Unterfangens)
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1729440844373" ID="ID_1099183225" MODIFIED="1729441884421" TEXT="Problem Aufruf-Reihenfolge">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Hier tritt das bekannte Problem der umgekehrten Reihenfolge f&#252;r einfach verkettete Listen auf: das zuletzt hinzugef&#252;gte Element liegt zuoberst...
</p>
</body>
</html></richcontent>
<node COLOR="#5b280f" CREATED="1729442020752" ID="ID_250162620" MODIFIED="1729445590081" TEXT="L&#xf6;sung: Append an eine Typliste">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Man konstruiert einen (Meta)Typ f&#252;r den eigentlichen Aufruf, und verwendet das bereits implementierte Anh&#228;ngen an eine Typliste. Dieser Ansatz birgt zwei schwer absch&#228;tzbare Risiken
</p>
<ul>
<li>
die Compilation k&#246;nnte extrem lang dauern und ggfs sogar komplett scheitern, wenn es sehr viele Ports gibt
</li>
<li>
die Debug-Infos k&#246;nnten extrem aufgebl&#228;ht werden, falls f&#252;r jeden Zwischenschritt eine Typ-Info generiert wird; das ist besonders gef&#228;hrlich, da f&#252;r sehr viele Nodes jeweils andere konkrete Typen generiert werden (andere Processing-Function, abweichende Parameter). Das sieht nach einem sehr gef&#228;hrlichen Hebel aus!
</li>
</ul>
</body>
</html></richcontent>
<icon BUILTIN="stop-sign"/>
</node>
<node CREATED="1729441886482" ID="ID_717700960" MODIFIED="1729444821476" TEXT="L&#xf6;sung: nicht tail-rekursiver Aufruf">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
In der eigentlichen Invocation macht man einfach etwas vor und etwas nach dem rekursiven Aufruf. Gefahr: Stack-Overflow bei sehr vielen Ports (Ambisonics etc....)
</p>
</body>
</html></richcontent>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1729444822953" ID="ID_1145060657" MODIFIED="1729445566433" TEXT="KISS">
<icon BUILTIN="yes"/>
</node>
<node CREATED="1729444842118" ID="ID_1809031640" MODIFIED="1729445554172" TEXT="Gefahr vieler Ports anderweitig vermeiden">
<arrowlink COLOR="#ff2d4f" DESTINATION="ID_159630415" ENDARROW="Default" ENDINCLINATION="1388;-127;" ID="Arrow_ID_184854899" STARTARROW="None" STARTINCLINATION="-2248;146;"/>
<icon BUILTIN="yes"/>
</node>
</node>
</node>
</node>
</node>
<node CREATED="1728921324643" ID="ID_1723172951" MODIFIED="1728921332417" TEXT="das kann doch gar nicht funktionieren!"/>
</node>
</node>
</node>
@ -90931,6 +91322,45 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<linktarget COLOR="#e72c46" DESTINATION="ID_374254461" ENDARROW="Default" ENDINCLINATION="2123;-72;" ID="Arrow_ID_1323424774" SOURCE="ID_558040709" STARTARROW="None" STARTINCLINATION="-2473;168;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1729444885416" ID="ID_159630415" MODIFIED="1729445554173" TEXT="exzessiv viele Ports vermeiden">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Der Node-Build sammelt Parameterdaten f&#252;r jeden Port in einer verschachtelten Datenstruktur auf dem Heap, und arbeitet diese rekursiv ab; der so generierte Code ist sehr effizient (Optimiser), bedingt aber eine Limitierung auf eine kleine Anzahl an Ports
</p>
</body>
</html></richcontent>
<linktarget COLOR="#ff2d4f" DESTINATION="ID_159630415" ENDARROW="Default" ENDINCLINATION="1388;-127;" ID="Arrow_ID_184854899" SOURCE="ID_1809031640" STARTARROW="None" STARTINCLINATION="-2248;146;"/>
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1729445061304" HGAP="51" ID="ID_953179351" MODIFIED="1729445526986" TEXT="k&#xf6;nnte ein Problem darstellen f&#xfc;r HO-Ambisonics" VSHIFT="17">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
aber nur, falls wirklich Outputs f&#252;r einzelne Komponenten gerendert werden sollen
</p>
</body>
</html></richcontent>
<icon BUILTIN="clanbomber"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1729445134016" HGAP="35" ID="ID_17165416" MODIFIED="1729445530760" TEXT="Ausweg: Behandlung f&#xfc;r repetitiv-analoge Topologien" VSHIFT="-2">
<icon BUILTIN="idea"/>
<node CREATED="1729445245465" ID="ID_404840536" MODIFIED="1729445481127" TEXT="&#xbb;virtuelle Ports&#xab; auf Selektor-Paramter abbilden">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
es m&#252;&#223;te dann auf Ebene der Fixture die m&#246;glichkeit <i>Virtueller </i>oder <i>Iterativer Ports</i>&#160;geschaffen werden, ohne dort die Storage ausufern zu lassen; solche Ports m&#252;&#223;ten dann geeignet in die Aufruf-Parameter repr&#228;sentiert werden, so da&#223; das Turnout-System dann jeweils einen einzigen realen Port aktiviert, diesem aber einen iterativ generierten Selektor-Parameter auf dem Weg der Automation durchgibt, wodurch im Node-Graphen selber an geeigneter Stelle ein Kanal-Selektor bei ansonsten gleicher Verarbeitung koordiniert w&#252;rde. Die eigentliche Schwierigkeit bei diesem Ansatz liegt allerdings darin, da&#223; diese <i>komplexe und globale Struktur</i>&#160;im Builder <i>erkannt</i>&#160;und <i>transformiert</i>&#160; werden mu&#223;
</p>
</body>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1729445259863" ID="ID_1891578734" MODIFIED="1729445265857" TEXT="Ticket">
<icon BUILTIN="flag-pink"/>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1713824835597" ID="ID_1311484733" MODIFIED="1713825651947" TEXT="Dokumentation">