From f990f97c41eafd46a48c99d597c4b8154c6690e0 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 29 Dec 2024 03:23:59 +0100 Subject: [PATCH] Invocation: groundwork for a Parameter-Build-Spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...which in turn would then allow * to refer to extended parameters within scope * to build a Param(Agent)Node, which builds a parameter tuple by invoking the given parameter-functors Can now demonstrate in the test * define several »slots«, each with either value or functor * apply these functors to a `TurnoutSystem` --- src/common/integration/common-services.cpp | 15 +++++ src/lib/time/timecode.hpp | 3 + src/steam/engine/param-weaving-pattern.hpp | 47 +++++++++++++++ src/steam/engine/turnout-system.hpp | 9 +++ tests/core/steam/engine/node-feed-test.cpp | 26 ++++++++- wiki/thinkPad.ichthyo.mm | 67 ++++++++++++++++++---- 6 files changed, 153 insertions(+), 14 deletions(-) diff --git a/src/common/integration/common-services.cpp b/src/common/integration/common-services.cpp index cd205f491..d988e38ca 100644 --- a/src/common/integration/common-services.cpp +++ b/src/common/integration/common-services.cpp @@ -47,6 +47,7 @@ namespace error = lumiera::error; #include "lib/time/timequant.hpp" #include "lib/time/quantiser.hpp" +#include "lib/time/timecode.hpp" #include "lib/time/mutation.hpp" #include "common/advice.hpp" @@ -98,6 +99,20 @@ namespace time { return retrieveQuantiser (gridID); } + /** + * @remark Handles the common case to determine the frame number relative to some time grid. + * The regular path for this conversion would be to have a quantiser for this grid, + * to construct a QuTime and then a FrameNr instance based on this QuTime. Assuming + * that the grid is actually well-known and was registered via Advice-System with + * a symbolic ID, the quantiser can directly be retrieved and applied to convert. + */ + FrameCnt + FrameNr::quant (Time const& time, Symbol gridID) + { + return Quantiser::retrieve(gridID)->gridPoint (time); + } + + /** build a time mutation to \em nudge the target time value in steps based on a pre-defined grid. * @param adjustment number of grid steps to apply as offset diff --git a/src/lib/time/timecode.hpp b/src/lib/time/timecode.hpp index 4564bf8da..b5f7a68fa 100644 --- a/src/lib/time/timecode.hpp +++ b/src/lib/time/timecode.hpp @@ -107,6 +107,9 @@ namespace time { FrameNr (QuTime const& quantisedTime); + /** convenience shortcut: time grid to frame number */ + static FrameCnt quant (Time const&, Symbol gridID);// defined in common-services.cpp + using TCode::operator string; // CountVal implicitly convertible to long ///////////TICKET #882 : outch! should be a 64bit type! }; diff --git a/src/steam/engine/param-weaving-pattern.hpp b/src/steam/engine/param-weaving-pattern.hpp index 75e6a3b43..8eba9b5fe 100644 --- a/src/steam/engine/param-weaving-pattern.hpp +++ b/src/steam/engine/param-weaving-pattern.hpp @@ -43,6 +43,9 @@ #include "steam/engine/turnout.hpp" #include "steam/engine/turnout-system.hpp" #include "steam/engine/feed-manifold.hpp" ////////////TODO wegdamit +#include "lib/meta/function.hpp" +#include "lib/meta/variadic-helper.hpp" +#include "lib/meta/tuple-helper.hpp" /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation //#include "vault/gear/job.h" //#include "steam/engine/exit-node.hpp" @@ -64,6 +67,8 @@ namespace steam { namespace engine { using std::move; + using std::forward; + using std::make_tuple; using std::tuple; using lib::Several;////TODO RLY? @@ -73,11 +78,53 @@ namespace engine { { using Functors = tuple; + using ResTypes = typename lib::meta::ElmTypes::template Apply; + using ParamTup = lib::meta::Tuple; + Functors functors_; ParamBuildSpec (Functors&& funz) : functors_{move (funz)} { } + + template + auto + addSlot (FUN&& paramFun) + { + return ParamBuildSpec{std::tuple_cat (move(functors_) + ,make_tuple (forward(paramFun)))}; + } + + template + auto + addValSlot (PAR paramVal) + { + return addSlot ([paramVal](TurnoutSystem&){ return paramVal; }); + } + + template + class Slot + : util::MoveOnly + { + ParamBuildSpec& spec_; + + Slot (ParamBuildSpec& spec) + : spec_{spec} + { } + friend class ParamBuildSpec; + + public: + auto + invokeParamFun (TurnoutSystem& turnoutSys) + { + return std::get (spec_.functors_) (turnoutSys); + } + }; + + template + Slot + slot() + { return *this; } }; auto diff --git a/src/steam/engine/turnout-system.hpp b/src/steam/engine/turnout-system.hpp index 705aeaf80..178b76f03 100644 --- a/src/steam/engine/turnout-system.hpp +++ b/src/steam/engine/turnout-system.hpp @@ -62,6 +62,9 @@ namespace engine { { public: using FrontBlock = lib::HeteroData; + enum {SLOT_TIME = 0 + ,SLOT_KEY = 1 + }; private: FrontBlock invoParam_; @@ -70,6 +73,12 @@ namespace engine { TurnoutSystem (Time absoluteNominalTime, ProcessKey procKey =0) : invoParam_{FrontBlock::build (absoluteNominalTime,procKey)} { } + + Time + getNomTime() + { + return invoParam_.get(); + } }; diff --git a/tests/core/steam/engine/node-feed-test.cpp b/tests/core/steam/engine/node-feed-test.cpp index f594cbb3d..688589694 100644 --- a/tests/core/steam/engine/node-feed-test.cpp +++ b/tests/core/steam/engine/node-feed-test.cpp @@ -24,7 +24,9 @@ #include "steam/engine/turnout-system.hpp" #include "steam/engine/turnout.hpp" #include "steam/engine/diagnostic-buffer-provider.hpp" +#include "steam/asset/meta/time-grid.hpp" #include "lib/several-builder.hpp" +#include "lib/time/timecode.hpp" #include "lib/test/diagnostic-output.hpp"/////////////////////TODO //#include "lib/util.hpp" @@ -32,6 +34,8 @@ //using std::string; using lib::Several; using lib::makeSeveral; +using lib::time::Time; +using lib::time::FSecs; namespace steam { @@ -105,8 +109,26 @@ namespace test { void feedParamNode() { - auto spec = buildParamSpec(); -SHOW_TYPE(decltype(spec)) + steam::asset::meta::TimeGrid::build("grid_sec", 1); + + auto fun1 = [](TurnoutSystem& turSys) + { + return lib::time::FrameNr::quant (turSys.getNomTime(), "grid_sec"); + }; + + auto spec = buildParamSpec() + .addValSlot (LIFE_AND_UNIVERSE_4EVER) + .addSlot (move (fun1)) + ; + using Spec = decltype(spec); +SHOW_TYPE(Spec) +SHOW_TYPE(Spec::ParamTup) + + TurnoutSystem turnoutSys{Time{FSecs(5,2)}}; + auto v0 = spec.slot<0>().invokeParamFun (turnoutSys); + auto v1 = spec.slot<1>().invokeParamFun (turnoutSys); +SHOW_EXPR(v0) +SHOW_EXPR(v1) TODO ("implement a simple Builder for ParamAgent-Node"); TODO ("then use both together to demonstrate a param data feed here"); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 2a0e2741b..f14640f2d 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -86884,7 +86884,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

- Das muß so sein aus Gründen der logischen Konsistenz: Der Invocation-Mechanismus der Render-Engine ist generisch, und das bedeutet, er kann nichts implizit über das zu rendernde Modell wissen; zwar wird für den Build-Vorgang in absolute Placements  reduziert, aber diese beziehen sich immer noch auf eine bestimmte Timeline — ebenso wie der Render-Vorgang, der auf einer Timeline  abläuft. Das bedeutet, für den Rendervorgang ist das Koordinatensystem implizit, und er gibt nur eine absolute nominal Time relativ dazu an; jedoch wird dieser implizite Kontext in der Job-Planung übersetzt in den Zugriff auf eine bestimmte konkrete Exit-Node. Insofern kann dann ein Job komplett generisch auf der Render-Engine laufen, denn er tarnsportiert sowohl die absolute nominal Time, alsauch die konkrete ExitNode. Das Turnout-System selber ist ebenfalls generisch, und das heißt, es wird nur sinnvoll in Verbindung mit einer ExitNode zur Aufführung gebracht + Das muß so sein aus Gründen der logischen Konsistenz: Der Invocation-Mechanismus der Render-Engine ist generisch, und das bedeutet, er kann nichts implizit über das zu rendernde Modell wissen; zwar wird für den Build-Vorgang in absolute Placements reduziert, aber diese beziehen sich immer noch auf eine bestimmte Timeline — ebenso wie der Render-Vorgang, der auf einer Timeline abläuft. Das bedeutet, für den Rendervorgang ist das Koordinatensystem implizit, und er gibt nur eine absolute nominal Time relativ dazu an; jedoch wird dieser implizite Kontext in der Job-Planung übersetzt in den Zugriff auf eine bestimmte konkrete Exit-Node. Insofern kann dann ein Job komplett generisch auf der Render-Engine laufen, denn er tarnsportiert sowohl die absolute nominal Time, alsauch die konkrete ExitNode. Das Turnout-System selber ist ebenfalls generisch, und das heißt, es wird nur sinnvoll in Verbindung mit einer ExitNode zur Aufführung gebracht

@@ -88249,6 +88249,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

+ + @@ -88473,6 +88475,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + +

+ ...hab jetzt die Abkürzung eingebaut FrameNr::quant (time, "Grid") +

+

+ .... somit spart man sich das Konstruiren der QuTime, und einer FrameNr instanz, bloß um dann letztlich in einen int64_t umzuwandeln. Ich halte das für vertretbar, da dennoch das Grid explizit genannt sein muß... +

+ +
+ + +
@@ -94165,7 +94182,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -94175,8 +94192,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Zur Erinnerung: HeteroData ist ein low-level Daten-Layout, das ich speziell für den Anwendungsfall im Turnout mir ausgedacht habe; es beruht auf einer single-linked-List von Datenblöcken, in denen jeweils ein Datentupel sitzt. Und hier liegt das Problem: diese Chain-Blöcke sollen nun schrittweise über eine Builder-Notation aufgebaut werden — aber die Konstruktor-Funktion in HeteroData erwartet die Angabe des ganzen Tupel-Typs auf einmal.

- -
+
@@ -94205,8 +94221,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + +
@@ -94227,8 +94243,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
also ein Instanz-Typ allein legt alles fest; keine Indirektion oder Virtualisierung

- - +
@@ -94248,8 +94263,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
...weil wir allein mit einer solchen ParamBuildSpec auf ein TurnoutSystem losgehen wollen; eine Hetero-Data prefix-Chain ist damit notwendig, als Anker-Punkt um einen konkreten Konstruktor für einen Chain-Block zu generieren, den wir in den aktuellen StackFrame legen wollen

- -
+
@@ -94277,11 +94291,36 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
⟹ Ankerpunkt muß ein nested type TurnoutSystem::FrontBlock sein

- - +
+ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -97712,6 +97751,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + +