diff --git a/src/steam/engine/feed-manifold.hpp b/src/steam/engine/feed-manifold.hpp
index aef6200ba..40a4f5a9b 100644
--- a/src/steam/engine/feed-manifold.hpp
+++ b/src/steam/engine/feed-manifold.hpp
@@ -263,7 +263,7 @@ namespace engine {
static constexpr bool hasParam() { return _Proc::hasParam(); }
- using Param = std::conditional_t>;
+ using Param = std::conditional_t>;
template
using Res = typename _Fun::Ret;
@@ -569,7 +569,7 @@ namespace engine {
, paramFun_{move (par)}
{ }
// default move acceptable : pass pre-established setup
-
+
static constexpr bool hasParam() { return _Trait::hasParam(); }
static constexpr bool hasParamFun() { return _Trait::template isParamFun(); }
static constexpr bool canActivate() { return _Trait::template canActivate(); }
@@ -582,9 +582,30 @@ namespace engine {
{
if constexpr (hasParamFun())
if (_Trait::isActivated(paramFun_))
- return Feed{paramFun_(turnoutSys), procFun_};
+ return Feed(paramFun_(turnoutSys), procFun_);
return Feed{procFun_};
}
+
+
+ template
+ using Adapted = FeedPrototype;
+
+ /**
+ * Cross-Builder to add configuration with a given parameter-functor.
+ * @return new FeedPrototype instance outfitted with the current
+ * processing-functor and the given other param-functor
+ * @warning the current instance is likely **defunct** after this call,
+ * and should not be used any more, due to the move-construct.
+ * @remark together with the move-ctor of FeedPrototype this helper
+ * can be used to configure a Prototype in several steps.
+ */
+ template
+ auto
+ moveAdapted (PFX otherParamFun)
+ {
+ using OtherParamFun = std::decay_t;
+ return Adapted{move(procFun_), move(otherParamFun)};
+ }
};
diff --git a/tests/core/steam/engine/node-base-test.cpp b/tests/core/steam/engine/node-base-test.cpp
index 7ac87019d..36e200ae0 100644
--- a/tests/core/steam/engine/node-base-test.cpp
+++ b/tests/core/steam/engine/node-base-test.cpp
@@ -328,7 +328,6 @@ namespace test {
verify_FeedPrototype()
{
// Prepare setup to build a suitable FeedManifold...
- long r1 = rani(100);
using Buffer = long;
BufferProvider& provider = DiagnosticBufferProvider::build();
BuffHandle buff = provider.lockBufferFor (-55);
@@ -336,24 +335,66 @@ namespace test {
auto fun_singleParamOut = [](short param, Buffer* buff) { *buff = param-1; };
using M1 = FeedManifold;
using P1 = M1::Prototype;
- CHECK ( P1::hasParam());
- CHECK (not P1::hasParamFun());
+ CHECK ( P1::hasParam()); // checks that the processing-function accepts a parameter
+ CHECK (not P1::hasParamFun()); // while this prototype has no active param-functor
CHECK (not P1::canActivate());
- P1 p1{move (fun_singleParamOut)};
+ P1 p1{move (fun_singleParamOut)}; // create the instance of the prototype, moving the functor in
CHECK (sizeof(p1) <= sizeof(void*));
- TurnoutSystem turSys{Time::NEVER};
+ TurnoutSystem turSys{Time::NEVER}; // Each Node invocation uses a TurnoutSystem instance....
- M1 m1 = p1.createFeed(turSys);
- CHECK (m1.param == short{});
- m1.outBuff.createAt(0, buff);
+ M1 m1 = p1.createFeed(turSys); //... and also will create a new FeedManifold from the prototype
+ CHECK (m1.param == short{}); // In this case here, the param value is default constructed.
+ m1.outBuff.createAt(0, buff); // Perform the usual steps for an invocation....
CHECK (buff.accessAs() == -55);
m1.connect();
CHECK (*m1.outArgs == -55);
m1.invoke();
- CHECK (*m1.outArgs == 0 - 1);
+ CHECK (*m1.outArgs == 0 - 1); // fun_singleParamOut() -> param - 1 and param ≡ 0
CHECK (buff.accessAs() == 0 - 1);
+ long& calcResult = buff.accessAs(); // for convenience use a reference into the result buffer
+
+
+
+ //_____________________________________
+ // Reconfigure to attach a param-functor
+ long rr{11}; // ▽▽▽▽ Note: side-effect
+ auto fun_paramSimple = [&](TurnoutSystem&){ return rr += 1+rani(100); };
+ using P1x = P1::Adapted;
+ CHECK ( P1x::hasParam());
+ CHECK ( P1x::hasParamFun());
+ CHECK (not P1x::canActivate());
+
+ P1x p1x = p1.moveAdapted (move(fun_paramSimple));
+ M1 m1x = p1x.createFeed(turSys); // ◁————————— param-functor invoked here
+ CHECK (rr == m1x.param); // ...as indicated by the side-effect
+ short r1 = m1x.param;
+
+ // the rest works as always with FeedManifold (which as such is agnostic of the param-functor!)
+ m1x.outBuff.createAt(0, buff);
+ m1x.connect();
+ m1x.invoke(); // Invoke the processing functor
+ CHECK (calcResult == r1 - 1); // ...which computes fun_singleParamOut() -> param-1
+
+ // but let's play with the various instances...
+ m1.invoke(); // the previous FeedManifold is sill valid and connected
+ CHECK (calcResult == 0 - 1); // and uses its baked in parameter value (0)
+ m1x.invoke();
+ CHECK (calcResult == r1 - 1); // as does m1x, without invoking the param-functor
+
+ // create yet another instance from the prototype...
+ M1 m1y = p1x.createFeed(turSys); // ◁————————— param-functor invoked here
+ CHECK (rr == m1y.param);
+ CHECK (r1 < m1y.param); // ...note again the side-effect
+ m1y.outBuff.createAt(0, buff);
+ m1y.connect();
+ m1y.invoke(); // ...and so this third FeedManifold instance...
+ CHECK (calcResult == rr - 1); // uses yet another baked-in param value;
+ m1x.invoke(); // recall that each Node invocation creates a new
+ CHECK (calcResult == r1 - 1); // FeedManifold on the stack, since invocations are
+ m1.invoke(); // performed concurrently, each with its own set of
+ CHECK (calcResult == 0 - 1); // buffers and parameters.
}
};
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index 48c107c6b..433b51247 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -26939,9 +26939,7 @@
-
-
-
+
b = 0.6180339887498948482
@@ -27630,9 +27628,7 @@
-
-
-
+
-
-
-
+
The device-space coordinate system is tied to the surface, and cannot change. The user-space coordinate system
@@ -28873,9 +28867,7 @@
-
-
-
+
Beispiel: Wenn der Typ selber keinen Support anbietet,
@@ -28908,9 +28900,7 @@
-
-
-
+
...denn diese Duck-Detector-Metafunktion bildet den Typ eines Member-Pointers,
@@ -30202,9 +30192,7 @@
-
-
-
+
Anmerkung 1/2023: seinerzeit habe ich die Mechanik der Layout-Zuteilung noch nicht wirklich verstanden
@@ -31593,9 +31581,7 @@
-
-
-
+
spezielle Regel gesetzt auf: .timeline-page > .timeline-body fork.timeline
@@ -32945,9 +32931,7 @@
-
-
-
+
d.h. wir müssen...
@@ -33686,9 +33670,7 @@
-
-
-
+
...darüber bin ich auch beim Zeichnen der Connector im StaveBracket gestolpert
@@ -33876,9 +33858,7 @@
-
-
-
+
-
@@ -34580,9 +34560,7 @@
-
-
-
+
...diese erstreckt sich typischerweise über die gesamte Länge des umschließenden Containers, und paßt sich dieser ohne weiteres dynamisch an
@@ -34960,9 +34938,7 @@
-
-
-
+
...habe ich aber noch nie getestet...
@@ -88756,8 +88732,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
auch Implementierung von all_buffers_released() fehlt
-
-
+
@@ -88765,8 +88740,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
Glorreich — testgetriebene Entwicklung und dann den wichtigen zentralen Test >10 Jahre lang auskommentiert rumstehen lassen
-
-
+
@@ -88792,8 +88766,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
also muß ich im BlockPool alles als released markieren
-
-
+
@@ -88837,6 +88810,9 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
@@ -91653,8 +91629,8 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
@@ -91695,17 +91671,19 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
-
-
+
+
-
+
+
+
@@ -91811,6 +91789,13 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
+
+
@@ -91872,7 +91857,8 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
+
@@ -91902,14 +91888,15 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
-
-
+
+
+
-
+
@@ -91984,7 +91971,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -92104,7 +92091,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -92112,9 +92099,9 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
-
+
@@ -92129,6 +92116,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
@@ -92222,24 +92210,29 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
-
-
+
+
+
+
+
-
-
+
+
+
+
+
+
@@ -92459,6 +92452,18 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
+
+
+
+
+
+
+
@@ -92490,24 +92495,52 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+ Name: prototype.moveAdapted (paramFun)
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
-
-
+
-
+
+
+
+
+
@@ -92520,6 +92553,32 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -92844,6 +92903,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
+
@@ -92919,7 +92979,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -99108,8 +99168,8 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -150185,7 +150245,7 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo
sieht aber soweit sauber aus...
- Wenngleich auch ziemlich elaboriert; all diese Tracking-Funktionalität war seinerzeit angelegt worden, aber nur oberflächlich getestet, weil der Render-Engine-Entwurf von 2012 letztlich steckengeblieben ist. Jetzt, 2024 beginne ich, den TrackingHeapBlockProvider zu für Tests zu nutzen, einfach weil er da ist — und stelle fest, daß einige Details unfertig und etwas unausgereift wirken....
+ Wenngleich auch ziemlich elaboriert; all diese Tracking-Funktionalität war seinerzeit angelegt worden, aber nur oberflächlich getestet, weil der Render-Engine-Entwurf von 2012 letztlich steckengeblieben ist. Jetzt, 2024 beginne ich, den TrackingHeapBlockProvider zu für Tests zu nutzen, einfach weil er da ist — und stelle fest, daß einige Details unfertig und etwas unausgereift wirken....