diff --git a/src/lib/meta/function.hpp b/src/lib/meta/function.hpp index 040309de1..a6df90aa3 100644 --- a/src/lib/meta/function.hpp +++ b/src/lib/meta/function.hpp @@ -216,6 +216,9 @@ namespace meta{ template using is_BinaryFun = has_Arity; + template + using is_TernaryFun = has_Arity; + diff --git a/src/steam/engine/feed-manifold.hpp b/src/steam/engine/feed-manifold.hpp index 307d6d509..7fcc86b75 100644 --- a/src/steam/engine/feed-manifold.hpp +++ b/src/steam/engine/feed-manifold.hpp @@ -75,6 +75,7 @@ #include "steam/engine/buffhandle.hpp" #include "lib/uninitialised-storage.hpp" #include "lib/meta/function.hpp" +#include "lib/meta/typeseq-util.hpp" //#include "lib/several.hpp" //#include @@ -92,8 +93,42 @@ namespace engine { namespace {// Introspection helpers.... using lib::meta::_Fun; + using lib::meta::is_UnaryFun; using lib::meta::is_BinaryFun; + using lib::meta::is_TernaryFun; using std::remove_reference_t; + using lib::meta::enable_if; + using std::void_t; + using std::__and_; + using std::__not_; + + template + struct is_Structured + : std::false_type + { }; + template + struct is_Structured>> + : std::true_type + { }; + + template + struct is_Value + : __and_<__not_> + ,__not_> + ,__not_> + ,std::is_default_constructible + ,std::is_copy_assignable + > + { }; + + template + struct is_Buffer + : __and_<__not_> + ,__not_> + ,std::is_default_constructible + ,__not_<_Fun> + > + { }; /** Helper to pick up the parameter dimensions from the processing function * @remark this is the rather simple yet common case that media processing @@ -107,32 +142,78 @@ namespace engine { struct _ProcFun { static_assert(_Fun() , "something funktion-like required"); - static_assert(is_BinaryFun() , "function with two arguments expected"); + static_assert(0 < _Fun::ARITY , "function with at least one argument expected"); + static_assert(3 >= _Fun::ARITY , "function with up to three arguments accepted"); using Sig = typename _Fun::Sig; - template - struct MatchBuffArray + template + using _Arg = typename lib::meta::Pick::Args, i>::Type; + + + template + struct _ArgTrait { - static_assert(not sizeof(ARG), "processing function expected to take array-of-buffer-pointers"); + static_assert(not sizeof(ARG), "processing function expected to take parameters, " + "buffer-poiinters or tuples or arrays of these"); + }; + template + struct _ArgTrait>> + { + using Buff = PAR; ////////////////////////////////OOO not correct, remove this! + enum{ SIZ = 1 }; + }; + template + struct _ArgTrait>> + { + using Buff = BUF; + enum{ SIZ = 1 }; }; template - struct MatchBuffArray> + struct _ArgTrait> { using Buff = BUF; enum{ SIZ = N }; }; - using SigI = remove_reference_t::Args::List::Head>; - using SigO = remove_reference_t::Args::List::Tail::Head>; - using BuffI = typename MatchBuffArray::Buff; - using BuffO = typename MatchBuffArray::Buff; + template + struct _Case + { + static_assert(not sizeof(SIG), "use case could not be determined from function stignature"); + }; + template + struct _Case>> + { + enum{ SLOT_O = 0 + , SLOT_I = 0 + }; + }; + template + struct _Case>> + { + enum{ SLOT_O = 1 + , SLOT_I = is_Value<_Arg>()? 1 : 0 + }; + }; + template + struct _Case>> + { + enum{ SLOT_O = 2 + , SLOT_I = 1 + }; + }; - enum{ FAN_I = MatchBuffArray::SIZ - , FAN_O = MatchBuffArray::SIZ - , SLOT_I = 0 - , SLOT_O = 1 + using SigI = _Arg::SLOT_I>; + using SigO = _Arg::SLOT_O>; + + using BuffI = typename _ArgTrait::Buff; + using BuffO = typename _ArgTrait::Buff; + + enum{ FAN_I = _ArgTrait::SIZ + , FAN_O = _ArgTrait::SIZ + , SLOT_I = _Case::SLOT_I + , SLOT_O = _Case::SLOT_O , MAXSZ = std::max (uint(FAN_I), uint(FAN_O)) /////////////////////OOO required temporarily until the switch to tuples }; @@ -161,8 +242,8 @@ namespace engine { * @todo WIP-WIP-WIP 7/24 now reworking the old design in the light of actual render engine requirements... */ template - struct FeedManifold - : FeedManifold_StorageSetup + struct FoldManifeed + : util::NonCopyable { enum{ STORAGE_SIZ = _ProcFun::MAXSZ }; using BuffS = lib::UninitialisedStorage; @@ -171,6 +252,16 @@ namespace engine { BuffS outBuff; }; + template + struct FeedManifold + : FeedManifold_StorageSetup + { + using _Trait = _ProcFun; + + static constexpr bool hasInput() { return _Trait::hasInput(); } + static constexpr bool hasParam() { return _Trait::hasParam(); } + }; + /** diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp index 37b76b42d..08febc229 100644 --- a/src/steam/engine/weaving-pattern-builder.hpp +++ b/src/steam/engine/weaving-pattern-builder.hpp @@ -145,7 +145,7 @@ namespace engine { : util::MoveOnly { enum{ MAX_SIZ = _ProcFun::MAXSZ }; - using Manifold = FeedManifold; + using Manifold = FoldManifeed; ////////////////////////////////////////////////////OOO temporary fork between old-style and new-style implementation using Feed = SimpleFunctionInvocationAdapter; std::function buildFeed; diff --git a/tests/core/steam/engine/node-base-test.cpp b/tests/core/steam/engine/node-base-test.cpp index fece463ad..f7c2d41bb 100644 --- a/tests/core/steam/engine/node-base-test.cpp +++ b/tests/core/steam/engine/node-base-test.cpp @@ -22,6 +22,7 @@ #include "steam/engine/proc-node.hpp" #include "steam/engine/turnout.hpp" #include "steam/engine/turnout-system.hpp" +#include "steam/engine/feed-manifold.hpp" //#include "lib/format-cout.hpp" //#include "lib/util.hpp" @@ -50,6 +51,7 @@ namespace test { { seedRand(); verify_TurnoutSystem(); + verify_FeedManifold(); UNIMPLEMENTED ("build a simple render node and then activate it"); } @@ -61,6 +63,24 @@ 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 } + + + /** @test the FeedManifold as adapter between Engine and processing library + */ + void + verify_FeedManifold() + { + // some random numbers to test... + long r1 = rani(100); + + // Type setup to build a suitable FeedManifold + using Buffer = long; + + auto fun_singleOut = [&](Buffer* buff) { *buff = r1; }; + using M1 = FeedManifold; + CHECK (not M1::hasInput()); + CHECK (not M1::hasParam()); + } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 079b4b8c0..39418e99a 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -23820,9 +23820,7 @@ - - - +

Grundlagen müssen vor GTK's Behandlung erfolgen @@ -24335,9 +24333,7 @@ - - - +

Nein: keine Abhängigkeiten, @@ -24872,9 +24868,7 @@ - - - +

die Kontrollstruktur ist bereits gefährlich komplex; spezielle "Schleifen" durch die Innereien eigentlich nicht involvierter Entitäten allein aus Performance-Gründen sollten vermieden werden @@ -25679,9 +25673,7 @@ - - - +

denn er erzwingt entweder.... @@ -26948,9 +26940,7 @@ - - - +

ich kann zwar einrasten, aber ich kann weder um einen definierten Punkt drehen, noch kann ich Schnittpunkte ermitteln @@ -28548,9 +28538,7 @@ - - - +

Unterscheidung verschoben in die Darstellung @@ -29562,9 +29550,7 @@ - - - +

weil man damit eine generische Klammer bauen kann @@ -32422,9 +32408,7 @@ - - - +

Kommentar sagt: it is your responsibility that these two coordinates match @@ -33870,9 +33854,7 @@ - - - +

man soll ohnehin keinen so großen box-shadow verwenden @@ -35809,9 +35791,7 @@ - - - +

....erzeugt wird das hier: @@ -37216,9 +37196,7 @@ - - - +

naja... sie besteht schon von Anfang an, insofern das Event-Konzept, wie auch die konkrete Quelle, ohnehin an das UI-Framework gebunden sind @@ -37697,9 +37675,7 @@ - - - +

...denn ich will ja grade unnötige Storage-Slots für Rückpointer und sonstige Flags vermeiden; daher besteht eine Gesten-Konfiguration nur darin, irgendwo ganz versteckt ein Signal auf das Widget verdrahtet zu haben... @@ -38509,9 +38485,7 @@ - - - +

im Gegensatz zum CanvasHook ist das hier durchaus relevant @@ -38787,9 +38761,7 @@ - - - +

...sonst würde entweder das Subject selber ad hoc etwas bereitstellen müssen und dafür zusätzliche Storage brauchen (Hebel, es gibt sehr viele Subjekte!), oder das Interface "Subject" würde löchrig und zu einer Kodifizierung von Einzelfällen. Die Lösung mit dem Adapter stattdessen fällt unter das Prinzip Inversion of Control @@ -91304,8 +91276,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + - + @@ -91379,9 +91353,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + + @@ -91420,8 +91395,117 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + + + + + + + + + + + + + + + +

+ vorsicht Falle: Parameter werden oft per Referenz genommen +

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

+ ich muß für die strukturierten Fälle eine eingene Trait-Spezialisierung anlegen +

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

+ ...dieser Umbau ist durchaus schwer zu stemmen.... +

+

+ Denn der weitere darauf aufbauende Code ist ebenfalls nicht ganz in Ordnung und benötigt die Generalisierung, um dann grade gezogen zu werden... und ich fürchte die Situation, wo mir ein Berg von Template-Code um die Ohren fliegt +

+ + +
+ + +
+
+ + +
+ + + + + + + +
@@ -91554,7 +91638,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -91584,8 +91669,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Der Name und die Vorstellung hat nun mehrfach gewechselt, aber es ging doch letztlich immer darum, eine unbekannte Library-Funktion so aufzurüsten, daß man sie mit einem generischen Schema zu fassen bekommt. Auch die Idee, die Buffer-Pointer in ein Array zu packen, gehört letztlich zu diesem Ansatz. Der darüber hinausgehende Teil der ursprünglichen Idee, dieses Strukur auch zu »bespielen« ist jetzt in der »weaving«-Metapher aufgegangen — und dieses fortschreitende Wechselspiel in der Speicherbelegung findet darüber ja nun tatsächlich statt.

- - +
@@ -91611,8 +91695,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
hier zeigt sich immer wieder der gleiche Trade-off: zusätzliche Indirektion vs. Template-Bloat

- - +
@@ -91691,14 +91774,27 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - +
+ + + + + + + + + + + + + +