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>;
template<class PF>
using isSuitable = __and_<is_constructible<Param, Res<PF>>
,std::is_invocable<PF, TurnoutSystem&>
>;
using isSuitable = is_constructible<Param, Res<PF>>;
template<class PF>
using canInvoke = std::is_invocable<PF, TurnoutSystem&>;
template<class PF>
using isConfigurable = __and_<is_constructible<bool, PF&>
@ -280,7 +280,9 @@ namespace engine {
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>
static constexpr bool canActivate() { return isSuitable<PF>() and isConfigurable<PF>(); }
};
@ -607,15 +609,19 @@ namespace engine {
template<typename 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? */
template<typename PFX>
static constexpr bool isSuitable()
static constexpr bool isSuitableParamFun()
{
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.
@ -634,44 +640,6 @@ namespace engine {
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
* @note possible only if both proc-functor and param-functor are copyable
@ -697,6 +665,61 @@ namespace engine {
paramFun_ = forward<PFX> (paramFunDef);
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

View file

@ -435,6 +435,7 @@ namespace engine {
};
}
/** control parameter(s) by an automation function, based on nominal timeline time */
template<class AUTO>
auto
attachAutomation (AUTO&& aFun)
@ -446,6 +447,7 @@ namespace engine {
});
}
/** embed a fixed value to use for the parameter(s) */
template<typename PAR>
auto
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>
auto
retrieveParam (GET&& getter)

View file

@ -294,12 +294,7 @@ namespace engine {
using AdaptedPrototype = typename PROT::template Adapted<PFX>;
template<class 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,_
* so that it is invoked whenever a new `FeedManifold` is built.
* @return adapted WeavingBuilder marked with changed `FeedManifold` type.
@ -308,7 +303,7 @@ namespace engine {
auto
adaptParam (PFX paramFunctor)
{
static_assert (PROT::template isSuitable<PFX>()
static_assert (PROT::template isSuitableParamFun<PFX>()
,"suitable as param-functor for given processing-functor");
//
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>
auto
adaptProcFunParam (DEC decorator)
{
// static_assert (PROT::template isSuitable<DEC>()
// ,"suitable as param-functor for given processing-functor"); //////////////////////////OOO need some static check here to reject processing-fun without params
static_assert (PROT::template isSuitableParamAdaptor<DEC>()
,"suitable to adapt the processing-functor's param argument");
//
using AdaptedWeavingBuilder = Decorated<DEC>;
//

View file

@ -170,7 +170,7 @@ namespace test {
* - again use a processing function which takes a parameter
* - but then _decorate_ this functor, so that it takes different arguments
* - attach parameter handling to supply these adapted arguments
* @todo 2/25 define 🔁 implement
* @todo 2/25 define implement
*/
void
build_Node_adaptedParam()
@ -185,7 +185,8 @@ namespace test {
.setParam ("55")
.completePort()
.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="1739230222313" ID="ID_1885735081" MODIFIED="1739230235891" TEXT="es zahlt sich nun aus, da&#xdf; PROT eine Policy ist"/>
</node>
<node CREATED="1739242229992" ID="ID_639089925" MODIFIED="1739242251537" 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">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1739242229992" ID="ID_639089925" MODIFIED="1739468102008" TEXT="L&#xf6;sung in mehreren Schritten">
<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"/>
<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 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"/>
</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"/>
<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"/>
<node CREATED="1739289987481" ID="ID_714942938" MODIFIED="1739290007177" TEXT="kann Variante mit Parameter voraussetzen">
<icon BUILTIN="idea"/>
@ -105566,11 +105568,30 @@ StM_bind(Builder&lt;R1&gt; b1, Extension&lt;R1,R2&gt; extension)
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#cfa0bf" COLOR="#690f14" CREATED="1739290063125" ID="ID_1127173969" MODIFIED="1739290092107" TEXT="noch ziemlich h&#xe4;sslich">
<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 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"/>
</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 BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1739242477076" ID="ID_509590719" MODIFIED="1739242501812" TEXT="statische Fehlermeldung wenn es gar keine Parameter gibt">
<icon BUILTIN="yes"/>