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:
parent
634df743f0
commit
b4aee6fba8
3 changed files with 536 additions and 66 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>>;
|
||||
|
||||
|
|
|
|||
|
|
@ -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=""Zugriff auf Core" 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äre dann: den Iterator zu verwenden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
denn das ist der sinnvollste Fall für ein generisches Lambda
|
||||
|
|
@ -9397,9 +9393,7 @@
|
|||
<node CREATED="1512951807371" ID="ID_1239289160" MODIFIED="1512951840907" TEXT="muß für diesen Fall selbständig terminieren"/>
|
||||
<node CREATED="1512951841703" ID="ID_815720383" MODIFIED="1512951903322" TEXT=""komplett entfaltet" 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ür <i>elided</i> 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> an einen Serivce
|
||||
|
|
@ -16989,9 +16977,7 @@
|
|||
<node CREATED="1487472730667" ID="ID_1826692985" MODIFIED="1518487921076" TEXT="kö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ätzlich klar">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
und funktioniert gut für Clip-Widgets auf der Timeline
|
||||
|
|
@ -50369,9 +50353,7 @@
|
|||
<icon BUILTIN="go"/>
|
||||
<node CREATED="1453545875627" ID="ID_1411740156" MODIFIED="1576282358001" TEXT="Definition »Zentral-Dienste«">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Dienste im UI, erreichbar ü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ß</i> Instanzen einsetzen
|
||||
|
|
@ -50874,9 +50854,7 @@
|
|||
<node CREATED="1488677350640" ID="ID_901346570" MODIFIED="1488677370377" TEXT="Ausführung im Dispatcher erst spä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ä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 übergeben?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
es könnte z.B. sein, daß man vom InteractionState
|
||||
|
|
@ -89593,8 +89567,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<font face="Monospaced" size="2">                                         ,void(array<char*,1>,array<char*,1>) >>></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:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
insofern verhält sich hier der Compiler<i> formal</i> und auch<i>  inhaltlich</i> <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:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<font color="#7407d7">MoveOnly</font> ◁— CONF  ◁— SimpleWeavingPattern  ◁— <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:   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:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Da ProcNodes regelmäßig auf ihre Leads per direkter Referenz zugreifen, mü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ß sich zwangsläufig von den Quellen durch den Graphen aufwä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="⟹ aber alles was im Builder auftritt ist potentiell gefährlich">
|
||||
|
|
@ -89707,8 +89676,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
»one-shot«-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:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Aufgrund der Komplexität der aufgebauten Strukturen ist nicht ersichtlich, ob der Compiler sich korrekt verhält; jedenfalls versucht er, den <b>Copy-Konstruktor</b> 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ü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:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
man müßte lediglich der build()-Methode explizit einen SeveralBuilder übergeben; das ließe sich sogar generalisieren auf etwas Generisches, das eine emplace()-Methode bietet; in erster Näherung (C++17) wä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 »Hintertür« funktioniert nur für die aktuell neueste Allokation">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -89794,8 +89761,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
mit »Hintertür« meine ich die Fähigkeit zum dynamischen Wachsen der Allokation speziell im Allocation-Cluster; das ist leicht mö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ösungen">
|
||||
|
|
@ -89831,7 +89797,7 @@ Date:   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ürde man sich dann am Abgrund bewegen">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1728920893861" ID="ID_563974492" MODIFIED="1728920908958" TEXT="Port wü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ß man aber wissen...">
|
||||
|
|
@ -89842,8 +89808,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
jedermann könnte jederzeit Port-Referenzen in anderen Umgständen erzeugen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -89860,15 +89825,441 @@ Date:   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 ≡ E ≔ 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="„sollte doch“ einen Turnout liefern"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1728921453763" ID="ID_1928466246" MODIFIED="1728921475471" TEXT="ich hätte erwartet, daß SeveralBuilder das aufgreift">
|
||||
<node COLOR="#5b280f" CREATED="1728921453763" ID="ID_1928466246" MODIFIED="1729302438858" TEXT="ich hätte erwartet, daß 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 ≔ Port — aber E würde in der DataBuilder-Definition gesetzt">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1729301399630" HGAP="36" ID="ID_1796030895" MODIFIED="1729301469234" TEXT="kann also niemals „aufgegriffen werden“" 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="»Turnout« 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> <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ßerdem aus konzeptionellen Gründen: es soll ja ein Extension-Point sein, also können wir eigentlich nichts über diesen Typ sagen
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1729300229244" ID="ID_1033505516" MODIFIED="1729300559466" TEXT="⟹ bereits das erste Element bewirkt lock_move"/>
|
||||
<node CREATED="1729300518732" ID="ID_735942887" MODIFIED="1729300563498" TEXT="⟹ das erste Element legt auch endgü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ß sofort ausreichend bestimmt sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
wenn später in der Sequenz eine größere FeedManifold gebraucht wird, läß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ß sofort ausreichend dimensioniert sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...weil kein realloc() möglich ist; zudem muß auch die Extent-Größ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ück kommen,</i>  dann kö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 »dynamische Belegung«
|
||||
</p>
|
||||
<p style="text-align: center">
|
||||
ist unter den vorgegebenen Beschrä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ü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ß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ösungen unterliegen den strengeren Beschränkungen bezüglich der Allokation; das hat aber auch den Vorteil, daß man diese Entscheidung rein auf Basis der sonstigen Vor- und Nachteile abwägen und treffen kann
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1729302635570" ID="ID_1269287328" MODIFIED="1729302815670" TEXT="Maßgabe: die Offenheit des Builders ist zu erhalten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Es besteht die Gefahr, daß fü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ü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ösung aus, daß der Client die benötigten Daten »vordimensioniert«">
|
||||
<icon BUILTIN="closed"/>
|
||||
</node>
|
||||
<node CREATED="1729302940255" ID="ID_1001603416" MODIFIED="1729302987650" TEXT="der Build-Vorgang muß 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ß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ür alle <i>problematischen Daten-Builder</i> gilt.....
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
»problematisch« sind alle Daten-Builder, die
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
mit heterogenen Objekten belegt werden
|
||||
</li>
|
||||
<li>
|
||||
und für die die Objekte nicht<i> trivially copyable</i> sind
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1729303223690" ID="ID_1668152159" MODIFIED="1729303249893" TEXT="vor Belegen des ersten Datenelements muß eine automatische Dimensionierung erfolgen"/>
|
||||
</node>
|
||||
<node CREATED="1729305640248" ID="ID_1661765820" MODIFIED="1729305648785" TEXT="Analyse der Einzelvorgä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äge(≙Turnouts) mü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ären: wo werden die Weaving-Pattern-Parameter zwischengespeichert?"/>
|
||||
<node CREATED="1729306296341" ID="ID_1639896665" MODIFIED="1729306365760" TEXT="bisherige Lösung: PortBuilder als eine temporä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üßte lediglich das Several für die leadPorts in die build()-Funktion schieben"/>
|
||||
</node>
|
||||
<node CREATED="1729307297963" ID="ID_943373598" MODIFIED="1729307309144" TEXT="abschließender Schritt">
|
||||
<node CREATED="1729307313017" ID="ID_1049380221" MODIFIED="1729307344813" TEXT="demnach müßte das Konstruieren des Turnout auf später verschoben werden"/>
|
||||
<node CREATED="1729307349538" ID="ID_377799822" MODIFIED="1729307371229" TEXT="damit ist aber weitere Storage notwendig für die Dateninhalte">
|
||||
<node CREATED="1729307384804" ID="ID_1867864484" MODIFIED="1729307391302" TEXT="Several<PortRef>"/>
|
||||
<node CREATED="1729307392664" ID="ID_1001735525" MODIFIED="1729307415447" TEXT="Several<BuffDescr>"/>
|
||||
<node CREATED="1729307446488" ID="ID_457436977" MODIFIED="1729307460312" TEXT="N (Größ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ürde damit die Dateninhalte auf dem Stack sammeln"/>
|
||||
<node CREATED="1729307669041" ID="ID_1469484154" MODIFIED="1729307806096" TEXT="allerdings muß dann auch die Port-Erzeugung Tail-rekursiv geschrieben werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Man würde sich damit von dem vertrauten und klaren Builder-API verabschieden, und stattdessen ein Aufrufmuster verwenden, welches von mindestens der Hälfte aller Programmierer als „schwierig“ empfunden wird. Und zwar rein aus Gründen der Implementierungs-Mechanik; nach der inhaltlichen Logik wä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<PortRef>,Several<BuffDescr>, 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ögerte terminal-build-Operation
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1729434345618" ID="ID_31768721" MODIFIED="1729434364792" TEXT="damit wird diese Lösung ihä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' bereits eine Type-Erasure machen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
denn der konkrete Funktionstyp und das N (≙Manifold-Größe), sowie ggfs. ein alternativer »InvocationAdapter«-Typ sind zunächst im konkreten Typ des PortBuilders angelegt (als Typ-Kontext); das bedeutet, das Parameter-Tupel muß aus lauter Wrappern bestehen, die die konkreten Typen bereits materialisiert und virtualisiert enthalten. Fü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ä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ß des Build-Vorganges ist lediglich eine Verzö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ü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 »abgeworfen«
|
||||
</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ß 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är auf dem Stack">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1729434130348" ID="ID_1796646662" MODIFIED="1729434165322" TEXT="muß size-Info weitergeben ⟹ Funktor allein genügt nicht">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1729435375920" ID="ID_232356982" MODIFIED="1729435650306" TEXT="damit bleibt nur eine rekursive funktionale Datenstruktur übrig">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...zwar könnte man jetzt wieder ein Tupel machen, in das den Builder-Functor legen und zusätzliche Steuer-Infos; diese Tupel würden dann in eine Collection auf dem Heap gehen und dort iteriert. Das wäre (scheinbar) simpel, aber nicht einfach und klar. Deshalb bleibt für mich als einzige Alternative, die notwendigen Schrite unmittelbar in eine verkettete Aufrufstruktur zu packen. Das ist dann zwar zunächst fordernd für den Leser (aber das ist die Implementierung des Builders sowiso schon); aber immerhin erschließt sich der Sinn unmittelbar lokal im jeweiligen Aufruf — genauer gesagt, man kann direkt beim lokalen Aufruf den Sinn in einem Kommentar erlä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> 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 äußeren Stack-Frame, welcher das Builder-API aufruft; sie werden jeweils für einen Aufruf in den nächsten Stack-Frame geschoben, und dann wieder zurü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="ü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äter, zum Aufruf) einen <font face="Monospaced" color="#521102">DataBuilder</font><font face="Monospaced"><</font><font color="#6512a3" face="Monospaced">Port</font><font face="Monospaced">> </font><font color="#a00101" face="Monospaced">&</font>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1729437541143" ID="ID_1903771115" MODIFIED="1729437573712" TEXT="erzeugt die Several<PortRef> und Several<BuffDescr>"/>
|
||||
<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 ü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ä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ätere Aufruf legt sich oben über eine Vererbungs-Kette, wobei lokal ermittelte Größen-Parameter der benötigten Datenstruktur mit eingebettet werden; damit läßt sich dann später auch die erforderliche Gesamt-Größ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ür einfach verkettete Listen auf: das zuletzt hinzugefügte Element liegt zuoberst...
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node COLOR="#5b280f" CREATED="1729442020752" ID="ID_250162620" MODIFIED="1729445590081" TEXT="Lösung: Append an eine Typliste">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Man konstruiert einen (Meta)Typ für den eigentlichen Aufruf, und verwendet das bereits implementierte Anhängen an eine Typliste. Dieser Ansatz birgt zwei schwer abschätzbare Risiken
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
die Compilation könnte extrem lang dauern und ggfs sogar komplett scheitern, wenn es sehr viele Ports gibt
|
||||
</li>
|
||||
<li>
|
||||
die Debug-Infos könnten extrem aufgebläht werden, falls für jeden Zwischenschritt eine Typ-Info generiert wird; das ist besonders gefährlich, da für sehr viele Nodes jeweils andere konkrete Typen generiert werden (andere Processing-Function, abweichende Parameter). Das sieht nach einem sehr gefährlichen Hebel aus!
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node CREATED="1729441886482" ID="ID_717700960" MODIFIED="1729444821476" TEXT="Lö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:   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ü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önnte ein Problem darstellen für HO-Ambisonics" VSHIFT="17">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
aber nur, falls wirklich Outputs fü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ür repetitiv-analoge Topologien" VSHIFT="-2">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1729445245465" ID="ID_404840536" MODIFIED="1729445481127" TEXT="»virtuelle Ports« auf Selektor-Paramter abbilden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
es müßte dann auf Ebene der Fixture die möglichkeit <i>Virtueller </i>oder <i>Iterativer Ports</i> geschaffen werden, ohne dort die Storage ausufern zu lassen; solche Ports müßten dann geeignet in die Aufruf-Parameter repräsentiert werden, so daß 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ürde. Die eigentliche Schwierigkeit bei diesem Ansatz liegt allerdings darin, daß diese <i>komplexe und globale Struktur</i> im Builder <i>erkannt</i> und <i>transformiert</i>  werden muß
|
||||
</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">
|
||||
|
|
|
|||
Loading…
Reference in a new issue