diff --git a/src/steam/engine/exit-node.hpp b/src/steam/engine/exit-node.hpp index d595b27a7..bf73ebb72 100644 --- a/src/steam/engine/exit-node.hpp +++ b/src/steam/engine/exit-node.hpp @@ -58,7 +58,7 @@ namespace engine { * @warning ExitNode should ideally be NonCopyable, since it is referred by the JobTicket * However, we need to clone-and-remould Segments (Split-Splice-Algo), and this implies * that the render nodes can be shared among multiple Segments. If all these assessments - * are correct an only be decided when the actual memory management is settled. + * are correct can only be decided when the actual memory management is settled. */ class ExitNode : util::Cloneable diff --git a/src/steam/engine/render-invocation.cpp b/src/steam/engine/render-invocation.cpp index 1f4e76053..3f9d0878e 100644 --- a/src/steam/engine/render-invocation.cpp +++ b/src/steam/engine/render-invocation.cpp @@ -15,19 +15,22 @@ /** @file render-invocation.cpp ** Implementation details regarding the invocation of a single render node ** @deprecated very likely to happen in a different way, while the concept remains valid - ** @todo unfinished draft from 2009 regarding the render process + ** @todo WIP-WIP-WIP 12/2024 about to build a Render Node invocation, combining the old + ** unfinished draft from 2009 with the new Render Engine code */ -#include "steam/engine/render-invocation.hpp" #include "steam/engine/turnout-system.hpp" +#include "steam/engine/render-invocation.hpp" + + +using vault::gear::JobParameter; namespace steam { namespace engine { namespace { // Details... - } // (END) Details... @@ -36,20 +39,36 @@ namespace engine { // using mobject::session::Effect; + string + RenderInvocation::diagnostic() const + { + return "TODO ... what can the ExitNode tell us here?"; ///////////////////////////////////////////////TICKET #1367 : once we have a working draft of a node invocation, it should be possible to retrieve some Node-Spec here... + } + + InvocationInstanceID + RenderInvocation::buildInstanceID (HashVal) const + { + return InvocationInstanceID(); //////////////////////////////////////////////////////TICKET #1278 : so what do we need here for real, finally? + } + + size_t + RenderInvocation::hashOfInstance (InvocationInstanceID invoKey) const + { ////////////////////////////////////////////////TICKET #1295 : settle upon the parameters actually needed and decide what goes into this hash + std::hash hashr; + HashVal res = hashr (invoKey.frameNumber); + return res; + } + + /** @note this builds a one-way off invocation state context * and then forwards the call; this may or may not cause * actual calculations, depending on the cache. - * @todo for real use within the engine, the pull()-call should be - * dispatched through the scheduler; of course then the call semantics - * would be completely different. Maybe this invocation will be test only? */ - BuffHandle - RenderInvocation::operator[] (size_t channel) - { - REQUIRE (theNode_); - REQUIRE (channel < size()); + void + RenderInvocation::invokeJobOperation (JobParameter invoParam) + { ////////////////////////////////////////////////TICKET #905 : yess.... finally DO IT + UNIMPLEMENTED ("how to »doIt«"); - StateProxy invocationState; #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation return theNode_->pull(invocationState, channel); #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation diff --git a/src/steam/engine/render-invocation.hpp b/src/steam/engine/render-invocation.hpp index 91a35598b..cda2793a4 100644 --- a/src/steam/engine/render-invocation.hpp +++ b/src/steam/engine/render-invocation.hpp @@ -15,11 +15,12 @@ ** Initiate a single calculation unit within the renderengine. ** Usually, this will cause the rendering of a single frame or sub-frame. ** - ** @todo unfinished draft from 2009 regarding the render process + ** @todo WIP-WIP-WIP 2024-12 finally about to connect the unfinished draft from 2009 + ** with the engine structures built bottom-up meanwhile ///////////////////////////////////////////TICKET #905 : Work out what parameters are required to invoke the real code available now.... ** ** @see engine::ProcNode - ** @see StateClosure - ** @see node-basic-test.cpp + ** @see turnout-system.hpp + ** @see NodeBasic_test ** */ @@ -27,11 +28,9 @@ #define ENGINE_RENDER_INVOCATION_H -//#include "steam/engine/state-closure.hpp" -//#include "steam/engine/proc-node.hpp" ///////////////////////////////TODO clarify if required further on -#include "steam/engine/connectivity-obsolete.hpp" -#include "steam/engine/buffhandle.hpp" -//#include "steam/engine/bufftable-obsolete.hpp" +#include "vault/gear/job.h" +#include "steam/engine/proc-node.hpp" +//#include "steam/engine/buffhandle.hpp" @@ -41,32 +40,37 @@ namespace engine { /** + * A concrete JobFunctor with the ability to activate the »Render Node Network«. * @todo write type comment + * @warning WIP-WIP 2024-12 rework render node invocation for »Playback Vertical Slice« */ class RenderInvocation + : public vault::gear::JobClosure ////////////////////////////////////////////////TICKET #1287 : should inherit from JobFunctor, get rid of the C-isms { - ProcNode* theNode_; + ProcNode& theNode_; - public: - RenderInvocation (ProcNode* exitNode) - : theNode_(exitNode) + + /* === JobFunctor Interface === */ + + JobKind + getJobKind() const override { - REQUIRE (theNode_); + return CALC_JOB; } - size_t size() { return theNode_->nrO(); } - - /** pull calculated data from the N-th node output channel */ - BuffHandle operator[] (size_t channel); + string diagnostic() const override; + InvocationInstanceID buildInstanceID (HashVal) const override; //////////////////////////////////TICKET #1278 : so what do we need here for real, finally? + size_t hashOfInstance (InvocationInstanceID invoKey) const override; + void invokeJobOperation (vault::gear::JobParameter); + public: + RenderInvocation (ProcNode& exitNode) + : theNode_(exitNode) + { } }; - ///////////////////////////////////TODO: currently just fleshing out the API - - - }} // namespace steam::engine diff --git a/src/steam/engine/turnout-system.cpp b/src/steam/engine/turnout-system.cpp index 4181319aa..3185a2750 100644 --- a/src/steam/engine/turnout-system.cpp +++ b/src/steam/engine/turnout-system.cpp @@ -35,51 +35,6 @@ namespace engine { /** @internal */ - BuffHandle - StateProxy::allocateBuffer (const lumiera::StreamType*) - { - UNIMPLEMENTED ("allocate a suitable buffer to hold a frame of the denoted type"); - } - - - - void - StateProxy::releaseBuffer (BuffHandle& bh) - { - UNIMPLEMENTED ("free a buffer"); - } - - - - BuffHandle - StateProxy::fetch (FrameID const& fID) - { - UNIMPLEMENTED ("fetch a buffer with input data"); - } - - - - void - StateProxy::is_calculated (BuffHandle const& bh) - { - UNIMPLEMENTED ("declare a buffer as fully calculated and done"); - } - - - - FrameID const& - StateProxy::genFrameID (NodeID const&, uint chanNo) - { - UNIMPLEMENTED ("derive/generate an ID to denote this specific fame+Node position in the graph"); - } - - - - BuffTableStorage& - StateProxy::getBuffTableStorage() /////////////TODO need somehow to denote the specific storage requirements - { - UNIMPLEMENTED ("allocate a chunk of storage suitable for holding the buffer pointer tables"); - } }} // namespace engine diff --git a/src/steam/engine/turnout-system.hpp b/src/steam/engine/turnout-system.hpp index 591d0c609..1561ce0a2 100644 --- a/src/steam/engine/turnout-system.hpp +++ b/src/steam/engine/turnout-system.hpp @@ -13,14 +13,22 @@ /** @file turnout-system.hpp - ** Access point to the state of a frame rendering evaluation. - ** The rendering of frames is triggered from a render job, and recursively - ** retrieves the data from predecessor nodes. Some statefull aspects are involved - ** into this recursive evaluation, beyond the data in the local call stack. Such - ** additional statefull dependencies are problematic (regarding concurrency and - ** throughput) and are thus abstracted from the actual processing operations - ** with the help of the steam::engine::StateClosure interface - ** @todo unfinished draft from 2009 regarding the render process + ** THe actual state of a frame rendering evaluation parametrised for a single job. + ** The rendering of frames is triggered from a render job, and recursively retrieves the data + ** from predecessor render nodes, prepared, configured and interconnected by the Builder. + ** Some statefull aspects can be involved into this recursive evaluation, beyond the data + ** passed directly through the recursive calls and interconnected data buffers. Notably, + ** some operations need direct call parameters, e.g. the frame number to retrieve or + ** the actual parametrisation of an effect, which draws from _parameter automation._ + ** Moreover, when rendering interactively, parts of the render pipeline may be + ** changed dynamically by mute toggles or selecting an output in the viever's + ** _Switch Board. + ** + ** The TurnoutSystem is related to the actual incidence and is created dynamically, + ** while connecting to all the existing \ref Turnout elements sitting in the render node ports. + ** It acts as mediator and data exchange hub, while gearing up the actual invocation to cause + ** calculation of media data in the render nodes connected below + ** @todo WIP-WIP-WIP 12/2024 now combining the draft from 2009 / 2012 with recent engine development */ @@ -28,8 +36,7 @@ #define STEAM_ENGINE_TURNOUT_SYSTEM_H -//#include "steam/engine/proc-node.hpp" /////////////////////OOO dependency cycle ProcNode <-> TurnoutSystem -#include "steam/engine/state-closure.hpp" +#include "steam/engine/state-closure.hpp" /////////////////////OOO will take on a different role (if any) /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation @@ -38,30 +45,12 @@ namespace engine { -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - class StateProxy - : public StateClosure - { - - private: /* === top-level implementation of the StateClosure interface === */ - - BuffHandle allocateBuffer (const lumiera::StreamType*); //////////////////////////TICKET #828 - - void releaseBuffer (BuffHandle& bh); - - BuffHandle fetch (FrameID const& fID); - - void is_calculated (BuffHandle const& bh); - - FrameID const& genFrameID (NodeID const&, uint chanNo); - - BuffTableStorage& getBuffTableStorage(); - - virtual StateClosure& getCurrentImplementation () { return *this; } - - }; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - + /** + * Communication hub to coordinate and activate the »Render Node Network« performance. + * An instance will be created on the stack for each evaluation of a [render job](\ref RenderInvocation). + * It provides access to common invocation parameters, an extension system to register further _data slots,_ + * and initiates the recursive pull()-call into the render node network as attached for this call. + */ class TurnoutSystem /////////////////////////////////////////OOO von wo erbt das?? laut ursprünglichem Konzept von StateClosure ... bin mir aber nicht mehr sicher { diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp index be242493b..195dc3d1f 100644 --- a/src/steam/engine/weaving-pattern-builder.hpp +++ b/src/steam/engine/weaving-pattern-builder.hpp @@ -350,6 +350,20 @@ namespace engine { using SimpleDirectInvoke = SimpleWeavingPattern>; + /** + * A low-level Builder to prepare and adapt for a specific node invocation. + * In this context, »weaving« refers to the way parameters and results of an + * processing function are provided, combined and forwarded within the setup + * for an actual Render Node invocation. When the invocation happens, a kind + * of preconfigured _blue print_ or invocation plan is executed; the purpose + * of the build at »Level-2« (≙the purpose of this code) is to preconfigure + * this invocation scheme. Using a _low level builder_ as controlled by the + * actual NodeBuilder and PortBuilder allows to introduce extension points + * and helps to abstract away internal technical details of the invocation. + * @tparam POL allocation and context configuration policy + * @tparam N maximum number of input and output slots + * @tparam FUN function or invocation adapter to invoke + */ template struct WeavingBuilder : util::MoveOnly diff --git a/tests/46node.tests b/tests/46node.tests index 0a3f0c391..adb2f6c99 100644 --- a/tests/46node.tests +++ b/tests/46node.tests @@ -6,6 +6,10 @@ PLANNED "Proc Node basics" NodeBasic_test < + +  **Lumiera** is free software; you can redistribute it and/or modify it +  under the terms of the GNU General Public License as published by the +  Free Software Foundation; either version 2 of the License, or (at your +  option) any later version. See the file COPYING for further details. + +* *****************************************************************/ + +/** @file node-builder-test.cpp + ** unit test \ref NodeBuilder_test + */ + + +#include "lib/test/run.hpp" +#include "steam/engine/node-builder.hpp" +//#include "lib/util.hpp" + + +using std::string; + + +namespace steam { +namespace engine{ +namespace test { + + + + + /***************************************************************//** + * @test creating and configuring various kinds of render nodes. + */ + class NodeBuilder_test : public Test + { + virtual void + run (Arg) + { + UNIMPLEMENTED ("build and wire some render nodes"); + } + }; + + + /** Register this test class... */ + LAUNCHER (NodeBuilder_test, "unit node"); + + + +}}} // namespace steam::engine::test diff --git a/tests/core/steam/engine/node-devel-test.cpp b/tests/core/steam/engine/node-devel-test.cpp index d51b50c64..9794587f7 100644 --- a/tests/core/steam/engine/node-devel-test.cpp +++ b/tests/core/steam/engine/node-devel-test.cpp @@ -268,9 +268,12 @@ namespace test { } + /** @test demonstrate simple usage of test-render setup * - access the TestRandOntology as singleton * - create a Spec record + * - retrieve a functor bound suitably to invoke + * data processing code from the TestRandOntology */ void testRand_simpleUsage() diff --git a/tests/core/steam/engine/node-factory-test.cpp b/tests/core/steam/engine/node-factory-test.cpp index 00c0bb4c9..a74984b9f 100644 --- a/tests/core/steam/engine/node-factory-test.cpp +++ b/tests/core/steam/engine/node-factory-test.cpp @@ -13,6 +13,9 @@ /** @file node-factory-test.cpp ** unit test \ref NodeFactory_test + ** @todo 12/2024 this test will focus on the high-level integration, + ** which is future work and possibly addressed in the next »Vertical Slice« + ** when we add processing of a given media clip from disk. */ @@ -35,10 +38,11 @@ namespace test { */ class NodeFactory_test : public Test { - virtual void run(Arg) + virtual void + run (Arg) { UNIMPLEMENTED ("build and wire some render nodes"); - } + } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 8e12e2634..5f7fae6c5 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -1,6 +1,6 @@ - + @@ -20425,9 +20425,7 @@ - - - +

InteractionControl @@ -20806,9 +20804,7 @@ - - - +

Jeder neue TrackPresenter bekommt zur Erzeugung einen Funktor, mit dem sich der von ihm gehaltene DisplayFrame in einen Vater-Kontext "einhäkeln" kann... @@ -21233,9 +21229,7 @@ - - - +

...sondern zur Timeline gehört @@ -21931,9 +21925,7 @@ - - - +

...hab mich davon überzeugt, daß die Namen anders herum verwendet werden sollten. @@ -23016,9 +23008,7 @@ - - - +

und zwar interessanterweise über Kreuz gegliedert @@ -24615,9 +24605,7 @@ - - - +

Invariante: (nach dem Pass) liegen vorläufig/hinreichend brauchbare Layout-Maße vor @@ -28216,9 +28204,7 @@ - - - +

dpi-Wert für aktuellen Screen herausfinden GTK ⟵ GDK @@ -34804,9 +34790,7 @@ - - - +

es geht nur um Rollen @@ -39000,9 +38984,7 @@ - - - +

typischerweise liefern die low-level-Events gerätespezifische Koordinaten ab, und deren Übersetzung in die Modell/Domänenwerte erfordert Hilfsmittel, die man sich mehrstufig beschaffen muß. Da aber die einzelnen Events unverbunden daherkommen, muß die Verarbeitung vereinzelt erfolgen. Und das heißt, man leistet diesen Einrichtungs-Aufwand für jedes einzelne Event; dies geht zu Lasten der »Reaktivität« @@ -40308,9 +40290,7 @@ - - - +

Liegt in unserem gui::model @@ -40964,9 +40944,7 @@ - - - +

das bedeutet: genau durch diese Abrundung auf den nächst kleineren µTick könnten wir u.U einen Pixel verlieren @@ -41640,9 +41618,7 @@ - - - +

gelöst durch geschickte schrittweise Berechnung: @@ -41975,9 +41951,7 @@ - - - +

Fazit: @@ -42268,9 +42242,7 @@ - - - +

das unterschlägt den Divisionsrest. Oder anders gesagt, die Integer-Division ist keine lineare Funktion, die man einfach so umkehren kann @@ -81550,7 +81522,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -83009,6 +82981,23 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + +

+ weil sie ja tatsächlich als Brücke fungiert und Daten einspeist, die jenseits der normalen Aufruf-Hierarchie über das Turnout-System vermittelt werden +

+ +
+
+
+ + @@ -83623,12 +83612,24 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + - + + + @@ -83712,6 +83713,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + @@ -87262,30 +87267,30 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - - - - - - + + + + - - - + + + - - + + + + - - + + @@ -87326,7 +87331,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -87336,13 +87341,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + - + + + + + + + + + @@ -87424,18 +87437,24 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + +
- - + + + + @@ -87506,9 +87525,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + - + @@ -87550,6 +87571,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ @@ -87658,8 +87680,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - +
@@ -87695,6 +87716,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ @@ -87928,7 +87950,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -87937,6 +87959,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

+
@@ -88122,6 +88145,25 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + +

+ ...das ein bestimmtes Schema für Funktionsaufrufe und Buffer-Arrays fest vorgibt; damit kann dann auch die FeedManifold Teil des InvocationAdapters werden und beide zusammen liegen beim Aufruf im Stack-Frame +

+ + +
+
+ + + +
@@ -88205,6 +88247,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ @@ -88226,12 +88269,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- +

- ...man könnte ein System von nested scopes aufbauen, auf Basis einer persistenten Datenstruktur. Es ist aber noch nicht klar, ob soetwas jemals gebraucht wird (YAGNI); im Besonderen bräuchte man dann auch einen Propagations-Mechanismus für Bindings, und damit wird die Sache komplex und potentiell aufwendig. Als ein anderes Modell könnte man lediglich einen Verweis auf einen Key-Value-Store durchgeben, der dann auf dem Einstiegs-Stackframe liegen würde. Und als minimal-Version würden wir nur einen Koordinaten-Record per Funktionsparameter nach unten durchreichen — bräuchten dann aber einen offband-channel  um Muting und Aktivierungen (z.B. Switchboard) durchzugeben; letztere müssen übrigens auf Ebene der Job-Invocation atomar aufgegriffen werden (wie genau ist noch nicht klar) + ...man könnte ein System von nested scopes aufbauen, auf Basis einer persistenten Datenstruktur. Es ist aber noch nicht klar, ob soetwas jemals gebraucht wird (YAGNI); im Besonderen bräuchte man dann auch einen Propagations-Mechanismus für Bindings, und damit wird die Sache komplex und potentiell aufwendig. Als ein anderes Modell könnte man lediglich einen Verweis auf einen Key-Value-Store durchgeben, der dann auf dem Einstiegs-Stackframe liegen würde. Und als minimal-Version würden wir nur einen Koordinaten-Record per Funktionsparameter nach unten durchreichen — bräuchten dann aber einen out-of-band-channel um Muting und Aktivierungen (z.B. Switchboard) durchzugeben; letztere müssen übrigens auf Ebene der Job-Invocation atomar aufgegriffen werden (wie genau ist noch nicht klar)

@@ -88247,13 +88290,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + +
@@ -88263,7 +88309,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + + @@ -88467,6 +88518,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + +

+ also einfach ein Zugriff via lib::Depend<Service> +

+ +
+
+ + + +
@@ -88484,9 +88550,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + +

+ welcher hiermit nur noch über eine virtuelle Methode weave() zur Laufzeit eingebunden ist +

+ + +
+
@@ -88507,12 +88585,37 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + +

+ ...wäre demnach ehr eine Hintertür im Design +

+ + +
+
+
+ + + + + +
+ @@ -88521,10 +88624,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + + @@ -88793,7 +88897,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -89055,8 +89159,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -89145,7 +89249,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

- sich nicht verrückt machen: das hier ist ein hermeneutischer Zirkel: Um ein gutes Werkzeug bauen zu können, muß ich die Sache  verstehen — und das mache ich, indem ich auf den Werkzeuggebrauch hin stipuliere + sich nicht verrückt machen: das hier ist ein hermeneutischer Zirkel: Um ein gutes Werkzeug bauen zu können, muß ich die Sache verstehen — und das mache ich, indem ich auf den Werkzeuggebrauch hin stipuliere

@@ -89210,8 +89314,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -89640,9 +89744,19 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + - - + + + + + + + + + + @@ -89714,7 +89828,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

- Unabhängig davon, welche der drei vorgenannten Lösungen zum Zuge kommt, gibt es steths noch eine weitere, komplexere Variante, die aber sehr attraktiv erscheint: es ist nämlich in den weitaus meisten Fällen so, daß nur ein einziger, einheitlicher Buffer-Typ zum Einsatz kommt; daher läuft das Belegen eines Array mit einem expliziten Deskriptor für jeden »Slot« auf erhebliche Speicherverschwendung hinaus. Stattdessen könnte man versucht sein, die Belegung durch ein Stück Code machen zu lassen (eine Closure), und dafür eine Meta-Spec zu interpretieren. Das wird aber in jedem Fell recht komplexer Code, der dann auch zur Render-Zeit läuft (ja wirklich, in jedem Aufruf), und deshalb wieder das Problem aufwirft, woher man die Storage für temporäre Datenstrukturen nimmt. Denn solche wird es zwingend geben, schließlich muß man ja irgendwie markieren, was die bereits behandelten Spezialfälle sind, und welche »Slots« damit übrig bleiben und mit dem Standard-Fall behandelt werden müssen. Ja mei! + Unabhängig davon, welche der drei vorgenannten Lösungen zum Zuge kommt, gibt es stets noch eine weitere, komplexere Variante, die aber sehr attraktiv erscheint: es ist nämlich in den weitaus meisten Fällen so, daß nur ein einziger, einheitlicher Buffer-Typ zum Einsatz kommt; daher läuft das Belegen eines Array mit einem expliziten Deskriptor für jeden »Slot« auf erhebliche Speicherverschwendung hinaus. Stattdessen könnte man versucht sein, die Belegung durch ein Stück Code machen zu lassen (eine Closure), und dafür eine Meta-Spec zu interpretieren. Das wird aber in jedem Fell recht komplexer Code, der dann auch zur Render-Zeit läuft (ja wirklich, in jedem Aufruf), und deshalb wieder das Problem aufwirft, woher man die Storage für temporäre Datenstrukturen nimmt. Denn solche wird es zwingend geben, schließlich muß man ja irgendwie markieren, was die bereits behandelten Spezialfälle sind, und welche »Slots« damit übrig bleiben und mit dem Standard-Fall behandelt werden müssen. Ja mei!

@@ -89746,7 +89860,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -90341,7 +90456,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -92960,6 +93075,34 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -93472,7 +93615,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -93747,6 +93891,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + +
@@ -93786,7 +93941,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -93800,6 +93955,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ @@ -93851,6 +94007,53 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + +

+ welches jedoch stimmig sein muß +

+ +
+ +
+
+
+ + + + + + + + + + + + + + + + @@ -93859,11 +94062,618 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + + + + + + + + + + + + + + +

+ Also explizit für Kern-Funktionalität; das wäre ein naheliegender Lösungsansatz, der sich gewissermaßen unter der Struktur der Feed-Manifold »durchgräbt«. Hierzu würde man spezielle Buffer vereinbaren, in denen ein Adapter-Typ liegt, der dann irgendwie mit den Parametern versorgt wird. +

+

+ +

+

+ Besonders fragwürdig ist die hohe Komplexität, und auch die Indirektion, die über mehrere Level des Builders hinweg durchgereicht werden muß +

+ + +
+ +
+ + + + +

+ elegant, weil nichts gemacht wird an einer Stelle an der ohnehin nichts zu tun ist — denn die eigentliche Logik liegt auf Level-3 +

+

+ effizient, denn Buffer-Speicher wird gepoolt und damit gute Chancen auf Cache-Locality +

+ + +
+
+ + + + +

+ die bisher bedachten Strukturen sind auf die Datenströme ausgerichtet — es wäre ungeschickt, hier explizit etwas zur Parameterversortung einzurichten; vielmehr kann der Apekt der Berechnungs-Verknüpfung hier mit abgebildet werden, aber die eigentliche Ansteuerung muß von der Invocation ausgehen, und kann daher nur durch das Turnout-System laufen, welches hierdurch seinen bisher nur abstrakt gefaßten Sinn bekommt. +

+ + +
+
+ + + + +

+ Ein Teil der Parameter-Berechnung ist wohl spezifisch für den Einzelfall und gehört damit sinnigerweise in eine Node; diese wird aber speziell aufgebaut und direkt mit dem Turnout-System verbunden; letzteres wurde durch diese Überlegungen nun konkretisiert und wird verstanden als Mediator für den Austausch von Parameter-Daten; die ParamAgent-Node stellt damit die Brücke dar ⟹ folglich muß eine Test-Spec auch die Möglichkeit mit einschließen, solche ParamAgent-Nodes zu erzeugen +

+ +
+
+
+
+ + + + +

+ da drücke ich mich schon seit Jahren drum +

+ + +
+ + + + + + + + + + + + + + +

+ »geliefert« ist das Wort das diese Debatte klärt +

+ + +
+ + + +

+ Hier im Rahmen der Render-Engine wird nach einem einheitlichen Webemuster vorgegangen: die Berechnung erfolgt lazy und schreitet in Wellen von der Quelle in Richtung des Resultats fort. Und, ganz wichtig, die Berechnungen sind hochgradig concurrent. Deshalb muß jedweder intemediäre Berechnungszustand externalisiert werden — wir brauchen Storage, die in Buffern organisiert ist und jweils für eine Node-Invocation bereitgestellt wird. Daher muß ein Berechnungsergebnis stets irgendwo abgestellt werden — und das heißt, es fällt als Wert an. +

+ + +
+
+
+ + + + + + + + + + + + + + + + +

+ als Funktion der nominal Time +

+ + +
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + +

+ Es ist eine ungeklärte Frage, ob Abkürzungen in der Render-Engine sinnvoll sind. Diese Frage kann nur empirisch geklärt werden, und vermutlich niemals abschließend. Erfahrung im high-Performance-Computing zeigt, daß Schematisierung oft der Einzelfallbehandlung überlegen ist — es sei denn, der Einzelfalls stellt selbst ein Schema dar +

+ + +
+
+ + + + + + + + + + + + + +

+ Automation ist eine Domain-Ontology +

+ + +
+ + + + + + + + + +

+ nenne sie »Special Agent« +

+ + +
+
+ + + + + + + +

+ DataAgent: Übergabe von Daten aus einem anderen Job +

+ + +
+
+ + + + +

+ ParamAgent: Einspielen von Steuerparametern +

+ + +
+
+ + + + +

+ CacheAgent: Cache-Verwaltung +

+ +
+
+ + + + +

+ ControlAgent: Instrumentierung +

+ +
+
+
+
+
+ + + + +

+ Verbindung zwischen Invocation +

+

+ und +

+

+ »ParamAgent«-Nodes +

+ +
+ + + + + + + + +

+ und zwar, weil eine Referenz in den weave()-Aufruf gegeben wird, und dieser — dem WeavingPattern gemäß — an andere Nodes weitergereicht wird; insofern hier ein nested Scope im Callgraphen entsteht, kann auch ein adaptiertes Objekt erzeugt und überlagert werden +

+ +
+ +
+ + + + + + +

+ das war mal klar .... +

+

+  und dann hat sich diese Vorstellung im Prototyping verflüchtigt +

+ +
+ + + +

+ Mir schwebte ein verwobenes Wechselspiel vor: der Turnout schafft eine Sprosse des Turnout-Systems, und diese wiederum führt diesen Turout aus. Dann habe ich versucht, das in konkretes Speicher-Layout zu übersetzen und das uferte zunächst aus, bis ich alles auf den Stack gelegt habe, womit es aber mehrere Ebenen weit tiefer gerutscht ist, in die konkrete Implementierung des Aufrufs +

+ +
+ +
+ + + + + +

+ Fahrweg — Weichenstraße — konkrete Spurführung +

+ + +
+
+ + + + +

+ Denn die Render-Engine ist — genauso wie ein Schienenweg — ein vermittelndes Gebilde und nicht die Sache selber (genausowenig wie der Zug oder die Lokomotive ist das nicht, wenn sie auf dem Abstellgleis stehen). +

+

+ +

+

+ Seitens der Nodes ist mir das wohl ganz gut gelungen, aber es besteht die Gefahr, sich letztlich doch noch irgendwo auf ein Über-System festzulegen; daher sollte auch auf der Seite der Kontrolle und Steuerung ein Erweiterungspunkt vorgesehen werden +

+ + +
+
+
+ + + + + + + + + +

+ Das ist hochgradig relevant, weil auf diesem Weg jetzt etwas gebaut werden kann, ohne die Gefahr von Architektur-Fehlern +

+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + +

+ die würde sich der SpecialAgent dann vom generischen TurnoutSystem holen um dann in einem speziellen Service einen hinterlegten Kontext aufzugreifen +

+ + +
+
+ + + + + + + + +

+ das widerspricht jedoch dem Erkenntnisbild von Fahrweg ⟶ Weichenstraße ⟶ Spurführung +

+ + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+ Festlegung: genau ein virtual call pro Node +

+ + +
+ +
+ + + + + + + + + + + + + + + + + +

+ Aber der Visitor von »damals« erscheint mir... +

+
    +
  • + immer noch unrund +
  • +
  • + zu generisch und auf Hierarchien fixiert +
  • +
  • + viel zu indirekt für den Effizienz-Maßstab in der Render-Engine (wäre akzeptabel im Builder) +
  • +
  • + viel zu systemisch bezogen auf den hier essentiellen Grad der Offenheit +
  • +
+ + +
+
+ + + + + + + +

+ VTable-Träger ist der »opaque Gegenstand« +

+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ und zwar muß noch festgelegt werden, auf welche Art Parameter zugegriffen wird, und wo; das könnte allerdings Teil eines Parameter-Berechnungsfunktors sein, der dann ein TurnoutSystem& als Argument nimmt — damit wäre die Prekonfiguration auf einem vergleichbaren Level wie für die Medienberechnungs-Nodes +

+ + +
+
+ + + + +

+ Unabhängig davon ob lediglich ein Basis-Parameter zugegriffen wird, oder ob ein vorher explizit berechneter Parameterwerd von einer ParamAgent-Node abgeholt wird: es ist eine Indirektion notwendig, um die die Konkrete Daten_Adresse zu bekommen, denn diese ist i.d.R. erst zum Zeitpunkt der Invocation feststellbar +

+ + +
+
+ + + + + + + + + + + + + + + + + + +

+ Paramter werden in ParamAgent-Nodes berechnet, welche über den normalen Builder eingehängt werden — und zwar nur bei Bedarf. Sofern also spezielle Parameter-Berechnung notwendig ist, wird dies in der Belegung und Verschaltung der Nodes prekonfiguriert, so daß die eigentliche Invocation davon nichts wissen muß. +

+ + +
+
+ + + + +

+ Obzwar weitgehende Flexibilität besteht, soll im Regelfall die weitergehende Parameter-Berechnung in einer speziellen Parameter-Aufbereitungs-Node gebündelt werden; diese ist als erster Lead unter der Exit-Node eingehängt und wird somit als erste aktiviert. Die Berechnungsfunktion in dieser Node bekommt eine Referenz auf das TurnoutSystem, und kann somit dort per Seiteneffekt zusätzliche Daten-Module registrieren. Als Storage für die zusätzlichen Datenmodule dient der Ausgabepuffer dieser Aufbereitungs-Node, welcher — gemäß allgemeinem Auswertungsschema — garantiert bis zum Ende der Render-Invocation im Speicher bestehen bleibt. +

+ + +
+
+ + + + +

+ Das Turnout-System erlaubt es, einzelne Datenmodule zu registrieren und später über diese Registrierung auch wieder (mit integriertem Cast) abzugreifen. In der Grundausstattung bietet das Turnout-System nur Zugriff auf die Invocation-Koordinaten (vor allem: die absolute nominal Time). In die ParamAgentNodes (welche letztlich einen konkreten Parameter für eine nachfolgend aufgeschaltete Berechnungs-Node bereitstellen) wird ein konkret abgeschlossenes Zugriffs-λ gebunden, welches das TurnoutSystem als Referenz bekommt, und dann aber eine Template-Funktion für den konkreten Datenzugriff aufruft. An dieser Stelle finden keine Verifikationen mehr statt, aber das Turnout-System speichert die Indirektion auf den konkreten Datenpuffer +

+ + +
+
+
+
+
+ + + + + + + + + + +
+ + + +
@@ -94141,8 +94951,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
nicht das reine NodeSymbol

- -
+
@@ -94184,6 +94993,35 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

+ + + + +

+ ...weil man es nicht erwarten kann, daß irgend ein Library-Plugin hier eine sinnvolle Systematik einführt +

+ + +
+
+ + + + + + + +

+ System schaffen +

+

+  nicht einfach ad hoc verdrahten +

+ + +
+ +
@@ -94205,7 +95043,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -94490,6 +95328,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + @@ -94499,8 +95341,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + @@ -94513,24 +95354,32 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + + + + + + + + + + + + + - + - + - - - - - - @@ -95019,17 +95868,18 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- +

- Das war schon beim allerersten Entwurf 2009 ein Problem, daß ich immerfort das Bild eines komplexen Interaktions-Protokolls im Kopf hatte; im Bezug auf die tatsächlich zu realisierenden Abläufe mag das ja stimmen, aber es muß nicht explizit in Software-Strukturen repräsentiert werden. Jetzt, für das überarbeitete Schema habe ich zwar die Interaktionen genauer verstanden, und auch ein anderes Erkenntnisbild zugrundegelegt (ein Webe-Vorgang) — trotzdem unterliege ich immer wieder dem gleichen Denkfehler, diese per Analyse offentlegten Strukturen auch in Software-Komponenten verkörpern zu wollen. + Das war schon beim allerersten Entwurf 2009 ein Problem, daß ich immerfort das Bild eines komplexen Interaktions-Protokolls im Kopf hatte; im Bezug auf die tatsächlich zu realisierenden Abläufe mag das ja stimmen, aber es muß nicht explizit in Software-Strukturen repräsentiert werden. Jetzt, für das überarbeitete Schema habe ich zwar die Interaktionen genauer verstanden, und auch ein anderes Erkenntnisbild zugrundegelegt (ein Webe-Vorgang) — trotzdem unterliege ich immer wieder dem gleichen Denkfehler, diese per Analyse offengelegten Strukturen auch in Software-Komponenten verkörpern zu wollen.

+
@@ -95770,8 +96620,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -95783,6 +96633,20 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + +

+ Hab zunächst den alten Code von 2009 / 2012 analysiert und dann die Node-Struktur neu aufgebaut; beim Verschalten der Nodes stellte sich dann zwangsläufig wieder die Frage nach den Parametern (und sei es bloß die Frame-Nummer, die man irgendwo abgreifen muß). Aus den bereits geschaffenen Strukturen war Anfang Dezember 2024 ein Entwurf möglich, der die noch vorhandenen Freiräume nutzt und die Vorstellung von Parametern konkretisiert als Funktor-Aufrufe +

+ +
+ +
+ + +