diff --git a/src/steam/engine/feed-manifold.hpp b/src/steam/engine/feed-manifold.hpp index 8f1f034e0..8869295a8 100644 --- a/src/steam/engine/feed-manifold.hpp +++ b/src/steam/engine/feed-manifold.hpp @@ -216,6 +216,10 @@ namespace engine { using ArgO = typename ElmTypes::Seq; using ArgP = typename ElmTypes::Seq; + // Metaprogramming helper for Buffer types (sans pointer) + using ElmsI = ElmTypes::template Apply>; + using ElmsO = ElmTypes::template Apply>; + enum{ FAN_I = ElmTypes::SIZ , FAN_O = ElmTypes::SIZ , FAN_P = ElmTypes::SIZ @@ -457,6 +461,7 @@ namespace engine { struct FeedManifold : _StorageSetup::Storage { + using _T = _ProcFun; using _S = _StorageSetup; using _F = typename _S::Storage; @@ -493,8 +498,8 @@ namespace engine { return arg; } - using TupI = typename ElmTypes::Tup; - using TupO = typename ElmTypes::Tup; + using TupI = typename _T::ElmsI::Tup; + using TupO = typename _T::ElmsO::Tup; void @@ -504,7 +509,7 @@ namespace engine { { forEachIDX ([&](auto i) { - using BuffI = remove_pointer_t>; + using BuffI = tuple_element_t; accessArg (_F::inArgs) = & _F::inBuff[i].template accessAs(); }); } @@ -512,7 +517,7 @@ namespace engine { { forEachIDX ([&](auto i) { - using BuffO = remove_pointer_t>; + using BuffO = tuple_element_t; accessArg (_F::outArgs) = & _F::outBuff[i].template accessAs(); }); } @@ -552,7 +557,7 @@ namespace engine { * parameter-functor with the **cross-builder-API**, a _new instance_ of the prototype * is created _as a replacement_ of the old one (note: we move the processing functor). * This adds a parameter-functor to the configuration, which will then be invoked - * _whenever a new FeedManifold instance_ [is created](\ref #createFeed); the result of + * _whenever a new FeedManifold instance_ [is created](\ref #buildFeed); the result of * this parameter-functor invocation should be a parameter value, which can be passed * into the constructor of FeedManifold, together with a copy of the proc-functor. * @see NodeBase_test::verify_FeedPrototype() @@ -561,13 +566,26 @@ namespace engine { class FeedPrototype : util::MoveOnly { + using _Proc = _ProcFun; using _Trait = _ParamFun; - using Feed = FeedManifold; FUN procFun_; PAM paramFun_; public: + using Feed = FeedManifold; + enum{ FAN_I = Feed::FAN_I + , FAN_O = Feed::FAN_O + , FAN_P = Feed::FAN_P + }; + using ElmsI = typename _Proc::ElmsI; + using ElmsO = typename _Proc::ElmsO; + + template class META> + using OutTypesApply = typename ElmsO::template Apply; + + + /** setup with processing-functor only */ FeedPrototype (FUN&& proc) : procFun_{move (proc)} , paramFun_{} @@ -583,16 +601,16 @@ namespace engine { static constexpr bool hasParamFun() { return _Trait::template isParamFun(); } static constexpr bool canActivate() { return _Trait::template canActivate(); } - /** @return runtime test: there is actually usable parameter-functor to invoke? */ + /** @return runtime test: actually usable parameter-functor available to invoke? */ bool isActivated() const { return _Trait::isActivated(paramFun_); } /************************************************************//** - * build suitable Feed(Manifold) for processing a Node invocation + * create suitable Feed(Manifold) for processing a Node invocation */ Feed - createFeed (TurnoutSystem& turnoutSys) + buildFeed (TurnoutSystem& turnoutSys) { if constexpr (hasParamFun()) if (isActivated()) diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp index f3c4b2dc3..81c86e79c 100644 --- a/src/steam/engine/node-builder.hpp +++ b/src/steam/engine/node-builder.hpp @@ -361,7 +361,7 @@ namespace engine { completePort() { weavingBuilder_.connectRemainingInputs (_Par::leads_, this->defaultPort_); - weavingBuilder_.fillRemainingBufferTypes(); + weavingBuilder_.fillRemainingBufferTypes(); ////////////////////////////////////////////////////////////////////OOO Nein! sollte gleich zu Beginn (automatisch) passieren return NodeBuilder{static_cast&&> (*this) // slice away PortBulder subclass data ,weavingBuilder_.sizMark ,weavingBuilder_.build()}; diff --git a/src/steam/engine/turnout.hpp b/src/steam/engine/turnout.hpp index c648b0862..2ec2fb055 100644 --- a/src/steam/engine/turnout.hpp +++ b/src/steam/engine/turnout.hpp @@ -76,7 +76,9 @@ namespace engine { constexpr bool _verify_usable_as_InvocationAdapter() { - ASSERT_MEMBER_FUNCTOR (&ADA::connect, void(uint, uint)); + // also: array-like outBuff + // optionally array-like inBuff + ASSERT_MEMBER_FUNCTOR (&ADA::connect, void()); ASSERT_MEMBER_FUNCTOR (&ADA::invoke, void()); return sizeof(ADA); } @@ -87,7 +89,7 @@ namespace engine { _verify_usable_as_WeavingPattern() { using Feed = typename PAT::Feed; - ASSERT_MEMBER_FUNCTOR (&PAT::mount, Feed()); + ASSERT_MEMBER_FUNCTOR (&PAT::mount, Feed(TurnoutSystem&)); ASSERT_MEMBER_FUNCTOR (&PAT::pull, void(Feed&, TurnoutSystem&)); ASSERT_MEMBER_FUNCTOR (&PAT::shed, void(Feed&, OptionalBuff)); ASSERT_MEMBER_FUNCTOR (&PAT::weft, void(Feed&)); @@ -129,7 +131,7 @@ namespace engine { BuffHandle weave (TurnoutSystem& turnoutSys, OptionalBuff outBuff =std::nullopt) override { - Feed feed = PAT::mount(); + Feed feed = PAT::mount(turnoutSys); PAT::pull(feed, turnoutSys); PAT::shed(feed, outBuff); PAT::weft(feed); diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp index 5362e5565..69ae81e17 100644 --- a/src/steam/engine/weaving-pattern-builder.hpp +++ b/src/steam/engine/weaving-pattern-builder.hpp @@ -101,6 +101,7 @@ #include "steam/engine/weaving-pattern.hpp" #include "steam/engine/buffer-provider.hpp" #include "steam/engine/buffhandle-attach.hpp" /////////////////OOO why do we need to include this? we need the accessAs() template function +#include "lib/meta/tuple-helper.hpp" #include "lib/test/test-helper.hpp" ////////////////////////////OOO TODO added for test #include "lib/format-string.hpp" #include "lib/iter-zip.hpp" @@ -225,8 +226,8 @@ namespace engine { - template - using SimpleDirectInvoke = MediaWeavingPattern>; +// template +// using SimpleDirectInvoke = MediaWeavingPattern>; /** @@ -246,11 +247,13 @@ namespace engine { struct WeavingBuilder : util::MoveOnly { - using FunSpec = _ProcFun; - using TurnoutWeaving = Turnout>; + using FunSpec = _ProcFun; ///////////////////////////////////TODO remove this!!! + using Prototype = typename FeedManifold::Prototype; + using WeavingPattern = MediaWeavingPattern; + using TurnoutWeaving = Turnout; static constexpr SizMark sizMark{}; - static constexpr uint FAN_I = FunSpec::FAN_I; - static constexpr uint FAN_O = FunSpec::FAN_O; + static constexpr uint FAN_I = Prototype::FAN_I; + static constexpr uint FAN_O = Prototype::FAN_O; using TypeMarker = std::function; @@ -271,6 +274,7 @@ namespace engine { template WeavingBuilder(FUN&& init, StrView nodeSymb, StrView portSpec, INIT&& ...alloInit) : leadPorts{forward (alloInit)...} + , buffTypes{fillDefaultBufferTypes()} , nodeSymb_{nodeSymb} , portSpec_{portSpec} , fun_{move(init)} @@ -305,11 +309,16 @@ namespace engine { return move(*this); } + /** @deprecated handling of output buffer configuration should be "the other way round": + * Instead of filling-in, a default should be established at start, + * which can then arbitrarily be refined + */ WeavingBuilder&& - fillRemainingBufferTypes() + fillRemainingBufferTypes() ///////////////////////////////////////////////////OOO Buffer-Typen gleich zu Beginn default-belegen { using BuffO = typename FunSpec::BuffO; uint cnt = FAN_O - buffTypes.size(); +ENSURE (cnt == 0); ///////////////////////////////////////////////////////////////////OOO already filled in constructor now -- remove this code return appendBufferTypes(cnt); } @@ -352,8 +361,8 @@ namespace engine { outTypes.append ( typeConstructor (providers[i])); - ENSURE (leadPorts.size() == FunSpec::FAN_I); - ENSURE (outTypes.size() == FunSpec::FAN_O); + ENSURE (leadPorts.size() == FAN_I); + ENSURE (outTypes.size() == FAN_O); using PortDataBuilder = DataBuilder; // provide a free-standing functor to build a suitable Port impl (≙Turnout) @@ -381,6 +390,59 @@ namespace engine { for (uint i=providers.size(); i < maxSlots; ++i) providers.emplace_back (ctx().mem); } + + /** + * @internal configuration builder for buffer descriptors + * @tparam BU target type of the buffer (without pointer) + * The FeedPrototype can generate for the given \a FUN a + * type sequence of output buffer types, which are used + * to instantiate this template and then later to work + * on specific output buffer slots. + */ + template + struct BufferDescriptor + { + /** + * Setup the constructor function for the default BufferDescriptors. + * @return a functor that can be applied to the actual BufferProviders + * at the point when everything for this port is configured. + */ + TypeMarker + makeBufferDescriptor() const + { + return [](BufferProvider& provider) + { return provider.getDescriptor(); }; + } + }; + + using OutTypesDescriptors = typename Prototype::template OutTypesApply; + using OutDescriptorTup = lib::meta::Tuple; + + /** A tuple of BufferDescriptor instances for all output buffer types */ + static constexpr OutDescriptorTup outDescriptors{}; + + /** @internal pre-initialise the buffTypes vector with a default configuration. + * @remarks In the _terminal step,_ the buffTypes will be transformed into a + * sequence of BufferDescriptor entries, which can later be used + * by the node invocation to prepare a set of output buffers. + * - each slot holds a function + * - these can be used to configure specific setup for some buffers + * - the default BufferDescriptor will just default-construct the + * designated «output slot» of the media processing-function. + */ + static auto + fillDefaultBufferTypes() + { + std::vector defaultBufferTypes; + defaultBufferTypes.reserve (std::tuple_size_v); + lib::meta::forEach(outDescriptors + ,[&](auto& desc) + { + defaultBufferTypes.emplace_back( + desc.makeBufferDescriptor()); + }); + return defaultBufferTypes; + } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : (End)Prototyping: how to assemble a Turnout diff --git a/src/steam/engine/weaving-pattern.hpp b/src/steam/engine/weaving-pattern.hpp index cfe80ce53..84fea30b5 100644 --- a/src/steam/engine/weaving-pattern.hpp +++ b/src/steam/engine/weaving-pattern.hpp @@ -85,10 +85,12 @@ namespace engine { * @note assumptions made regarding the overall structure * - `INVO::Feed` defines an _invocation adapter_ for the processing function * - `INVO::buildFeed()` is a functor to (repeatedly) build `Feed` instances - * - the _invocation adapter_ in turn embeds a `FeedManifold` to hold - * + an array of input buffer pointers - * + an array of output buffer pointers - * + `INVO::MAX_SIZ` limits both arrays + * - the _invocation adapter_ in turn embeds a `FeedManifold` to hold + * + a setup of output buffer pointers (single, tuple or array) + * + (optionally) a similar setup for input buffer pointers + * + (optionally) a parameter or parameter tuple + * + storage to configure BuffHandle entries for each «slot» + * + storage to hold the actual processing functor */ template struct MediaWeavingPattern @@ -117,32 +119,35 @@ namespace engine { Feed - mount() + mount (TurnoutSystem& turnoutSys) { - return INVO::buildFeed(); + ENSURE (leadPort.size() <= INVO::FAN_I); + ENSURE (outTypes.size() <= INVO::FAN_O); + return INVO::buildFeed (turnoutSys); } void pull (Feed& feed, TurnoutSystem& turnoutSys) { - for (uint i=0; i() == -55); @@ -370,7 +370,7 @@ namespace test { CHECK (not P1x::canActivate()); P1x p1x = p1.moveAdapted (move(fun_paramSimple)); - M1 m1x = p1x.createFeed(turSys); // ◁————————— param-functor invoked here + M1 m1x = p1x.buildFeed(turSys); // ◁————————— param-functor invoked here CHECK (rr == m1x.param); // ...as indicated by the side-effect short r1 = m1x.param; @@ -387,7 +387,7 @@ namespace test { 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 + M1 m1y = p1x.buildFeed(turSys); // ◁————————— param-functor invoked here CHECK (rr == m1y.param); CHECK (r1 < m1y.param); // ...note again the side-effect m1y.outBuff.createAt(0, buff); @@ -423,18 +423,18 @@ namespace test { CHECK (not p1f.isActivated()); // yet in current runtime configuration, the function is empty // create a FeedManifold instance from this prototype - M1 m1f1 = p1f.createFeed(turSys); // no param-functor invoked, + M1 m1f1 = p1f.buildFeed(turSys); // no param-functor invoked, CHECK (m1f1.param == short{}); // so this FeedManifold will use the default-constructed parameter // but since std::function is assignable, we can activate it... CHECK (not p1f.isActivated()); p1f.assignParamFun ([](TurnoutSystem&){ return 47; }); CHECK ( p1f.isActivated()); - M1 m1f2 = p1f.createFeed(turSys); // ◁————————— param-functor invoked here + M1 m1f2 = p1f.buildFeed(turSys); // ◁————————— param-functor invoked here CHECK (m1f2.param == 47); // ...surprise: we got number 47... p1f.assignParamFun(); CHECK (not p1f.isActivated()); // can /deactivate/ it again... - M1 m1f3 = p1f.createFeed(turSys); // so no param-functor invoked here + M1 m1f3 = p1f.buildFeed(turSys); // so no param-functor invoked here CHECK (m1f3.param == short{}); // done with buffer diff --git a/tests/core/steam/engine/node-link-test.cpp b/tests/core/steam/engine/node-link-test.cpp index 86edfbc00..2d4bcea91 100644 --- a/tests/core/steam/engine/node-link-test.cpp +++ b/tests/core/steam/engine/node-link-test.cpp @@ -112,7 +112,7 @@ SHOW_EXPR(metaN1.genNodeSpec(con.leads)) /** @test TODO Use existing node connectivity to generate a TurnoutSystem - * @todo WIP 7/24 🔁 define ⟶ implement + * @todo WIP 12/24 🔁 define ⟶ implement */ void generate_turnout_system() @@ -122,7 +122,7 @@ SHOW_EXPR(metaN1.genNodeSpec(con.leads)) /** @test TODO Invoke some render nodes as linked together - * @todo WIP 7/24 🔁 define ⟶ implement + * @todo WIP 12/24 🔁 define ⟶ implement */ void trigger_node_port_invocation() diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index fbfd0a054..f616fad8a 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -1,6 +1,6 @@ - + @@ -27563,9 +27563,7 @@ - - - +

TrackHeadWidget::syncSubtrackStartHeight (uint directHeight) @@ -27950,9 +27948,7 @@ - - - +

@@ -28223,9 +28219,7 @@ - - - +

Mehrere Aspekte sind hier offen (2023: Abschluß der GUI-Neugründung und vor Playback-Vertical-Slice): @@ -28923,9 +28917,7 @@ - - - +

weil ich dann explizit ein bestimmtes Basis-Interface verlangen werde, @@ -29584,9 +29576,7 @@ - - - +

commit 09714cfe28739ceff0b5693447be41166c1cc8d6 @@ -30927,9 +30917,7 @@ - - - +

wir können nicht von 0 bis MAXINT zeichnen @@ -31152,9 +31140,7 @@ - - - +

....und dient damit als Vorlage für Theme-Autoren @@ -32154,9 +32140,7 @@ - - - +

und zwar für bestimmte Elemente (Konvention) @@ -33109,9 +33093,7 @@ - - - +

weil dann der Platz für den "pinned" Ruler redundant im Body-Canvas vorhanden ist! @@ -33815,9 +33797,7 @@ - - - +

nämlich eine abgekürzte Übersichts-Darstellung, die wohl ehr auf der Basis ganzer Tracks zu zeichnen wäre (Tracks deshalb, weil wir eine Abkürzungs-Darstellung  der Tracks selber nicht vorsehen) @@ -34376,9 +34356,7 @@ - - - +

aktive Elemente im Clip-Widget lösen UI-Signale aus, die eine abstrahierte Funktion aufrufen — und diese gebundene Funktion (zumindest der Einsprungpunkt) liegt im Clip-Presenter @@ -91519,9 +91497,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + @@ -91529,8 +91507,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -91595,7 +91573,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -91629,6 +91607,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + @@ -91869,8 +91852,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
jetzt bin ich bereits so weit gekommen, und hab den größten Teil der Komplexität in die FeedManifold verlagert....

- -
+
@@ -91917,14 +91899,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Dieser Trait erbringt keine so hohe Abstraktiosleistung wie _ProcFun; im Grunde könnte man auch allen diesen Code direkt in FeedPrototype schieben — es ist also mehr ein Vekikel zur Code-Organisation, räumt die low-level-Details weg und macht sie auch leichter testbar

- - +
- - + + @@ -92139,8 +92120,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -92285,8 +92266,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -92297,16 +92279,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + - + @@ -92317,7 +92299,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -92448,8 +92431,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
prototype.moveAdapted (paramFun) ⟶ move in neue FeedPrototype-Instanz

- - +
@@ -92460,8 +92442,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
prototype.clone() ⟶ Kopie falls beide Funktoren das erlauben

- - +
@@ -92480,7 +92461,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -92707,8 +92688,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
                             >;

- - +
@@ -92752,8 +92732,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + +

+ ...das war der Name im Prototyping-Entwurf, und der ist viel besser! +

+ + +
+ +
- + + @@ -92786,6 +92779,26 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +

+ FeedPrototype wird zur Gelenkstelle zum WeavingPatternBuilder +

+ +
+ +
+ + + + + + +
@@ -92794,7 +92807,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -92841,8 +92854,174 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + +

+ FeedPrototype wird zentraler Konfigurationspunkt +

+ +
+ + +
- + + + + +

+ «InvocationAdapter» ist nun stets die FeedManifold +

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

+ Output-Buffer-Typ-Default +

+

+ muß von unten kommen +

+ + +
+ + + + + +

+ hatte im Juli 24 noch keinerlei Durchblick und ging außerdem davon aus, direkt auf den Ergebnis-Daten in lib::SeveralBuilder zu arbeiten; daher der Ansatz mit "Einfüllen" +

+ +
+
+ + + + +

+ Im Gegensatz zur Konfiguration der Lead-Ports ist diese ganze Buffer-Belegungs-Thematik weitgehend undifferenziert — es ist nur klar daß wir von irgendwoher einen Buffer brauchen, und daß es typisierte BufferDeskcriptoren gibt. Also hatte ich seinerzeit (Juli 24) die Behandlung symmetrisch zur Eingangs-Seite aufgezogen, und erst mal eine default-Konfiguration für jeden »Slot« gemacht. Dann, mit dem Umbau der FeedManifold (Dezember 24) ergab sich Möglichkeit (und Notwendigkeit), jeden Ausgabe-Slot individuell zu konfigurieren +

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

+ diese Schachtel möchte ich nicht nach außen aufmachen... +

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

+ Ich möchte definitiv nicht +

+
    +
  • + daß auch nur der WeavingBuilder noch direkt mit der Typ-Repräsentation der FeedManifold herumfummelt +
  • +
  • + ich möchte aber auch nicht, daß der FeedPrototype nun maßgeschneiderte Daten für die Interna eines WeavingBuilders liefert +
  • +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + +

+ Lösung: Iteration über ein Buffer-Descriptor-Tupel +

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

+ Hat noch so einige Tücken, wiewohl es im Prinzip einfach ist +

+ +
+
+ + + + + + + + + + + + + + + + + + +
+
+
+ @@ -92860,8 +93039,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
die interne Logik ist so aufgebaut, daß sie sich dann durchgehend korrekt verhält, ohne daß dafür viel getan werden müßte; es muß lediglich eine Funktion sein, und kein brauchbares Ergebnis liefern

- - +
@@ -92903,6 +93081,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + +
@@ -92924,7 +93113,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -93143,7 +93332,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -93302,7 +93491,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -93448,6 +93637,285 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +

+ Strategie: während des Umbaues den alten downstream-Code compilierbar gehalten +

+ + +
+ + + +

+ und zwar, indem ich zunächst die Type-Traits umgestellt habe, und dann den alten Code auf das neue Traits-Inteface portiert. Damit konnte ich die alte Implementierung der FeedManifold (als "FoldManifeed" ☺) im Code erhalten — und alles was darunter hängt... +

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

+ Haha! Nur ist das jetzt eines der zentralen Gelenkstellen im FeedPrototype geworden — oh oh oh wenn das alles bloß nicht so spannend wäre, könnte man ja glatt anderen Leuten davon erzählen +

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

+ ich habe die Einbindung in ein fixed-size-Array der Größe N komplett aufgegeben, zugunsten einer flexiblen, Tuple-basierten Storage +

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

+ alle Argumente ab dem 4.Argument gehen pauschal durch an INVO +

+ + +
+ + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
    +
  • + der Prototype kann uns einen Tupel-Typ der Output-Buffer-Typen konstruieren +
  • +
  • + zusätzlich können wir ElmTypes<TUP>::Apply verwenden +
  • +
  • + damit kann man lokal im WeavingPatternBuilder ein »Handler-Template« für jeden Buffer-Typ instantiieren +
  • +
  • + in dieses könen wir die lokale Builder-Logik einbauen +
  • +
  • + und darauf auch laufzeit-indiziert zugreifen +
  • +
  • + oder statisch iterieren +
  • +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -93709,7 +94177,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -93735,6 +94204,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+
@@ -93893,7 +94363,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -94831,6 +95301,43 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + +

+ im WeavingBuilder: +

+

+ using TypeMarker = std::function<BuffDescr(BufferProvider&)>; +

+ +
+
+ + + + + + + + + + +
@@ -96216,7 +96723,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- +
@@ -99166,6 +99673,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + @@ -144581,8 +145092,7 @@ std::cout << tmpl.render({"what", "World"}) << s entscheiden

- - + @@ -144610,8 +145120,7 @@ std::cout << tmpl.render({"what", "World"}) << s Das bedeutet: ein Funktionspointer mit passender Signatur kann von einem λ initialisiert werden und kann dann die dahinter stehende Funktion aufrufen. Vermutlich als Kompatibilität zu C-Callbacks gedacht....

- - +