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 @@ - - - +

  • @@ -28112,9 +28108,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....