Invocation: use introspection to setup an example

The deeper problem is that we must not engage into any premature decisions
regarding the structure or layout of the actual processing function invocation.

Thus attempting to create a kind of »firewall« of sorts, by connecting
the building blocks strictly through template parameter and preferably
figuring out any detailed knowledge locally, through ''compile-time introspection...''
This commit is contained in:
Fischlurch 2024-07-11 17:34:57 +02:00
parent e7b68427d3
commit 1955d28087
2 changed files with 116 additions and 48 deletions

View file

@ -272,7 +272,7 @@ namespace engine {
}
struct WeavingPatternBase
struct WeavingPatternBase ///////OOO seems to be obsolete...??
//////////////////////////////OOO non-copyable? move-only??
{
using Feed = FeedManifold<0>;
@ -284,15 +284,84 @@ namespace engine {
void fix (Feed&) { /* NOP */ }
};
namespace {// Introspection helpers....
using lib::meta::_Fun;
using lib::meta::is_BinaryFun;
/** Helper to pick up the parameter dimensions from the processing function
* @remark this is the rather simple yet common case that media processing
* is done by a function, which takes an array of input and output
* buffer pointers with a common type; this simple case is used
* 7/2024 for prototyping and validate the design.
* @tparam FUN a _function-like_ object, expected to accept two arguments,
* which both are arrays of buffer pointers (input, output).
*/
template<class FUN>
struct _ProcFun
{
static_assert(_Fun<FUN>() , "something funktion-like required");
static_assert(is_BinaryFun<FUN>() , "function with two arguments expected");
using ArgI = typename _Fun<FUN>::Args::List::Head;
using ArgO = typename _Fun<FUN>::Args::List::Tail::Head;
template<class ARG>
struct MatchBuffArray
{
static_assert(not sizeof(ARG), "processing function expected to take array-of-buffer-pointers");
};
template<class BUF, size_t N>
struct MatchBuffArray<std::array<BUF*,N>>
{
using Buff = BUF;
enum{ SIZ = N };
};
using BuffI = typename MatchBuffArray<ArgI>::Buff;
using BuffO = typename MatchBuffArray<ArgO>::Buff;
enum{ FAN_I = MatchBuffArray<ArgI>::SIZ
, FAN_O = MatchBuffArray<ArgO>::SIZ
};
};
}//(End)Introspection helpers.
/**
* Adapter to handle a simple yet common setup for media processing
* - somehow we can invoke processing as a simple function
* - this function takes two arrays: the input- and output buffers
* @remark this setup is useful for testing, and as documentation example;
* actually the FeedManifold is mixed in as baseclass, and the
* buffer pointers are retrieved from the BuffHandles.
* @tparam MAN a FeedManifold, providing arrays of BuffHandles
* @tparam FUN the processing function
*/
template<class MAN, class FUN>
struct InvocationAdapter
struct SimpleFunctionInvocationAdapter
: MAN
{
static constexpr auto N = MAN::inBuff::size();
using BuffI = typename _ProcFun<FUN>::BuffI;
using BuffO = typename _ProcFun<FUN>::BuffO;
enum{ N = MAN::inBuff::size()
, FAN_I = _ProcFun<FUN>::FAN_I
, FAN_O = _ProcFun<FUN>::FAN_O
};
static_assert(FAN_I <= N and FAN_O <= N);
using ArrayI = std::array<BuffI*, FAN_I>;
using ArrayO = std::array<BuffO*, FAN_O>;
FUN process;
ArrayI inParam;
ArrayO outParam;
void
connect (uint fanIn, uint fanOut)
{
@ -307,13 +376,27 @@ namespace engine {
}
};
template<class PAR, uint N, class FUN>
struct SimpleWeavingPattern
: PAR
/**
* Example base configuration for a Weaving-Pattern chain:
* - use a simple processing function
* - pass an input/output buffer array to this function
* - map all »slots« directly without any re-ordering
* - use a sufficiently sized FeedManifold as storage scheme
*/
template<uint N, class FUN>
struct Conf_DirectFunctionInvocation
{
using Manifold = FeedManifold<N>;
using Feed = InvocationAdapter<Manifold, FUN>;
using Feed = SimpleFunctionInvocationAdapter<Manifold, FUN>;
enum{ MAX_SIZ = N };
};
template<class CONF>
struct SimpleWeavingPattern
: CONF
{
using Feed = typename CONF::Feed;
static_assert (_verify_usable_as_InvocationAdapter<Feed>());
@ -321,7 +404,7 @@ namespace engine {
uint fanOut{0};
template<class X>
using Storage = lib::UninitialisedStorage<X,N>;
using Storage = lib::UninitialisedStorage<X,CONF::MAX_SIZ>;
Storage<PortRef> leadPort;

View file

@ -1223,9 +1223,7 @@
<node CREATED="1502402798909" ID="ID_813337624" MODIFIED="1518487921051" TEXT="z&#xe4;hlt nicht wirklich, denn.."/>
<node CREATED="1502402810620" ID="ID_439896117" MODIFIED="1518487921051" TEXT="mit dem Diff-Konzept habe ich das bereits akzeptiert">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
n&#228;mlich
@ -1276,9 +1274,7 @@
<node CREATED="1484877696486" ID="ID_476867583" MODIFIED="1538263469664" TEXT="wir m&#xfc;ssen jede Aktion in den Event-Thread &#xfc;bergeben"/>
<node CREATED="1484877711388" ID="ID_407918505" MODIFIED="1538263469664">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
das hei&#223;t, die Diff-<b>Implementierung</b>&#160;mu&#223; l&#228;nger leben
@ -1298,9 +1294,7 @@
</node>
<node CREATED="1484877743992" ID="ID_680582075" MODIFIED="1538263469664">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
um das Diff zu <i>pullen</i>
@ -1338,9 +1332,7 @@
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1501850684373" ID="ID_1688212376" MODIFIED="1576282358156" TEXT="ein Dispatcher pro Call">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
jede Facade-Funktion brauch einen Dispatcher
@ -1361,9 +1353,7 @@
<node CREATED="1501850920950" ID="ID_1529426036" MODIFIED="1538263469665" TEXT="mu&#xdf; im UI-Thread erfolgen"/>
<node CREATED="1501850933596" ID="ID_620574396" MODIFIED="1538263469665">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
<i>bevor</i>&#160;die Facade ge&#246;ffnet wir
@ -2840,9 +2830,7 @@
</node>
<node CREATED="1534721435740" FOLDED="true" ID="ID_1066281960" MODIFIED="1561827464627" TEXT="Konvention: Fehlerlog-Widget zerst&#xf6;ren">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...und nicht blo&#223; inaktiv schalten.
@ -4620,9 +4608,7 @@
<icon BUILTIN="button_ok"/>
<node CREATED="1481686982097" ID="ID_1925999031" MODIFIED="1576282358146" TEXT="passiert on demand">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...wenn jemand zugreift
@ -7048,9 +7034,7 @@
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1489461946997" HGAP="-10" ID="ID_1526466868" MODIFIED="1576282358131" TEXT="direkt von den Lambdas aus delegieren" VSHIFT="7">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
wir k&#246;nnen den gr&#246;&#223;ten Teil dieser Einzeiler-Funktionen loswerden,
@ -87935,8 +87919,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...und zwar seit dem Anfang des Lumiera-Projekts. Vorstellungen haben ist sch&#246;n; aber um zu bauen, brauche ich entweder ein Baumuster, oder ich brauche einen Plan und ein formal definiertes Ziel. Ich habe aber nur eine klar (negativ) abgegrenzte Finalit&#228;t
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1720705996885" ID="ID_500742660" MODIFIED="1720706042427" TEXT="&#xbb;Butter bei die Fische&#xab; &#x27f9; mu&#xdf; mich festlegen">
<node COLOR="#5b280f" CREATED="1720706044862" ID="ID_205256998" MODIFIED="1720706842198" TEXT="kann darf und will ich nicht">
@ -87950,8 +87933,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
&#160;&#8212; zu einer gewaltigen <b>universellen Klassifikation</b>&#160;jedweden Medien-Processings
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="closed"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1720706055174" ID="ID_1229045724" MODIFIED="1720706085769" STYLE="bubble" TEXT="&#x21af;">
@ -87968,8 +87950,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
und zwar durch die <b>Entscheidungen der letzten Wochen</b>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1720706357708" ID="ID_1152413069" MODIFIED="1720706444797" STYLE="bubble" TEXT=" im Rahmen einer Domain-Ontology kann ich die notwendigen Festlegungen treffen">
<edge COLOR="#650282"/>
@ -87984,7 +87965,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<font ITALIC="true" NAME="SansSerif" SIZE="11"/>
</node>
<node CREATED="1720706943501" ID="ID_1956447342" MODIFIED="1720706950784" TEXT="konkrete Aufgaben">
<node CREATED="1720707034097" ID="ID_1479426384" MODIFIED="1720707046468" TEXT="einfachste Form des &#xbb;shedding&#xab; implementieren"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1720707034097" ID="ID_1479426384" MODIFIED="1720713747463" TEXT="einfachste Form des &#xbb;shedding&#xab; implementieren">
<icon BUILTIN="pencil"/>
</node>
<node CREATED="1720707047696" ID="ID_1008545178" MODIFIED="1720707071737">
<richcontent TYPE="NODE"><html>
<head/>
@ -87993,14 +87976,14 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
&#10233; mu&#223; daf&#252;r den <b>Buffer-Typ</b>&#160;kennen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1720707077876" ID="ID_802952115" MODIFIED="1720707082031" TEXT="catch-22"/>
<node CREATED="1720707082547" ID="ID_975232757" MODIFIED="1720707097949" TEXT="schon wieder ein impliziter Vorgriff..."/>
<node CREATED="1720707273074" ID="ID_319694638" MODIFIED="1720707294216" TEXT="Einschr&#xe4;nkung: auch die Processing-Funktion ist ein Vorgriff"/>
<node CREATED="1720707295151" ID="ID_975619644" MODIFIED="1720707305063" TEXT="und auch die Entscheidung, ein Buffer-Array zu haben"/>
<node CREATED="1720707426637" ID="ID_1630837670" MODIFIED="1720707431583" TEXT="Konsequenzen">
<node COLOR="#435e98" CREATED="1720707426637" ID="ID_1630837670" MODIFIED="1720713740435" TEXT="Konsequenzen">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="forward"/>
<node CREATED="1720707433653" ID="ID_1772098945" MODIFIED="1720707477157">
<richcontent TYPE="NODE"><html>
@ -88010,15 +87993,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
der hier gecodete InvocationAdapter ist <i>kein Inteface</i>&#160;(sondern ein <b>Concept</b>)
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
<node CREATED="1720707481678" ID="ID_515646989" MODIFIED="1720707502245">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
<b>Trennmauern</b>&#160;zwischen allen Bauelementen im Baukastensystem
@ -88026,6 +88006,11 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1720709146697" ID="ID_868020542" MODIFIED="1720713736503" TEXT="CONF &#x27f5; Konfigurations-Template als Mix-In"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1720709174409" ID="ID_425138503" MODIFIED="1720713736503" TEXT="PAT &#x27f5; Dekorator-Chain aus Pattern-Elementen"/>
</node>
<node COLOR="#338800" CREATED="1720713710865" ID="ID_1167199321" MODIFIED="1720713722018" TEXT="L&#xf6;sung: leite ihn per Introspektion vom Funktions-Typ ab">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>