diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp
index 783cf9d65..7ed3175ee 100644
--- a/src/steam/engine/node-builder.hpp
+++ b/src/steam/engine/node-builder.hpp
@@ -350,6 +350,25 @@ namespace engine {
return move(*this);
}
+ /**
+ * Embed the explicitly given parameter-functor into the FeedPrototype,
+ * so that it will be called on each Node invocation to generate parameters
+ * to be passed into the actual processing function. The TurnoutSystem acts
+ * as source for the base coordinates, typically the _absolute nominal Time._
+ * @return adapted PortBuilder marked with the `FeedPrototype` holding \a PFX
+ */
+ template
+ auto
+ attachParamFun (PFX paramFunctor)
+ {
+ using AdaptedWeavingBuilder = typename WAB::template Adapted;
+ using AdaptedPortBuilder = PortBuilder;
+ //
+ return AdaptedPortBuilder{move(*this)
+ ,weavingBuilder_.adaptParam (move (paramFunctor))
+ };
+ }
+
/*************************************************************//**
* Terminal: complete the Port wiring and return to the node level.
diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp
index 383bd225e..b6c392871 100644
--- a/src/steam/engine/weaving-pattern-builder.hpp
+++ b/src/steam/engine/weaving-pattern-builder.hpp
@@ -286,6 +286,28 @@ namespace engine {
, prototype_{move (adaptedPrototype)}
{ }
+
+ /** type builder for FeedPrototype adapted to another parameter-fun */
+ template
+ using AdaptedPrototype = typename PROT::template Adapted;
+ template
+ using Adapted = WeavingBuilder>;
+
+ /** Adapt a parameter-functor into the _Feed Prototype,_
+ * so that it is invoked whenever a new `FeedManifold` is built.
+ * @return adapted WeavingBuilder marked with changed `FeedManifold` type.
+ */
+ template
+ auto
+ adaptParam (PFX paramFunctor)
+ {
+ using AdaptedWeavingBuilder = Adapted;
+ //
+ return AdaptedWeavingBuilder{move(*this)
+ ,prototype_.moveAdapted (move (paramFunctor))
+ };
+ }
+
WeavingBuilder&&
attachToLeadPort (ProcNode& lead, uint portNr)
{
diff --git a/tests/core/steam/engine/node-builder-test.cpp b/tests/core/steam/engine/node-builder-test.cpp
index c64c44ece..89cbab87c 100644
--- a/tests/core/steam/engine/node-builder-test.cpp
+++ b/tests/core/steam/engine/node-builder-test.cpp
@@ -66,19 +66,32 @@ namespace test {
CHECK (watch(node).isSrc());
CHECK (watch(node).ports().size() == 1);
- // Prepare setup to invoke such a Render Node...
+ CHECK (LIFE_AND_UNIVERSE_4EVER == invokeRenderNode (node));
+ }
+
+ /**
+ * @internal Helper for Render Node invocation
+ * - use a DiagnosticBufferProvider to allocate a result buffer
+ * - assuming that the Node internally does not allocate further buffers
+ * - pull from Port #0 of the given node, passing the \a nomTime as argument
+ * - expect the buffer to hold a single `uint` value after invocation
+ */
+ uint
+ invokeRenderNode (ProcNode& theNode, Time nomTime =Time::ZERO)
+ {
BufferProvider& provider = DiagnosticBufferProvider::build();
BuffHandle buff = provider.lockBufferFor (-55);
- Time nomTime = Time::ZERO;
ProcessKey key{0};
uint port{0};
CHECK (-55 == buff.accessAs());
// Trigger Node invocation...
- buff = node.pull (port, buff, nomTime, key);
+ buff = theNode.pull (port, buff, nomTime, key);
- CHECK (LIFE_AND_UNIVERSE_4EVER == buff.accessAs());
+ uint result = buff.accessAs();
+ buff.release();
+ return result;
}
@@ -88,6 +101,18 @@ namespace test {
void
build_Node_fixedParam()
{
+ auto procFun = [](ushort param, uint* buff){ *buff = param; };
+ auto paramFun = [](TurnoutSystem&){ return LIFE_AND_UNIVERSE_4EVER; };
+
+ ProcNode node{prepareNode("Test")
+ .preparePort()
+ .invoke("fun()",procFun)
+ .attachParamFun(paramFun)
+ .completePort()
+ .build()};
+
+ CHECK (LIFE_AND_UNIVERSE_4EVER == invokeRenderNode (node));
+
UNIMPLEMENTED ("build node with fixed param");
}
diff --git a/tests/core/steam/engine/node-feed-test.cpp b/tests/core/steam/engine/node-feed-test.cpp
index 6c1eed43e..356d1bdbb 100644
--- a/tests/core/steam/engine/node-feed-test.cpp
+++ b/tests/core/steam/engine/node-feed-test.cpp
@@ -17,10 +17,20 @@
#include "lib/test/run.hpp"
+#include "steam/engine/proc-node.hpp"
+#include "steam/engine/node-builder.hpp"
+#include "steam/engine/weaving-pattern.hpp"
+#include "steam/engine/turnout-system.hpp"
+#include "steam/engine/turnout.hpp"
+#include "steam/engine/diagnostic-buffer-provider.hpp"
+#include "lib/several-builder.hpp"
+#include "lib/test/diagnostic-output.hpp"/////////////////////TODO
//#include "lib/util.hpp"
//using std::string;
+using lib::Several;
+using lib::makeSeveral;
namespace steam {
@@ -42,9 +52,56 @@ namespace test {
UNIMPLEMENTED ("render node pulling source data from vault");
}
- /** @test feed parameter data to nodes */
+
+ /** @test demonstrate internal setup to invoke a simple output-only function,
+ * passing an additional invocation parameter generated from a parameter-functor
+ * - embed the processing-functor and parameter-functor into a FeedPrototype
+ * - construct the type of the »Weaving Pattern« to use for invocation
+ * - setup an empty wiring (output-only, thus no predecessor ports)
+ * - setup a single BuffDesrc for a result puffer to pass to the processing-functor
+ * - create a Turnout, which implements the Port interface, using the Weaving-Pattern
+ * - for the actual invocation, setup a TurnoutSystem, initialised with a nominal time
+ * - invoke the Port::weave() function and retrieve the result from the buffer.
+ * @remark this is a semi-integrated setup to demonstrate the interplay of the
+ * internal components within a Render Node, without the _outer shell_
+ * provided by the NodeBuilder and the ProcNode itself
+ */
void
feedParam()
+ {
+ auto procFun = [](ushort param, uint* buff){ *buff = param; };
+ auto paramFun = [](TurnoutSystem&){ return LIFE_AND_UNIVERSE_4EVER; };
+
+ auto feedPrototype = FeedPrototype{move(procFun), move(paramFun)};
+ using Prototype = decltype(feedPrototype);
+ using WeavingPattern = MediaWeavingPattern;
+ using TurnoutWeaving = Turnout;
+
+ BufferProvider& provider = DiagnosticBufferProvider::build();
+
+ Several noLeadPorts; // ◁————————— empty predecessor-port-sequence
+ Several outBuffDescr = makeSeveral({provider.getDescriptor()})
+ .build(); // ◁————————— a single output buffer to hold an `uint`
+ uint resultSlot{0};
+
+ TurnoutWeaving port{ProcID::describe ("SimpleNode","procFun()")
+ , move (noLeadPorts)
+ , move (outBuffDescr)
+ , resultSlot
+ , move (feedPrototype)
+ };
+
+ // setup for invocation...
+ Time nomTime =Time::ZERO;
+ TurnoutSystem turnoutSys{nomTime};
+ BuffHandle result = port.weave (turnoutSys); // ◁————————— paramFun invoked here, then procFun
+ CHECK (LIFE_AND_UNIVERSE_4EVER == result.accessAs());// and procFun wrote param-value into result buffer
+ result.release();
+ }
+
+ /** @test create extended parameter data for use in recursive Node invocation */
+ void
+ feedParamNode()
{
TODO ("implement the logic for the TurnoutSystem --> node-base-test.cpp");
TODO ("implement a simple Builder for ParamAgent-Node");
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index 969232f0f..e882650e4 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -29011,9 +29011,7 @@
-
-
-
+
d.h. man erzeugt in einem einzigen Aufruf den VerbPack für eine Zielfunktion
@@ -29382,9 +29380,7 @@
-
-
-
+
und bleibt anderweitig ungenutzt
@@ -29708,9 +29704,7 @@
-
-
-
+
...und das würde auch erklären, warum trotzdem die Zelle mit der Glühbirne (=die direkten Controls) überhaupt nicht aufgespreitzt wird
@@ -29945,9 +29939,7 @@
-
-
-
+
hier können wir nicht exakt rechnen, weil aufsteigende Slopes kombiniert werden — und die Info dazu kennen wir nur beim Konstruieren des Profils. Daher überschätzt diese Höhenangabe die Track-Höhe — bleibt zu sehen, ob das relevant wird
@@ -30665,9 +30657,7 @@
-
-
-
+
das wäre der logisch richtige Ort
@@ -30956,9 +30946,7 @@
-
-
-
+
die Idee einer graphischen Benutzeroberfläche hat sich über die 60er / 70er-Jahre herausgebildet.
@@ -31880,9 +31868,7 @@
-
-
-
+
Nein. Es ist ein GDK-Wrapper/Adapter
@@ -32285,9 +32271,7 @@
-
-
-
+
g {
@@ -82221,8 +82205,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
...also vor allem die Frage: wirft das jetzt alles über den Haufen, kann man es außen anbauen, oder gar in bestehende Strukturen lediglich hinein-codieren?
-
-
+
@@ -82287,8 +82270,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
denn nun wird in der Regel erst mal aus dem PortBuilderRoot das Binding für die Processing-Function angelegt ⟹ PortBuilder — und erst von dort gibt man dann Parameter an ⟹ modifizierter PortBuilder
-
-
+
@@ -82353,9 +82335,51 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
+
+
+
+
+
+ »dropper-Funktion« verwenden, die einen fest hinterlegten Parameter-Wert für jede Invocation in die FeedManifold setzt
+
+
+
+
+
+
+
+
+
+
+ Parameter aus TurnoutSystem per Accessor abholen; ein solcher typ-sicherer Accessor kann über das HeteroData-Framework generiert werden, welches als Storage mit verketteten, getypten Datenblöcken direkt in das TurnoutSystem eingebaut ist. In der Standard-Konfiguration enthält so ein TurnoutSystem nur einen ersten Block mit den Invocation-Parameter (absoluteNominalTime und ein processKey). Daher ist diese API-Variante nur interessant, falls vorher schon per Parameter-Node ein erweiterter Datenblock mit zusätzlichen Parametern irgendwo auf den Stack gelegt wurde
+
+
+
+
+
+
+
+
+
+ zeitbasierte Funktion adaptieren, für klassische Parameter-Automation. Der Zeit-Parameter ist dabei die absolute-nominal-Time, welche aus dem Render-Job stammt und im TurnoutSystem abgelegt ist
+
+
+
+
+
+
+
+
+
+ beliebiger Parameter-Funktor, der auf dem TurnoutSystem arbeitet und einen passenden Parameter-Wert produziert; Typisierung wird zur compile-Zeit geprüft.
+
+
+
+
+
@@ -88993,7 +89017,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -91202,7 +91226,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -91955,9 +91979,9 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
-
+
+
+
@@ -92290,7 +92314,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -92904,9 +92928,9 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
-
+
+
+
@@ -92931,10 +92955,10 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
-
+
@@ -93126,19 +93150,19 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
-
+
+
+
-
-
+
+
-
+
-
+
@@ -93821,7 +93845,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -93845,8 +93869,8 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
@@ -93872,8 +93896,8 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
@@ -96941,8 +96965,9 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
+
@@ -96953,8 +96978,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
⟹ also muß der WeavingBuilder seine Typ-Parameter schwenken können
-
-
+
@@ -96964,10 +96988,9 @@ Date: Thu Apr 20 18:53:17 2023 +0200
⟹ und der ihn umschließende PortBuilder muß diesen Schwenk mitgehen
-
-
+
-
+
@@ -96987,8 +97010,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
schon das Ding mit PatternData ist grauenhaft — und s'werd ois no fui schmlimma
-
-
+
@@ -97009,7 +97031,8 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
+
@@ -97050,7 +97073,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -97070,11 +97093,13 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
+
+
-
+
@@ -97208,8 +97233,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
aber das wäre das eigentliche Problem
-
-
+
@@ -97258,8 +97282,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
insofern hier nämlich bereits akzidentelle Komplexität generiert wird
-
-
+
@@ -97269,8 +97292,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
Man kann die Struktur zwar extrahieren, aber die extrahierte Version läßt sich nicht sinnvoll in einfachereren Begriffen darstellen
-
-
+
@@ -97280,8 +97302,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
...insofern hier Komplexität nicht durch eine Abstraktion reduziert wurde, sondern nur durch Modularisierbarkeit und Zwischenschritte beherrschbarer gemacht wird; aber dies wird durch Generieren zusätzlicher Komplexität erkauft, was den Ansatz insgesamt in Frage stellt
-
-
+
@@ -97289,7 +97310,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
-
+
@@ -97297,19 +97318,24 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
Fazit: bite the bullet...
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -97319,17 +97345,18 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
-
-
+
+
-
-
+
+
-
-
+
+
+
@@ -97345,7 +97372,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
-
+
@@ -97353,6 +97380,23 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -97379,8 +97423,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
Das Pattern heißt jetzt auch MediaWeavingPattern und ist zum Standard geworden; der Build-Mechanismus im Port-Builder könnte jedes dazu kompatible Pattern ebenfalls handhaben
-
-
+
@@ -97420,11 +97463,36 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
-
+
-
+
+
+
+
+
+
+ erfolgt als Teil der Konfiguration eines Ports
+
+
+
+
+
+
+
+
+
+
+ also nachdem man den Processing-Functor gegeben hat
+
+
+
+
+
+
+
+
@@ -97476,8 +97544,11 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
-
-
+
+
+
+
+