Invocation: rearrange for clearer definitions

seemingly the definition can not be much simplified,
since there is no way around handling several definition flavours
of the processing-functor distinctly.

However, the definitions can be rearranged to be clearer,
the resulting type of the `FeedPrototype` can be deduced from the
builder function, and more stringent assertions can be added
This commit is contained in:
Fischlurch 2025-02-13 16:27:50 +01:00
parent 0e5ffe7780
commit 79b45601c0
5 changed files with 116 additions and 63 deletions

View file

@ -256,9 +256,9 @@ namespace engine {
using SigP = add_pointer_t<typename _Fun<PF>::Sig>; using SigP = add_pointer_t<typename _Fun<PF>::Sig>;
template<class PF> template<class PF>
using isSuitable = __and_<is_constructible<Param, Res<PF>> using isSuitable = is_constructible<Param, Res<PF>>;
,std::is_invocable<PF, TurnoutSystem&> template<class PF>
>; using canInvoke = std::is_invocable<PF, TurnoutSystem&>;
template<class PF> template<class PF>
using isConfigurable = __and_<is_constructible<bool, PF&> using isConfigurable = __and_<is_constructible<bool, PF&>
@ -280,7 +280,9 @@ namespace engine {
template<class PF> template<class PF>
static constexpr bool isParamFun() { return isSuitable<PF>(); } static constexpr bool canAdapt() { return isSuitable<PF>(); }
template<class PF>
static constexpr bool isParamFun() { return isSuitable<PF>() and canInvoke<PF>(); }
template<class PF> template<class PF>
static constexpr bool canActivate() { return isSuitable<PF>() and isConfigurable<PF>(); } static constexpr bool canActivate() { return isSuitable<PF>() and isConfigurable<PF>(); }
}; };
@ -607,15 +609,19 @@ namespace engine {
template<typename PFX> template<typename PFX>
using Adapted = FeedPrototype<FUN,PFX>; using Adapted = FeedPrototype<FUN,PFX>;
template<typename FUX>
using Decorated = FeedPrototype<FUX,PAM>;
/** is the given functor suitable as parameter functor for this Feed? */ /** is the given functor suitable as parameter functor for this Feed? */
template<typename PFX> template<typename PFX>
static constexpr bool isSuitable() static constexpr bool isSuitableParamFun()
{ {
return hasParam() and _Trait::template isParamFun<PFX>(); return hasParam() and _Trait::template isParamFun<PFX>();
} }
/** is the given functor suitable to adapt the parameter argument
* of the processing-functor to accept different input values? */
template<typename PFX>
static constexpr bool isSuitableParamAdaptor()
{
return hasParam() and _Trait::template canAdapt<PFX>();
}
/** /**
* Cross-Builder to add configuration with a given parameter-functor. * Cross-Builder to add configuration with a given parameter-functor.
@ -634,44 +640,6 @@ namespace engine {
return Adapted<OtherParamFun>{move(procFun_), move(otherParamFun)}; return Adapted<OtherParamFun>{move(procFun_), move(otherParamFun)};
} }
template<typename FUX>
auto
moveDecoratedProc (FUX adaptedProcFun)
{
using AugmentedProcFun = std::decay_t<FUX>;
return Decorated<AugmentedProcFun>{move(adaptedProcFun), move(paramFun_)};
}
template<typename TRA>
auto
moveTransformedParam (TRA paramTransformer)
{
static_assert (_Trait::hasParam(), "Processing-functor with parameters expected");
using SigP = lib::meta::_FunArg<TRA>;
using SigI = typename _Proc::SigI;
using SigO = typename _Proc::SigO;
if constexpr (_Proc::hasInput())
{
return moveDecoratedProc([procFun = move(procFun_)
,transform = move(paramTransformer)
]
(SigP par, SigI in, SigO out)
{
return procFun (transform(par), in, out);
});
}
else
{
return moveDecoratedProc([procFun = move(procFun_)
,transform = move(paramTransformer)
]
(SigP par, SigO out)
{
return procFun (transform(par), out);
});
}
}
/** build a clone-copy of this prototype, holding the same functors /** build a clone-copy of this prototype, holding the same functors
* @note possible only if both proc-functor and param-functor are copyable * @note possible only if both proc-functor and param-functor are copyable
@ -697,6 +665,61 @@ namespace engine {
paramFun_ = forward<PFX> (paramFunDef); paramFun_ = forward<PFX> (paramFunDef);
return move(*this); return move(*this);
} }
/** @internal build an adapted version of the processing-functor,
* thereby attaching the parameter-transformer. */
template<typename TRA>
auto
decorateProcParam (TRA paramTransformer)
{
static_assert (_Trait::hasParam(), "Processing-functor with parameters expected");
static_assert (isSuitableParamAdaptor<TRA>(), "Given functor's output not suitable "
"for adapting the proc-functor's 1st argument");
using SigP = lib::meta::_FunArg<TRA>;
using SigI = typename _Proc::SigI;
using SigO = typename _Proc::SigO;
if constexpr (_Proc::hasInput())
{
return [procFun = move(procFun_)
,transform = move(paramTransformer)
]
(SigP par, SigI in, SigO out)
{
return procFun (transform(par), in, out);
};
}
else
{
return [procFun = move(procFun_)
,transform = move(paramTransformer)
]
(SigP par, SigO out)
{
return procFun (transform(par), out);
};
}
}
template<typename TRA>
using DecoratedProcFun = decltype(std::declval<FeedPrototype>().decorateProcParam (std::declval<TRA>()));
template<typename TRA>
using Decorated = FeedPrototype<DecoratedProcFun<TRA>,PAM>;
/**
* Adapt parameter handling of the _processing-function_ by passing parameters
* through an adapter functor _before_ feeding them into the processing-function.
* @remark notably this allows to _partially close_ some parameters, i.e. supply
* some value from the adaptor, thereby removing them as visible parameters.
*/
template<typename TRA>
auto
moveTransformedParam (TRA paramTransformer)
{
return Decorated<TRA>{decorateProcParam (move(paramTransformer)), move(paramFun_)};
}
}; };
}} // namespace steam::engine }} // namespace steam::engine

View file

@ -435,6 +435,7 @@ namespace engine {
}; };
} }
/** control parameter(s) by an automation function, based on nominal timeline time */
template<class AUTO> template<class AUTO>
auto auto
attachAutomation (AUTO&& aFun) attachAutomation (AUTO&& aFun)
@ -446,6 +447,7 @@ namespace engine {
}); });
} }
/** embed a fixed value to use for the parameter(s) */
template<typename PAR> template<typename PAR>
auto auto
setParam (PAR paramVal) setParam (PAR paramVal)
@ -466,6 +468,8 @@ namespace engine {
}); });
} }
/** retrieve the parameter(s) at invocation time through a getter functor,
* which is typically constructed in conjunction with a »Param Agent« node. */
template<typename GET> template<typename GET>
auto auto
retrieveParam (GET&& getter) retrieveParam (GET&& getter)

View file

@ -294,12 +294,7 @@ namespace engine {
using AdaptedPrototype = typename PROT::template Adapted<PFX>; using AdaptedPrototype = typename PROT::template Adapted<PFX>;
template<class PFX> template<class PFX>
using Adapted = WeavingBuilder<POL, AdaptedPrototype<PFX>>; using Adapted = WeavingBuilder<POL, AdaptedPrototype<PFX>>;
template<class DEC>
using DecoratedPrototype = decltype(std::declval<PROT>().moveTransformedParam (move (std::declval<DEC>()))); /////OOO ugly!!!!
template<class DEC>
using Decorated = WeavingBuilder<POL, DecoratedPrototype<DEC>>;
/** Adapt a parameter-functor into the _Feed Prototype,_ /** Adapt a parameter-functor into the _Feed Prototype,_
* so that it is invoked whenever a new `FeedManifold` is built. * so that it is invoked whenever a new `FeedManifold` is built.
* @return adapted WeavingBuilder marked with changed `FeedManifold` type. * @return adapted WeavingBuilder marked with changed `FeedManifold` type.
@ -308,7 +303,7 @@ namespace engine {
auto auto
adaptParam (PFX paramFunctor) adaptParam (PFX paramFunctor)
{ {
static_assert (PROT::template isSuitable<PFX>() static_assert (PROT::template isSuitableParamFun<PFX>()
,"suitable as param-functor for given processing-functor"); ,"suitable as param-functor for given processing-functor");
// //
using AdaptedWeavingBuilder = Adapted<PFX>; using AdaptedWeavingBuilder = Adapted<PFX>;
@ -318,13 +313,22 @@ namespace engine {
}; };
} }
/** @todo */
/** type builder for FeedPrototype with remoulded parameter input */
template<class DEC>
using DecoratedPrototype = typename PROT::template Decorated<DEC>;
template<class DEC>
using Decorated = WeavingBuilder<POL, DecoratedPrototype<DEC>>;
/** Adapt parameter handling by _prepending_ the given transformer function
* to supply the parameter argument of the processing-functor. Notably this
* allows to _partially close_ some parameters. */
template<class DEC> template<class DEC>
auto auto
adaptProcFunParam (DEC decorator) adaptProcFunParam (DEC decorator)
{ {
// static_assert (PROT::template isSuitable<DEC>() static_assert (PROT::template isSuitableParamAdaptor<DEC>()
// ,"suitable as param-functor for given processing-functor"); //////////////////////////OOO need some static check here to reject processing-fun without params ,"suitable to adapt the processing-functor's param argument");
// //
using AdaptedWeavingBuilder = Decorated<DEC>; using AdaptedWeavingBuilder = Decorated<DEC>;
// //

View file

@ -170,7 +170,7 @@ namespace test {
* - again use a processing function which takes a parameter * - again use a processing function which takes a parameter
* - but then _decorate_ this functor, so that it takes different arguments * - but then _decorate_ this functor, so that it takes different arguments
* - attach parameter handling to supply these adapted arguments * - attach parameter handling to supply these adapted arguments
* @todo 2/25 ✔ define ⟶ 🔁 implement * @todo 2/25 ✔ define ⟶ ✔ implement
*/ */
void void
build_Node_adaptedParam() build_Node_adaptedParam()
@ -185,7 +185,8 @@ namespace test {
.setParam ("55") .setParam ("55")
.completePort() .completePort()
.build()}; .build()};
SHOW_EXPR(invokeRenderNode (node));
CHECK (55 == invokeRenderNode (node));
} }

View file

@ -105542,18 +105542,20 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<node CREATED="1739230175479" ID="ID_1244437448" MODIFIED="1739230182793" TEXT="nur nicht die Nerven verlieren"/> <node CREATED="1739230175479" ID="ID_1244437448" MODIFIED="1739230182793" TEXT="nur nicht die Nerven verlieren"/>
<node CREATED="1739230222313" ID="ID_1885735081" MODIFIED="1739230235891" TEXT="es zahlt sich nun aus, da&#xdf; PROT eine Policy ist"/> <node CREATED="1739230222313" ID="ID_1885735081" MODIFIED="1739230235891" TEXT="es zahlt sich nun aus, da&#xdf; PROT eine Policy ist"/>
</node> </node>
<node CREATED="1739242229992" ID="ID_639089925" MODIFIED="1739242251537" TEXT="L&#xf6;sung in mehreren Schritten"> <node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1739242229992" ID="ID_639089925" MODIFIED="1739468102008" TEXT="L&#xf6;sung in mehreren Schritten">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1739242253189" ID="ID_420283346" MODIFIED="1739242287474" TEXT="grunds&#xe4;tzlich den Proc-Functor adaptieren k&#xf6;nnen"> <icon BUILTIN="pencil"/>
<node COLOR="#435e98" CREATED="1739242253189" ID="ID_420283346" MODIFIED="1739468016365" TEXT="grunds&#xe4;tzlich den Proc-Functor adaptieren k&#xf6;nnen">
<icon BUILTIN="full-1"/> <icon BUILTIN="full-1"/>
<node CREATED="1739242379940" ID="ID_1980382512" MODIFIED="1739242388022" TEXT="das ist komplett boilerplate"/> <node CREATED="1739242379940" ID="ID_1980382512" MODIFIED="1739242388022" TEXT="das ist komplett boilerplate"/>
<node CREATED="1739242389157" ID="ID_1269699565" MODIFIED="1739242401453" TEXT="man h&#xe4;ngt die jeweiligen Template-Parameter um und gut is"/> <node CREATED="1739242389157" ID="ID_1269699565" MODIFIED="1739242401453" TEXT="man h&#xe4;ngt die jeweiligen Template-Parameter um und gut is"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1739242402448" ID="ID_936602196" MODIFIED="1739242425912" TEXT="einzige Aufgabe: sinnvolle static_assertion bereitstellen"> <node COLOR="#435e98" CREATED="1739242402448" ID="ID_936602196" MODIFIED="1739468061482" TEXT="einzige Aufgabe: sinnvolle static_assertion bereitstellen">
<linktarget COLOR="#475cae" DESTINATION="ID_936602196" ENDARROW="Default" ENDINCLINATION="197;10;" ID="Arrow_ID_1611908776" SOURCE="ID_817188131" STARTARROW="None" STARTINCLINATION="-120;6;"/>
<icon BUILTIN="yes"/> <icon BUILTIN="yes"/>
</node> </node>
</node> </node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1739242290552" ID="ID_575620979" MODIFIED="1739242324334" TEXT="spezielle Funktions-Komposition auf die Parameter-Stelle setzen"> <node COLOR="#435e98" CREATED="1739242290552" ID="ID_575620979" MODIFIED="1739468093469" TEXT="spezielle Funktions-Komposition auf die Parameter-Stelle setzen">
<icon BUILTIN="full-2"/> <icon BUILTIN="full-2"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1739242429615" ID="ID_1933481502" MODIFIED="1739242459785" TEXT="mu&#xdf; die verschiedenen Definitionsvarianten des Processing-Functors beachten"> <node COLOR="#435e98" CREATED="1739242429615" ID="ID_1933481502" MODIFIED="1739467883768" TEXT="mu&#xdf; die verschiedenen Definitionsvarianten des Processing-Functors beachten">
<icon BUILTIN="messagebox_warning"/> <icon BUILTIN="messagebox_warning"/>
<node CREATED="1739289987481" ID="ID_714942938" MODIFIED="1739290007177" TEXT="kann Variante mit Parameter voraussetzen"> <node CREATED="1739289987481" ID="ID_714942938" MODIFIED="1739290007177" TEXT="kann Variante mit Parameter voraussetzen">
<icon BUILTIN="idea"/> <icon BUILTIN="idea"/>
@ -105566,11 +105568,30 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<icon BUILTIN="button_ok"/> <icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#cfa0bf" COLOR="#690f14" CREATED="1739290063125" ID="ID_1127173969" MODIFIED="1739290092107" TEXT="noch ziemlich h&#xe4;sslich"> <node BACKGROUND_COLOR="#cfa0bf" COLOR="#690f14" CREATED="1739290063125" ID="ID_1127173969" MODIFIED="1739290092107" TEXT="noch ziemlich h&#xe4;sslich">
<icon BUILTIN="smiley-angry"/> <icon BUILTIN="smiley-angry"/>
<node CREATED="1739467887953" ID="ID_860561844" MODIFIED="1739467896758" TEXT="viel l&#xe4;&#xdf;t sich hier nicht verbessern"/>
<node CREATED="1739467898031" ID="ID_1231552769" MODIFIED="1739467920604" TEXT="man kann die Reihenfolge geschickter anordnen"/>
<node CREATED="1739467941421" ID="ID_1175438960" MODIFIED="1739467985473" TEXT="und damit den Typ von der Builder-Funktion abnehmen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
das geht, weil durch das constexpr-if die Funktion jedesmal erneut instantiiert wird, mit dann jeweils anderem deduziertem auto-Returntyp
</p>
</body>
</html>
</richcontent>
</node>
</node> </node>
<node BACKGROUND_COLOR="#dcd4b8" COLOR="#435e98" CREATED="1739290178567" ID="ID_1825991532" MODIFIED="1739290223471" TEXT="aber l&#xe4;&#xdf;t sich aufrufen &#xd83e;&#xdc32; mit korrektem Ergebnis"> <node BACKGROUND_COLOR="#dcd4b8" COLOR="#435e98" CREATED="1739290178567" ID="ID_1825991532" MODIFIED="1739290223471" TEXT="aber l&#xe4;&#xdf;t sich aufrufen &#xd83e;&#xdc32; mit korrektem Ergebnis">
<icon BUILTIN="idea"/> <icon BUILTIN="idea"/>
</node> </node>
</node> </node>
<node COLOR="#338800" CREATED="1739467990702" ID="ID_817188131" MODIFIED="1739468069604" TEXT="Assertions versch&#xe4;rfen und insgesamt besser anordnen">
<arrowlink COLOR="#475cae" DESTINATION="ID_936602196" ENDARROW="Default" ENDINCLINATION="197;10;" ID="Arrow_ID_1611908776" STARTARROW="None" STARTINCLINATION="-120;6;"/>
<icon BUILTIN="button_ok"/>
</node>
</node> </node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1739242477076" ID="ID_509590719" MODIFIED="1739242501812" TEXT="statische Fehlermeldung wenn es gar keine Parameter gibt"> <node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1739242477076" ID="ID_509590719" MODIFIED="1739242501812" TEXT="statische Fehlermeldung wenn es gar keine Parameter gibt">
<icon BUILTIN="yes"/> <icon BUILTIN="yes"/>