From 4a963c9fee358cada7054c711cdd3c98af59fb22 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 14 Oct 2024 04:07:47 +0200 Subject: [PATCH] Invocation: draft how the 1:1-fallback wiring could work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...and as expected, this turns up quite some inconsistencies, especially regarding usage of the »buffer types«. Basically, the `PortBuilder` is responsible for the high-level functionality and thus must ensure the nested `WiringBuilder` is addressed and parameterised properly to connect all »slots« of the processing function. - can use a helper function in the WiringBuilder to fill in connections - but the actual buffer types passed over these connectinos are totally unchecked at that level, and can not see yet how this danger can be mitigated one level above, where the PortBuilder is used. - it is still unclear what a »buffer type« actually means; it could be the pointer type, but it could also imply a class or struct type to be emplaced into the buffer, which is a special extension to the `BufferProvider` protocol, yet seems to be used here rather to transport specific data types required by the actual media handling library (e.g. FFmpeg) --- src/steam/engine/engine-ctx-facilities.cpp | 2 + src/steam/engine/engine-ctx.hpp | 1 + src/steam/engine/feed-manifold.hpp | 1 + src/steam/engine/node-builder.hpp | 4 +- src/steam/engine/turnout.hpp | 5 +- src/steam/engine/weaving-pattern-builder.hpp | 33 +- tests/core/steam/engine/node-linkage-test.cpp | 7 +- wiki/thinkPad.ichthyo.mm | 287 +++++++++++++----- 8 files changed, 259 insertions(+), 81 deletions(-) diff --git a/src/steam/engine/engine-ctx-facilities.cpp b/src/steam/engine/engine-ctx-facilities.cpp index fe0bb61d6..9c86f4d82 100644 --- a/src/steam/engine/engine-ctx-facilities.cpp +++ b/src/steam/engine/engine-ctx-facilities.cpp @@ -60,6 +60,8 @@ namespace engine{ + EngineCtx::~EngineCtx() { } + /** */ EngineCtx::EngineCtx() : services_{make_unique()} diff --git a/src/steam/engine/engine-ctx.hpp b/src/steam/engine/engine-ctx.hpp index ce25f0505..ec559a4d9 100644 --- a/src/steam/engine/engine-ctx.hpp +++ b/src/steam/engine/engine-ctx.hpp @@ -70,6 +70,7 @@ namespace engine { static lib::Depend access; private: + ~EngineCtx(); EngineCtx(); friend class lib::DependencyFactory; diff --git a/src/steam/engine/feed-manifold.hpp b/src/steam/engine/feed-manifold.hpp index 9bdfc92e5..d2af98772 100644 --- a/src/steam/engine/feed-manifold.hpp +++ b/src/steam/engine/feed-manifold.hpp @@ -70,6 +70,7 @@ namespace engine { : util::NonCopyable { using BuffS = lib::UninitialisedStorage; + enum{ STORAGE_SIZ = N }; BuffS inBuff; BuffS outBuff; diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp index 973b4fb9a..2597e3971 100644 --- a/src/steam/engine/node-builder.hpp +++ b/src/steam/engine/node-builder.hpp @@ -313,7 +313,9 @@ namespace engine { NodeBuilder completePort() { - //////////////////////////////////////////////////////////OOO finish port data setup here + //////////////////////////////////////////////////////////OOO need to provide all links to lead nodes here + weavingBuilder_.fillRemainingBufferTypes(); + _Par::ports_.append(weavingBuilder_.build()); return static_cast&&> (*this); } // slice away the subclass diff --git a/src/steam/engine/turnout.hpp b/src/steam/engine/turnout.hpp index 930b77269..20b16d937 100644 --- a/src/steam/engine/turnout.hpp +++ b/src/steam/engine/turnout.hpp @@ -266,11 +266,12 @@ namespace engine { * - `invoke()` invoke the processing function, passing the connected buffers */ template - constexpr void + constexpr bool _verify_usable_as_InvocationAdapter() { ASSERT_MEMBER_FUNCTOR (&ADA::connect, void(uint, uint)); ASSERT_MEMBER_FUNCTOR (&ADA::invoke, void()); + return sizeof(ADA); } @@ -302,7 +303,7 @@ namespace engine { //////////////////////////////////////////OOO builder must set-up those descriptors template - SimpleWeavingPattern(Several&& pr, Several dr, ARGS&& ...args) + SimpleWeavingPattern(Several&& pr, Several&& dr, ARGS&& ...args) : CONF{forward(args)...} , leadPort{move(pr)} , outTypes{move(dr)} diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp index ee9af93f1..bb21896fb 100644 --- a/src/steam/engine/weaving-pattern-builder.hpp +++ b/src/steam/engine/weaving-pattern-builder.hpp @@ -43,6 +43,8 @@ #include "steam/engine/turnout.hpp" #include "steam/engine/engine-ctx.hpp" #include "steam/engine/buffer-provider.hpp" +#include "steam/engine/buffhandle-attach.hpp" /////////////////OOO why do we need to include this? we need the accessAs() template function +#include "lib/test/test-helper.hpp" //#include "lib/util-foreach.hpp" //#include "lib/iter-adapter.hpp" //#include "lib/meta/function.hpp" @@ -148,7 +150,7 @@ namespace engine { using BuffI = typename _ProcFun::BuffI; using BuffO = typename _ProcFun::BuffO; - enum{ N = MAN::inBuff::size() + enum{ N = MAN::STORAGE_SIZ , FAN_I = _ProcFun::FAN_I , FAN_O = _ProcFun::FAN_O }; @@ -166,7 +168,7 @@ namespace engine { template SimpleFunctionInvocationAdapter (INIT&& ...funSetup) - : FUN{forward (funSetup)...} + : process{forward (funSetup)...} { } @@ -203,6 +205,16 @@ namespace engine { enum{ MAX_SIZ = N }; std::function buildFeed; + +// template + Conf_DirectFunctionInvocation(FUN fun) + : buildFeed{[=]//procFun = forward (fun)] + { +// using URGS = decltype(procFun); +// lib::test::TypeDebugger murks; + return Feed{fun}; + }} + { } }; @@ -243,7 +255,7 @@ namespace engine { attachToLeadPort(ProcNode& lead, uint portNr) { PortRef portRef; /////////////////////////////////////OOO TODO need Accessor on ProcNode!!!!! - leadPort.emplace (portRef); + leadPort.append (portRef); ENSURE (leadPort.size() < N); return move(*this); } @@ -259,6 +271,16 @@ namespace engine { return move(*this); } + WeavingBuilder + fillRemainingBufferTypes() + { + using FunSpec = _ProcFun; + auto constexpr FAN_O = FunSpec::FAN_O; + using BuffO = typename FunSpec::BuffO; + uint cnt = FAN_O - buffTypes.size(); + return appendBufferTypes(cnt); + } + WeavingBuilder selectResultSlot(uint idx) { @@ -271,10 +293,11 @@ namespace engine { build() { maybeFillDefaultProviders (buffTypes.size()); + REQUIRE (providers.size() == buffTypes.size()); uint i=0; for (auto& typeConstructor : buffTypes) - outTypes.emplace ( - typeConstructor (providers[i])); + outTypes.append ( + typeConstructor (providers[i++])); ENSURE (leadPort.size() < N); ENSURE (outTypes.size() < N); diff --git a/tests/core/steam/engine/node-linkage-test.cpp b/tests/core/steam/engine/node-linkage-test.cpp index c555844e8..ed9edc4c0 100644 --- a/tests/core/steam/engine/node-linkage-test.cpp +++ b/tests/core/steam/engine/node-linkage-test.cpp @@ -29,9 +29,11 @@ #include "steam/engine/proc-node.hpp" #include "steam/engine/node-builder.hpp" #include "steam/engine/test-rand-ontology.hpp" ///////////TODO -//#include "lib/util.hpp" +#include "lib/test/diagnostic-output.hpp"/////////////////TODO +#include "lib/util.hpp" +using util::isnil; //using std::string; @@ -74,7 +76,8 @@ namespace test { .invoke(dummyOp) .completePort() .build(); - UNIMPLEMENTED ("build render nodes linked into a connectivity network"); + CHECK (isnil (con.leads)); + CHECK (1 == con.ports.size()); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 63fc5d75d..be37f6053 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -8417,9 +8417,7 @@ - - - +

dann aber als State Monad @@ -8451,9 +8449,7 @@ - - - +

wende die resultierende State-Monade @@ -8494,9 +8490,7 @@ - - - +

alternatives @@ -8527,9 +8521,7 @@ - - - +

Fazit: @@ -8553,9 +8545,7 @@ - - - +

das impliziert grundsätzlich einen Stack @@ -9228,9 +9218,7 @@ - - - +

...denn wenn mal ein Layer "nur" Iterator wäre, @@ -11357,9 +11345,7 @@ - - - +

möglicherwese aber notwendig @@ -12713,9 +12699,7 @@ - - - +

sonst bekommen wir eine versteckte @@ -13621,9 +13605,7 @@ - - - +

der Level im UI ist noch offen @@ -15085,9 +15067,7 @@ - - - +

...um zu prüfen, ob das allgemeine Design @@ -81429,7 +81409,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

- + + @@ -89466,6 +89447,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+
@@ -89473,6 +89455,162 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...da es sich um C-Libraries handelt.... +

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

+ Unsicherheiten beim Durchreichen des Initialisierers. +

+

+ Das notorische Problem; ich möchte in der eigentlichen ProcNode keine std::function haben, sondern idealerweise ein Lambda. Aber irgendwo im Turnout muß ein Prototyp dieses Funktors liegen, von dem wir für jeden Aufruf kopieren können. Das ist kniffelig, wenn der Initialisierer hierfür durch eine perfect-forwarding-Kette durchgereicht werden soll. +

+ +
+ +
+ + + + +

+ src/lib/several-builder.hpp:327:39: warning: parameter 'src' set but not used [-Wunused-but-set-parameter] +

+

+          moveElem (size_t idx, Bucket* src, Bucket* tar) +

+ + +
+ +
+ + + + + + + + + + +
@@ -89600,6 +89738,31 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + +

+ ...weil es immer mehr darauf hinaus läuft, daß der PortBuilder die high-level-Sicht auf die Verdrahtung hat, während der WeavingBuilder von ersterem explizit gesteuert werden muß +

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

+ ...derzeit verwendet der fest eingestellt das SimpleWeavingPattern — und ebenso eine fest verdrahtete Basis-Konfiguration. Richtig wäre es, entweder mehrere WeavingBuilder-Varianten zu haben, oder — wenn schon ein einziger WeavingBuilder genügt — diesen nicht nur mit der Funktion zu parametrisieren +

+ +
+
+
@@ -89690,8 +89853,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
siehe TestFrame_test

- - + @@ -89702,8 +89864,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
es gibt nur einen festen Seed-Mechanismus, der auf der Kanal- und Sequenz-Nummer beruht

- - +
@@ -89713,8 +89874,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
kann Lifecycle markieren als CREATED, EMITTED, DISCARDED

- -
+
@@ -89733,8 +89893,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
bringt nicht wirklich was, aber zumindest sollte std::random mit kompatiblem Generator verwendet werden

- - +
@@ -89750,8 +89909,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Es fehlt ja generell noch ein Framework für Zufallswerte in Tests, so daß jeder Test seinen definiten Seed bekommt, welcher zwar normalerweise zufällig, ansonsten aber feststellbar und reproduzierbar sein sollte

- - +
@@ -89762,8 +89920,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Das sind sie bereits in der bestehenden Implementierung, und das Prinzip ist auch bereits gut genug; allerdings sollten wir das Schema von std::random verwenden, d.h. jeweils einen Generator und darauf aufbauend eine Distribution

- - +
@@ -89776,8 +89933,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Das Daten-Array liegt nicht am Anfang, und ist deshalb plattform/implementierungsabhängig aligned; das erschwert auch die direkte Interpretation eines Datenblocks als TestFrame....

- - + @@ -89788,8 +89944,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
....und damit sollte man jede beliebige Speicherlocation als Testframe interpretieren können, ohne diese zu korrumpieren; das impliziert auch, daß der behandelnde Code erkennen kann, ob ein Metadatenblock überhaupt angelegt wurde — und wenn das nicht der Fall ist, sollte auch niemals implizit in den Speicher geschrieben werden

- - +
@@ -89799,8 +89954,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Dabei ist die Prüfsumme ein verknüpfter Hash, und man sollte diese jederzeit berechnen können; jedoch ein regulär erstellter TestFrame sollte die Prüfsumme explizit speichern, und auch für beliebigen Dateninhalt sollte sich die Prüfsumme explizit markiern (speichern) lassen, denn damit werden auch weitergehende Berechnungen auf den Daten möglich, die vom initialen Seed abweichen

- -
+
@@ -89817,8 +89971,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
neue Bedeutung: es ist ein TestFrame mit erkennbarem Metadatenblock (auch wenn ansonsten keine der Prüfsummen mit den Daten zusammenpaßt); es sollte recht unwahrscheinlich sein, daß ein zufälliger Datenblock diesen Test besteht.

- - +
@@ -89828,8 +89981,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Es ist ein TestFrame mit gültigem Metadaten-Block, und die dort gespeicherte Prüfsumme wird durch die Daten bestätigt

- -
+
@@ -89839,8 +89991,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
entspricht dem bisherigen isSane() — d.h. isValid() aber zusätzlich passen die Daten auf die gespeicherte distinction, und das heißt, die Daten wurden vom Standard-Schema erzeugt und nicht weiter bearbeitet

- -
+
@@ -89880,8 +90031,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - +
@@ -89913,8 +90063,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
...das bedeutet, sie läuft auf size_t (oder was dann letztlich die Wortbreite sein wird für Lumiera Hash-Vorgänge) und sie ist nicht kommutativ in den Argumenten

- - +
@@ -89924,8 +90073,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Jeder Funktionsaufruf ist „gefärbt“, aber ansonsten äquivalent. Das heißt, ein fester Parameterwert fließt mit in die Berechnung jedes einzelnen Datenpunktes, und dieser Wert ist an den jeweiligen Aufruf gebunden wird, wodurch auch eine Kette gleichartiger Aufrufe in der Reihenfolge unterscheidbar gemacht werden kann.

- -
+
@@ -89935,8 +90083,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
...zwar handelt es sich stets nur um eine Hash-Verknüpfung, aber die Arität (und ggfs. später auch noch ein Array-Wertiger Input) kommen als Steuerparameter hinzu. Diese Parameter können als lesbarer Spec-String ausgegeben werden, und in einen Hash eingerechnet werden, der dann die Funktion markiert und unterscheidbar macht. Wenn ein Seed explizit angegeben wird, dann fließt er zusätzlich mit ein, und markiert außerdem auch die Berechnung an jedem Datenpunkt

- -
+
@@ -89946,8 +90093,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
...später, wenn ich abschließend geklärt habe, wie Automation funktionieren soll. Derzeit denke ich, daß solche Funktions-Parameter in einem Tree-walk vor dem eigentlichen pull() der Invocation gesetzt werden, also über das Turnout-System. Speziell für die Test-Ontology könnte man hier auch eine Node-ID oder einen Node-Struktur-Hash einfließen lassen (wobei mit jetzt aber nicht klar ist, ob diese Idee für das Testen überhaupt von Nutzen ist)

- -
+
@@ -89958,8 +90104,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Ich will also eine laterale Vermischung der Daten vermeiden; erst über die Prüfsumme des Ergebnis-Datenblocks werden die einzelnen Datenpunkte zusammengeführt; theoretisch wäre es dadurch sogar möglich, die Korruption einzelner Datenpunkte zu erkennen, indem man die intendierte Berechnungskette explizit gecodet nochmal ausführt und dann die Ergebnisdaten vergleicht.

- - +
@@ -89982,8 +90127,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
d.h. das EventLog liegt in einem Singleton, und wenn es da ist, dann hinterläßt jeder Funktionsaufruf einen Log-Eintrag, so daß sich der gesamte Berechnungsweg mit allen Aufruf-Reihenfolgen nachvollziehen und verifizieren läßt

- -
+
@@ -90006,10 +90150,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + @@ -90017,6 +90161,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+