From 8a4060861ff1a20c4c94b2c1c6d3077630d2efaf Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 18 Feb 2025 23:55:58 +0100 Subject: [PATCH] Invocation: complete simple test case regarding `TurnoutSystem` NodeBase_test demonstrates the building blocks of a Render Node, and verifies low-level mechanics of those building blocks, which can be quite technical. At the top of this test however are some very basic interactions, which serve as an introduction. __Remark__: renamed the low-level technical dispatch-access for the parameter-accessors in `TurnoutSystem` to be more obvious, and added comment (I was confused myself how to use them properly) --- src/lib/hetero-data.hpp | 4 +- src/steam/engine/node-builder.hpp | 2 +- src/steam/engine/param-weaving-pattern.hpp | 2 +- src/steam/engine/turnout-system.hpp | 19 ++++++- tests/core/steam/engine/node-base-test.cpp | 25 ++++++++- tests/core/steam/engine/node-feed-test.cpp | 4 +- tests/library/hetero-data-test.cpp | 22 ++++---- wiki/thinkPad.ichthyo.mm | 62 +++++++++++++++++----- 8 files changed, 107 insertions(+), 33 deletions(-) diff --git a/src/lib/hetero-data.hpp b/src/lib/hetero-data.hpp index 6aa231913..92513a280 100644 --- a/src/lib/hetero-data.hpp +++ b/src/lib/hetero-data.hpp @@ -217,14 +217,14 @@ namespace lib { template static Type& - get (HeteroData& frontEnd) + retrieveData (HeteroData& frontEnd) { auto& fullChain = _Self::recast (frontEnd); return fullChain.template get(); } template - Type& operator() (HH& frontEnd) const { return Accessor::get(frontEnd); } + Type& operator() (HH& frontEnd) const { return Accessor::retrieveData (frontEnd); } }; /** diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp index f6a59a304..29fdf5b1e 100644 --- a/src/steam/engine/node-builder.hpp +++ b/src/steam/engine/node-builder.hpp @@ -477,7 +477,7 @@ namespace engine { return attachParamFun ([accessor=forward(getter)] (TurnoutSystem& turnoutSys) { - return accessor.getParamVal (turnoutSys); + return turnoutSys.get(accessor); }); } diff --git a/src/steam/engine/param-weaving-pattern.hpp b/src/steam/engine/param-weaving-pattern.hpp index 27d12cd5a..24c68f5df 100644 --- a/src/steam/engine/param-weaving-pattern.hpp +++ b/src/steam/engine/param-weaving-pattern.hpp @@ -197,7 +197,7 @@ namespace engine { getParamVal (TurnoutSystem& turnoutSys) { using StorageAccessor = typename ChainCons::template Accessor; - return turnoutSys.get (StorageAccessor()); + return turnoutSys.retrieveData (StorageAccessor()); } }; diff --git a/src/steam/engine/turnout-system.hpp b/src/steam/engine/turnout-system.hpp index 13e3b1ade..2e6a2261f 100644 --- a/src/steam/engine/turnout-system.hpp +++ b/src/steam/engine/turnout-system.hpp @@ -86,13 +86,21 @@ namespace engine { return invoParam_.get(); } + /** + * get parameter from extension block, + * as configured by the provided getter functor + * @remark convenience front-end, will deflect to #retrieveData + * @warning only works if an extension block has been attached, + * terminates with unexpected exception else. + */ template auto& get (ACC const& getter) { - return getter.get (invoParam_); + return getter.getParamVal (*this); } + /** attach an extension block with further parameters * as HeteroData-chain to the embedded FrontBlock * @note structural properties must match, which @@ -111,6 +119,15 @@ namespace engine { { chainBlock.detachFrom (invoParam_); } + + /** @internal forward the call from a low-level accessor + * to the embedded anchor data block */ + template + auto& + retrieveData (ACC const& getter) + { + return getter(invoParam_); + } }; diff --git a/tests/core/steam/engine/node-base-test.cpp b/tests/core/steam/engine/node-base-test.cpp index 824d008ca..13c7b55de 100644 --- a/tests/core/steam/engine/node-base-test.cpp +++ b/tests/core/steam/engine/node-base-test.cpp @@ -23,6 +23,7 @@ #include "steam/engine/turnout.hpp" #include "steam/engine/turnout-system.hpp" #include "steam/engine/feed-manifold.hpp" +#include "steam/engine/node-builder.hpp" #include "steam/engine/diagnostic-buffer-provider.hpp" #include "steam/engine/buffhandle-attach.hpp" #include "lib/test/test-helper.hpp" @@ -73,7 +74,29 @@ namespace test { { Time nomTime{rani(10'000),0}; // drive test with a random »nominal Time« <10s with ms granularity TurnoutSystem invoker{nomTime}; // a time spec is mandatory, all further parameters are optional - ////////////////////////////////OOO unfinished - demonstrate simple accesses to the TurnoutSystem + + CHECK (invoker.getNomTime() == nomTime); // can access those basic params from within the render invocation. + CHECK (invoker.getProcKey() == ProcessKey{}); + + /* == That's all required for basic usage. == */ + + + // Demonstrate extension-block to TurnoutSystem + // Used to setup elaborate parameter-nodes. + double someVal = defaultGen.uni(); // some param value, computed by »elaborate logic« + auto spec = buildParamSpec() + .addValSlot (someVal); // declare a parameter slot for an extension data block + auto acc0 = spec.makeAccessor<0>(); // capture an accessor-functor for later use + + {// Build and connect extension storage block + auto dataBlock = + spec.makeBlockBuilder() + .buildParamDataBlock(invoker); + + invoker.attachChainBlock (dataBlock); // link extension data block into the TurnoutSystem + CHECK (invoker.get(acc0) == someVal); // now able to retrieve data from extension block + invoker.detachChainBlock (dataBlock); + } } diff --git a/tests/core/steam/engine/node-feed-test.cpp b/tests/core/steam/engine/node-feed-test.cpp index cc1b1a7db..43933bebf 100644 --- a/tests/core/steam/engine/node-feed-test.cpp +++ b/tests/core/steam/engine/node-feed-test.cpp @@ -210,8 +210,8 @@ namespace test { auto accessParam = [acc0,acc1] (TurnoutSystem& turnoutSys) -> Param { - return make_tuple (acc0.getParamVal (turnoutSys) - ,acc1.getParamVal (turnoutSys)); + return make_tuple (turnoutSys.get(acc0) + ,turnoutSys.get(acc1)); }; ProcNode delegate{prepareNode("Delegate") diff --git a/tests/library/hetero-data-test.cpp b/tests/library/hetero-data-test.cpp index 0dd4de274..fbd87afea 100644 --- a/tests/library/hetero-data-test.cpp +++ b/tests/library/hetero-data-test.cpp @@ -211,7 +211,7 @@ namespace test{ // Note the pitfall: Chain has not been connected yet, // but the Accessors would assume otherwise - CHECK (Acc2::get(front) == 2.3); + CHECK (Acc2::retrieveData(front) == 2.3); // Acc3::get(front); // would cause NPE (or assertion failure on debug build) Acc4 get4; // could even instantiate the accessors... @@ -220,10 +220,10 @@ namespace test{ // Now link the second data element in properly d2.linkInto(front); - CHECK (Acc1::get(front) == 0); - CHECK (Acc2::get(front) == 2.3); - CHECK (Acc3::get(front) == false); - CHECK (get4(front) == "Ψ"); + CHECK (Acc1::retrieveData(front) == 0); + CHECK (Acc2::retrieveData(front) == 2.3); + CHECK (Acc3::retrieveData(front) == false); + CHECK (get4(front) == "Ψ"); // further allocations can even be »elsewhere« const void* loc; @@ -262,12 +262,12 @@ namespace test{ CHECK (d2.get<0>() == true); CHECK (d2.get<1>() == "Ψ"); - CHECK (isSameAdr (Acc1::get(front), v1)); - CHECK (isSameAdr (Acc2::get(front), v2)); - CHECK (isSameAdr (Acc3::get(front), v3)); - CHECK (isSameAdr (Acc4::get(front), v4)); - CHECK (isSameAdr (Acc5::get(front), v5)); - CHECK (isSameAdr (Acc6::get(front), v6)); + CHECK (isSameAdr (Acc1::retrieveData(front), v1)); + CHECK (isSameAdr (Acc2::retrieveData(front), v2)); + CHECK (isSameAdr (Acc3::retrieveData(front), v3)); + CHECK (isSameAdr (Acc4::retrieveData(front), v4)); + CHECK (isSameAdr (Acc5::retrieveData(front), v5)); + CHECK (isSameAdr (Acc6::retrieveData(front), v6)); CHECK (not isSameAdr (front, v1)); CHECK (not isSameAdr (d2, v3)); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 83ac4fb5c..eae0c6b7c 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -91830,6 +91830,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + @@ -92397,6 +92403,35 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + +

+ Alle Parameter einer processing-function sind in ein einziges Tupel zusammengefaßt, aber typischerweise sind einige technisch, während andere die gestalterischen Steuermöglichkeiten der Operation repräsentieren. Beide Aspekte müssen auf dem gleichen NodeBuilder konfiguriert werden, aber aus verschiedenen Quellen (und vermutlich auch in verschiedenen Schritten) +

+ + +
+
+ + + + + + +

+ implementiert auf Basis der partial-function-closure +

+ + +
+
+
@@ -105745,12 +105780,13 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + + - + @@ -105760,8 +105796,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) AUA!‼ Hammer auf den letzten Metern

- -
+ @@ -105806,9 +105841,9 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - - + + + @@ -105817,7 +105852,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -105859,7 +105894,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -105930,8 +105965,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) daß wir jetzt eine std::function erzeugen ist hier ganz furchbar

- -
+ @@ -106017,7 +106051,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
- + @@ -106122,7 +106156,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -106373,7 +106407,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - +