diff --git a/src/steam/engine/feed-manifold.hpp b/src/steam/engine/feed-manifold.hpp index 43310b4f7..60e3d097b 100644 --- a/src/steam/engine/feed-manifold.hpp +++ b/src/steam/engine/feed-manifold.hpp @@ -107,6 +107,7 @@ namespace engine { using lib::meta::_Fun; using lib::meta::enable_if; + using lib::meta::disable_if_self; using lib::meta::is_UnaryFun; using lib::meta::is_BinaryFun; using lib::meta::is_TernaryFun; @@ -240,56 +241,100 @@ namespace engine { using BuffO = typename ArgO::List::Head; using BuffI = typename std::conditional::type; /////////////////////////TODO obsolete ... remove after switch }; - - - - /** FeedManifold building block: hold parameter data */ - template - struct ParamStorage - { - using ParSig = typename _ProcFun::SigP; - ParSig param{}; - }; - - template - struct BufferSlot_Input - { - using BuffS = lib::UninitialisedStorage::FAN_I>; - using ArgSig = typename _ProcFun::SigI; - - BuffS inBuff; - ArgSig inArgs{}; - }; - - template - struct BufferSlot_Output - { - using BuffS = lib::UninitialisedStorage::FAN_O>; - using ArgSig = typename _ProcFun::SigO; - - BuffS outBuff; - ArgSig outArgs{}; - }; - - template - using NotProvided = Tagged; - - template - using Provide_if = std::conditional_t>; }//(End)Introspection helpers. + + template - struct FeedManifold_StorageSetup - : util::NonCopyable - , BufferSlot_Output - , Provide_if<_ProcFun::hasInput(), BufferSlot_Input> - , Provide_if<_ProcFun::hasParam(), ParamStorage> + struct _StorageSetup { + using _Trait = _ProcFun; + enum{ FAN_I = _Trait::FAN_I + , FAN_O = _Trait::FAN_O + }; + static constexpr bool hasInput() { return _Trait::hasInput(); } + static constexpr bool hasParam() { return _Trait::hasParam(); } + + using ParSig = typename _Trait::SigP; + + template + using BuffS = lib::UninitialisedStorage; + + using BuffI = BuffS; + using BuffO = BuffS; + + using ArgI = typename _Trait::SigI; + using ArgO = typename _Trait::SigO; + + + /** FeedManifold building block: hold parameter data */ + struct ParamStorage + { + ParSig param; + + ParamStorage() = default; + + template + ParamStorage (INIT&& ...paramInit) + : param{forward (paramInit)...} + { } + }; + + struct BufferSlot_Input + { + BuffI inBuff; + ArgI inArgs{}; + }; + + struct BufferSlot_Output + { + BuffO outBuff; + ArgO outArgs{}; + }; + + template + using enable_if_hasParam = typename lib::meta::enable_if_c<_ProcFun>::hasParam()>::Type; + + template + using NotProvided = Tagged; + + template + using Provide_if = std::conditional_t>; + + using FeedOutput = BufferSlot_Output; + using FeedInput = Provide_if; + using FeedParam = Provide_if; + + /** + * Data Storage block for the FeedManifold + * Flexibly configured based on the processing function. + */ + struct Storage + : util::NonCopyable + , FeedOutput + , FeedInput + , FeedParam + { + FUN process; + + template + Storage (F&& fun) + : process{forward (fun)} + { } + + template + , typename =enable_if_hasParam> + Storage (F&& fun, INIT&& ...paramInit) + : FeedParam{forward (paramInit)...} + , process{forward (fun)} + { } + }; }; + /** * Adapter to connect input/output buffers to a processing functor backed by an external library. * Essentially, this is structured storage tailored specifically to a given functor signature. @@ -314,27 +359,23 @@ namespace engine { template struct FeedManifold - : FeedManifold_StorageSetup + : _StorageSetup::Storage { - using _Trait = _ProcFun; - using _F = FeedManifold; + using _S = _StorageSetup; + using _F = typename _S::Storage; - static constexpr bool hasInput() { return _Trait::hasInput(); } - static constexpr bool hasParam() { return _Trait::hasParam(); } + /** pass-through constructor */ + using _S::Storage::Storage; - using ArgI = typename _Trait::SigI; - using ArgO = typename _Trait::SigO; - enum{ FAN_I = _Trait::FAN_I - , FAN_O = _Trait::FAN_O + using ArgI = typename _S::ArgI; + using ArgO = typename _S::ArgO; + enum{ FAN_I = _S::FAN_I + , FAN_O = _S::FAN_O }; + static constexpr bool hasInput() { return _S::hasInput(); } + static constexpr bool hasParam() { return _S::hasParam(); } - FUN process; - - template - FeedManifold (INIT&& ...funSetup) - : process{forward (funSetup)...} - { } template auto& @@ -375,14 +416,34 @@ namespace engine { invoke() { if constexpr (hasInput()) - process (_F::inArgs, _F::outArgs); + _F::process (_F::inArgs, _F::outArgs); else - process (_F::outArgs); + _F::process (_F::outArgs); } }; + /** + * Builder-Prototype to create FeedManifold instances. + * This »Prototype« becomes part of the Turnout / WeavingPattern + * and holds processing- and parameter-functor instances as configuration. + * The Processing-Functor will be copied into the actual FeedManifold instance + * for each Node invocation. + * @tparam FUN type of the data processing-functor + * @tparam PAM type of an optional parameter-setup functor + */ + template + class FeedPrototype + : util::MoveOnly + { + FUN procFun_; + PAM paramFun_; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1386 : elaborate setup / binding for parameter-creation + }; + + /** * Adapter to handle a simple yet common setup for media processing * - somehow we can invoke processing as a simple function diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp index 08febc229..5362e5565 100644 --- a/src/steam/engine/weaving-pattern-builder.hpp +++ b/src/steam/engine/weaving-pattern-builder.hpp @@ -103,6 +103,7 @@ #include "steam/engine/buffhandle-attach.hpp" /////////////////OOO why do we need to include this? we need the accessAs() template function #include "lib/test/test-helper.hpp" ////////////////////////////OOO TODO added for test #include "lib/format-string.hpp" +#include "lib/iter-zip.hpp" //#include "lib/util-foreach.hpp" //#include "lib/iter-adapter.hpp" //#include "lib/meta/function.hpp" @@ -125,6 +126,7 @@ namespace engine { // using lib::Literal; using lib::Several; using lib::Depend; + using lib::izip; using util::_Fmt; using util::max; @@ -238,7 +240,6 @@ namespace engine { * actual NodeBuilder and PortBuilder allows to introduce extension points * and helps to abstract away internal technical details of the invocation. * @tparam POL allocation and context configuration policy - * @tparam N maximum number of input and output slots * @tparam FUN function or invocation adapter to invoke */ template @@ -346,10 +347,10 @@ namespace engine { REQUIRE (providers.size() == buffTypes.size()); auto outTypes = DataBuilder{leadPorts.policyConnect()} .reserve (buffTypes.size()); - uint i=0; - for (auto& typeConstructor : buffTypes) + + for (auto& [i,typeConstructor] : izip(buffTypes)) outTypes.append ( - typeConstructor (providers[i++])); + typeConstructor (providers[i])); ENSURE (leadPorts.size() == FunSpec::FAN_I); ENSURE (outTypes.size() == FunSpec::FAN_O); diff --git a/tests/core/steam/engine/node-base-test.cpp b/tests/core/steam/engine/node-base-test.cpp index 7e12e6a40..523c83d9f 100644 --- a/tests/core/steam/engine/node-base-test.cpp +++ b/tests/core/steam/engine/node-base-test.cpp @@ -79,21 +79,13 @@ namespace test { void verify_FeedManifold() { - // some random numbers to test... + // Prepare setup to build a suitable FeedManifold... long r1 = rani(100); - - // Prepare setup to build a suitable FeedManifold using Buffer = long; -/////////////////////////////////////////////////////////////////////////////////TODO - using T1 = tuple; - using T2 = array; - using T3 = int; - using T4 = int*; - using T5 = lib::HeteroData; -/////////////////////////////////////////////////////////////////////////////////TODO - auto fun_singleOut = [&](Buffer* buff) { *buff = r1; }; + // Example-1: a FeedManifold to adapt a simple generator function + auto fun_singleOut = [&](Buffer* buff) { *buff = r1; }; using M1 = FeedManifold; CHECK (not M1::hasInput()); CHECK (not M1::hasParam()); @@ -188,17 +180,12 @@ namespace test { BuffHandle buffI0 = buff; BuffHandle buffI1 = buffOut; BuffHandle buffI2 = provider.lockBufferFor (-22); -SHOW_EXPR(buffI0.accessAs()) -SHOW_EXPR(buffI1.accessAs()) -SHOW_EXPR(buffI2.accessAs()) CHECK (buffI0.accessAs() == r1 ); // (result from Example-1) CHECK (buffI1.accessAs() == r1+1); // (result from Example-2) CHECK (buffI2.accessAs() == -55 ); ///////////////////////////////////////OOO should be -22 // prepare a compound buffer and an extra buffer for output... BuffHandle buffO0 = provider.lockBufferFor (Sequence{-111,-222,-333}); BuffHandle buffO1 = provider.lockBufferFor (-33); -SHOW_EXPR(util::join(buffO0.accessAs())) -SHOW_EXPR(buffO1.accessAs()) CHECK ((buffO0.accessAs() == Sequence{-111,-222,-333})); CHECK (buffO1.accessAs() == -55 ); ///////////////////////////////////////OOO should be -33 @@ -209,20 +196,10 @@ SHOW_EXPR(buffO1.accessAs()) m3.outBuff.createAt(0, buffO0); m3.outBuff.createAt(1, buffO1); m3.connect(); -SHOW_EXPR(m3.inArgs) -SHOW_EXPR(m3.outArgs) // Verify data exposed prior to invocation.... auto& [ia0,ia1,ia2] = m3.inArgs; auto& [oa0,oa1] = m3.outArgs; auto& [o00,o01,o02] = *oa0; -SHOW_EXPR(ia0) -SHOW_EXPR(ia1) -SHOW_EXPR(ia2) -SHOW_EXPR(oa0) -SHOW_EXPR(o00) -SHOW_EXPR(o01) -SHOW_EXPR(o02) -SHOW_EXPR(oa1) CHECK (*ia0 == r1 ); CHECK (*ia1 == r1+1); CHECK (*ia2 == -55 ); /////////////////////////////////////////////////////OOO should be -22 @@ -232,14 +209,6 @@ SHOW_EXPR(oa1) CHECK (*oa1 == -55 ); /////////////////////////////////////////////////////OOO should be -33 m3.invoke(); -SHOW_EXPR(ia0) -SHOW_EXPR(ia1) -SHOW_EXPR(ia2) -SHOW_EXPR(oa0) -SHOW_EXPR(o00) -SHOW_EXPR(o01) -SHOW_EXPR(o02) -SHOW_EXPR(oa1) CHECK (*ia0 == r1 ); // Input buffers unchanged CHECK (*ia1 == r1+1); CHECK (*ia2 == -55 ); /////////////////////////////////////////////////////OOO should be -22 diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index b31a37af1..11c8af763 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -82,9 +82,7 @@ - - - +

TODO: Infos zusammentragen und dokumentieren @@ -25760,9 +25758,7 @@ - - - +

weil nur sie durch ihren Display-Frame die beiden Kind-Widgets kennen @@ -26446,9 +26442,7 @@ - - - +

d.h. der Versuch, die Probleme geschickt wegzuabstrahieren. @@ -27066,9 +27060,7 @@ - - - +

Das liegt vielleicht auch an der etwas „alten“ Version von ca. 2018. @@ -27894,9 +27886,7 @@ - - - +

...um festzulegen, an welcher Stelle in der Hierarchie dieses Styling definiert ist; allerdings machen wir bereits genau dies für die Timeline im Allgemeinen (und zwar genau wegen dem custom-drawing) @@ -29003,9 +28993,7 @@ - - - +

weil nämlich der Trait, für den optimalen Fall, ebenfalls die EmptyBase verwendet, um den Mix-In zu deaktivieren. @@ -30881,9 +30869,7 @@ - - - +

weil dann innerhalb des Canvas alles konsistent ist @@ -31464,9 +31450,7 @@ - - - +

StyleContext::create() @@ -33078,9 +33062,7 @@ - - - +

  • @@ -34535,9 +34517,7 @@ - - - +

    ...und dieser muß einfach lokal im UI zu realisieren sein, also ein Stock-Icon und ggfs ein Vektorgraphic-Element @@ -35190,9 +35170,7 @@ - - - +

    es gibt bereits einen Sündenfall, nämlich im RelativeCanvasHook: der muß delegieren, und daher von außen diese Methode aufrufen @@ -35683,9 +35661,7 @@ - - - +

    es sieht so aus, als wäre es "das" WorkspaceWindow @@ -36302,9 +36278,7 @@ - - - +

    • @@ -51077,9 +51051,7 @@ - - - +

      das ist ein grundlegender Beschluß. @@ -91878,8 +91850,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      Die Signatur des Parameter-Funktors folgt eigentlich zwansläufig aus der gegebenen Processing-Function: es muß ein TurnoutSystem& akzeptiert und ein Parameter(Tupel) geliefert werden (by-value). Seiteneffekte im TurnoutSystem sind möglich (aber die Ausnahme)

      - -
      +
      @@ -92098,6 +92069,63 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      + + + + + + + +

      + ...das wäre die billige Lösung: man erzeugt es einfach immer per Default, und dann macht man im ctor-body in FeedManifold eine conditional und eine Zuweisung. Das ist insofern unsauber, da wir Zuweisbarkeit der Werte im Param-Tupel nicht fordern (sondern nur default-Konstruierbarkeit). +

      + +
      + +
      + + + + + + + + + + +

      + ...und die neueren Compiler können sich auch nicht beschweren, daß wir anonyme Typen in die Storage binden, und obendrein sind so die ganzen Meta-Definitionen wirklich downstream nicht mehr sichtbar +

      + + +
      +
      + + + + + + + + + + + + + + +

      + er versucht nämlich erst einmal, den getemplateten Ctor mit dem this-type zu instantiieren. Das ist dann hier F = struct Storage selber. In der enable-if-Klausel bilden wir aber _ProcFun<F> — und Storage ist ganz offensichtlich keine Funktion und löst die Assertion aus +

      + +
      +
      + + + + + +
      @@ -92120,6 +92148,166 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

      + beide Funktoren müssen in den Typ eingehen +

      + + +
      +
      + + + + + + + + + + + + + + + + + + +

      + wenngleich auch lediglich indirekt, denn der sichtbare Parameter ist FUN, der Typ der Processing-Function +

      + + +
      +
      + + + + + +
      + + + + +

      + neuer Name: FeedPrototype +

      + + +
      +
      + + + + + + + + + +

      + Wenn es also ein Param-Tupel gibt, entscheidet es sich im Aufruf-Kontext, ob dafür ein Init-Wert geliefert wird. Wenn nicht, dann findet Default-Initialisierung statt. Ganz einfach +

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

      + ⟹ geht in eine Builder-Klasse FeedPrototype<FUN,PAM> +

      + + +
      + +
      @@ -92508,6 +92711,36 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      + + + + + + + +

      + in den Turnout wird ein Prototyp der FeedManifold eingebettet +

      + + +
      + + + + + + + + + +

      + das heißt, idealerweise ist dieses ganze komplexe Konfigurations-Thema optional und transparent +

      + + +
      +
      +
      @@ -92524,7 +92757,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - + @@ -92533,6 +92766,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

      +
      @@ -92554,6 +92788,32 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      + + + + + + + + + + + + + + +

      + bekommt ggfs. ein zusätzliches Parameter-Tupel als ctor-Wert +

      + + +
      +
      + + + + +
      @@ -92572,6 +92832,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      + + + +