diff --git a/src/steam/engine/buffer-provider.cpp b/src/steam/engine/buffer-provider.cpp index 711854b00..8b057a7e9 100644 --- a/src/steam/engine/buffer-provider.cpp +++ b/src/steam/engine/buffer-provider.cpp @@ -136,6 +136,7 @@ namespace engine { * @note this function may be used right away, without prior announcing, but then * the client should be prepared for exceptions. The #announce operation allows * to establish a reliably available baseline. + * @todo 2/2025 might need to accept a cache key as additional parameter //////////////////////////////////TICKET #1392 : get cache key from computation to the cache backend */ BuffHandle BufferProvider::lockBuffer (BuffDescr const& type) diff --git a/src/steam/engine/feed-manifold.hpp b/src/steam/engine/feed-manifold.hpp index a1a2904e8..5e0751caa 100644 --- a/src/steam/engine/feed-manifold.hpp +++ b/src/steam/engine/feed-manifold.hpp @@ -345,7 +345,7 @@ namespace engine { template ParamStorage (INIT&& ...paramInit) : param{forward (paramInit)...} - { } + { } /////////////////////////////TICKET #1392 : pick up actual param and compute cache key }; /** FeedManifold building block: hold input buffer pointers */ diff --git a/src/steam/engine/proc-id.hpp b/src/steam/engine/proc-id.hpp index f68ea9cf5..5be74e96e 100644 --- a/src/steam/engine/proc-id.hpp +++ b/src/steam/engine/proc-id.hpp @@ -111,22 +111,25 @@ namespace engine { /** * Metadata to qualify a Port (and implicitly the enclosing Node). + * @note must be essentially immutable; should ensure that implementation + * never changes anything constituent for the \ref hash_value(), + * due to de-duplication into a hashtable (see proc-node.cpp). */ class ProcID { StrView nodeName_; StrView portQual_; StrView argLists_; - ProcAttrib attrib_{}; + ProcAttrib attrib_; - ProcID (StrView nodeSymb, StrView portQual, StrView argLists); + ProcID (StrView nodeSymb, StrView portQual, StrView argLists, ProcAttrib); using ProcNodeRef = std::reference_wrapper; using Leads = lib::Several; public: /** build and register a processing ID descriptor */ - static ProcID& describe (StrView nodeSymb, StrView portSpec); + static ProcID& describe (StrView nodeSymb, StrView portSpec, ProcAttrib extAttrib =ProcAttrib{}); /* === symbolic descriptors === */ diff --git a/src/steam/engine/proc-node.cpp b/src/steam/engine/proc-node.cpp index 8215eb84b..96021386f 100644 --- a/src/steam/engine/proc-node.cpp +++ b/src/steam/engine/proc-node.cpp @@ -183,9 +183,11 @@ namespace engine { * @remark this is the only public access point to ProcID entries, * which are automatically deduplicated and managed in a common registry * and retained until end of the Lumiera process (never deleted). + * @todo isn't returning a non-const reference dangerous? someone might add + * mutable state then, thereby undercutting de-duplication into a hashtable. */ ProcID& - ProcID::describe (StrView nodeSymb, StrView portSpec) + ProcID::describe (StrView nodeSymb, StrView portSpec, ProcAttrib extAttrib) { REQUIRE (not isnil (nodeSymb)); REQUIRE (not isnil (portSpec)); @@ -196,7 +198,7 @@ namespace engine { "Node:%s Spec:%s"} % nodeSymb % portSpec }; - auto res = procRegistry.insert (ProcID{nodeSymb, portSpec.substr(0,p), portSpec.substr(p)}); + auto res = procRegistry.insert (ProcID{nodeSymb, portSpec.substr(0,p), portSpec.substr(p), extAttrib}); ProcID& entry{unConst (*res.first)}; if (res.second) {// new record placed into the registry @@ -209,10 +211,11 @@ namespace engine { } /** @internal */ - ProcID::ProcID (StrView nodeSymb, StrView portQual, StrView argLists) + ProcID::ProcID (StrView nodeSymb, StrView portQual, StrView argLists, ProcAttrib extAttrib) : nodeName_{nodeSymb} , portQual_{portQual} , argLists_{argLists} + , attrib_{extAttrib} { } /** @@ -386,6 +389,7 @@ namespace engine { } + namespace {// create a »backdoor access« into actual weaving-pattern instances using _DummyProc = void(&)(NullType*); @@ -393,12 +397,25 @@ namespace engine { using _DummyMediaWeaving = MediaWeavingPattern<_DummyProto>; using _RecastMediaWeaving = _TurnoutDiagnostic<_DummyMediaWeaving>; + using _EmptySpec = decltype(buildParamSpec()); + using _DummyParamWeaving = ParamWeavingPattern<_EmptySpec>; + using _RecastParamWeaving = _TurnoutDiagnostic<_DummyParamWeaving>; + lib::Several EMPTY_PRECURSORS; } - /** - * Intrude into the Turnout and find out about source connectivity + * Intrude into the Turnout and find out about source connectivity. + * At interface level, this information about predecessor ports is not retained, + * but for the most common weaving patterns (Port implementations) there is a way + * to access implementation internals, bypassing the \ref Port interface; otherwise + * a reference to an empty port collection is returned. + * @warning this is a possibly dangerous low-level access, bypassing type safety. + * It relies on flags in the ProcID attributes to be set properly by the builder, + * and it relies on a common shared prefix in the memory layout of weaving patterns. + * @remark the \ref Port interface is kept minimal, since a very large number of + * implementations and template instantiations can be expected, so that any further + * function would cause a lot of additional and mostly redundant code generation. */ lib::Several const& PortDiagnostic::srcPorts() @@ -408,7 +425,12 @@ namespace engine { auto [leads,types] = _RecastMediaWeaving::accessInternal (p_); return leads; } -/////////////////////////////////////////////////OOO add branch here to support Proxy-patterns + else + if (p_.procID.hasProxyPatt()) + { + Port& delegate = std::get<0>(_RecastParamWeaving::accessInternal (p_)); + return watch(delegate).srcPorts(); + } // recursive invocation on delegate of proxy else return EMPTY_PRECURSORS; } diff --git a/src/steam/engine/turnout.hpp b/src/steam/engine/turnout.hpp index 33495b7ae..2dceaff85 100644 --- a/src/steam/engine/turnout.hpp +++ b/src/steam/engine/turnout.hpp @@ -144,6 +144,8 @@ namespace engine { + + /** * @internal »Backdoor« for diagnostic * @warning must be kept **layout compatible** with Turnout diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 9c7237e5b..ff751b733 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -94909,6 +94909,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + @@ -94943,6 +94949,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+
@@ -102842,7 +102849,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -102851,6 +102858,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)

+ @@ -103260,7 +103268,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -103274,6 +103282,15 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + + + + @@ -104890,6 +104907,11 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + @@ -105078,6 +105100,26 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + + + + + +

+ ...braucht einen aktuellen Port-Hash, berechnet aber auf dieser Basis direkt den Beitrag der aktuell erzeugten Parameter-Werte +

+ + +
+
+
+ + @@ -105141,6 +105183,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) +
@@ -106235,30 +106278,66 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
- + - + - - - +

MediaWeavingPattern ⟵  Dummy-Funktion void(&)(NullType*)

- -
+
+ + + + +

+ ParamWeavingPattern ⟵  empty Spec buildParamSpec() +

+ +
+ +
+ + + + +

+ ....da ich im Moment nur spekuliere, und ein konkreter Bezugspunkt noch in weiter Ferne liegt; wegen der de-Duplikation sollten alle Quellen bereits in den statischen Factory-Aufruf gehen; man könnte natürlich eine Builder-DSL davor setzen (nicht daß wir schon genug Builder in dem Bereich hätten....) +

+ +
+
- + + + + + + + + + + + + + + + + + + + @@ -106280,18 +106359,33 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + - - + + - - + + + + + + + + + + +

+ Da Fall-1 am Wichtigsten ist, orientiert sich das Interface daran und reicht einfach die Collection der Vorgänger-Ports per Referenz heraus. Leider haben wir aber im Fall de ParamWeavingPattern gar keine Collection der Vorgänger-Ports, sondern nur eine direkte Referenz auf den Delegate des Proxy; und da es sich um einen einfachen Funktionsaufruf handelt, haben wir keinen Ort, an dem eine solche Collection hilfsweise konstruiert und abgelegt werden könnte. Deshalb bleibt nur, entweder in dem Fall gar nichts zu liefern, d.h. zwei verschiedene Methoden zu bieten, oder eben die Rekursion auf das Delegate (das dann hoffentlich ein Manifold-Pattern ist und deshalb eine solche Collection hat) +

+ +
+ +
@@ -106300,6 +106394,19 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
+ + + + +

+ ...entweder, indem es direkt im Turnout eine Querverbindung gibt, oder duch einen low-Level-Zugangsweg analog zu den Source-Ports +

+ +
+ + + +
@@ -107366,7 +107473,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -148253,6 +148360,11 @@ std::cout << tmpl.render({"what", "World"}) << s + + + + +