From 79b45601c0e5a5e95b7a747d5e9c3fcabbd163bd Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 13 Feb 2025 16:27:50 +0100 Subject: [PATCH] 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 --- src/steam/engine/feed-manifold.hpp | 115 +++++++++++------- src/steam/engine/node-builder.hpp | 4 + src/steam/engine/weaving-pattern-builder.hpp | 24 ++-- tests/core/steam/engine/node-builder-test.cpp | 5 +- wiki/thinkPad.ichthyo.mm | 31 ++++- 5 files changed, 116 insertions(+), 63 deletions(-) diff --git a/src/steam/engine/feed-manifold.hpp b/src/steam/engine/feed-manifold.hpp index 65dff69d4..352495953 100644 --- a/src/steam/engine/feed-manifold.hpp +++ b/src/steam/engine/feed-manifold.hpp @@ -256,9 +256,9 @@ namespace engine { using SigP = add_pointer_t::Sig>; template - using isSuitable = __and_> - ,std::is_invocable - >; + using isSuitable = is_constructible>; + template + using canInvoke = std::is_invocable; template using isConfigurable = __and_ @@ -280,7 +280,9 @@ namespace engine { template - static constexpr bool isParamFun() { return isSuitable(); } + static constexpr bool canAdapt() { return isSuitable(); } + template + static constexpr bool isParamFun() { return isSuitable() and canInvoke(); } template static constexpr bool canActivate() { return isSuitable() and isConfigurable(); } }; @@ -607,15 +609,19 @@ namespace engine { template using Adapted = FeedPrototype; - template - using Decorated = FeedPrototype; - /** is the given functor suitable as parameter functor for this Feed? */ template - static constexpr bool isSuitable() + static constexpr bool isSuitableParamFun() { return hasParam() and _Trait::template isParamFun(); } + /** is the given functor suitable to adapt the parameter argument + * of the processing-functor to accept different input values? */ + template + static constexpr bool isSuitableParamAdaptor() + { + return hasParam() and _Trait::template canAdapt(); + } /** * Cross-Builder to add configuration with a given parameter-functor. @@ -634,44 +640,6 @@ namespace engine { return Adapted{move(procFun_), move(otherParamFun)}; } - template - auto - moveDecoratedProc (FUX adaptedProcFun) - { - using AugmentedProcFun = std::decay_t; - return Decorated{move(adaptedProcFun), move(paramFun_)}; - } - - template - auto - moveTransformedParam (TRA paramTransformer) - { - static_assert (_Trait::hasParam(), "Processing-functor with parameters expected"); - using SigP = lib::meta::_FunArg; - 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 (paramFunDef); return move(*this); } + + + /** @internal build an adapted version of the processing-functor, + * thereby attaching the parameter-transformer. */ + template + auto + decorateProcParam (TRA paramTransformer) + { + static_assert (_Trait::hasParam(), "Processing-functor with parameters expected"); + static_assert (isSuitableParamAdaptor(), "Given functor's output not suitable " + "for adapting the proc-functor's 1st argument"); + using SigP = lib::meta::_FunArg; + 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 + using DecoratedProcFun = decltype(std::declval().decorateProcParam (std::declval())); + + template + using Decorated = FeedPrototype,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 + auto + moveTransformedParam (TRA paramTransformer) + { + return Decorated{decorateProcParam (move(paramTransformer)), move(paramFun_)}; + } + }; }} // namespace steam::engine diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp index d1f255553..4dc07103a 100644 --- a/src/steam/engine/node-builder.hpp +++ b/src/steam/engine/node-builder.hpp @@ -435,6 +435,7 @@ namespace engine { }; } + /** control parameter(s) by an automation function, based on nominal timeline time */ template auto attachAutomation (AUTO&& aFun) @@ -446,6 +447,7 @@ namespace engine { }); } + /** embed a fixed value to use for the parameter(s) */ template 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 auto retrieveParam (GET&& getter) diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp index cb4e73c3f..798816811 100644 --- a/src/steam/engine/weaving-pattern-builder.hpp +++ b/src/steam/engine/weaving-pattern-builder.hpp @@ -294,12 +294,7 @@ namespace engine { using AdaptedPrototype = typename PROT::template Adapted; template using Adapted = WeavingBuilder>; - - template - using DecoratedPrototype = decltype(std::declval().moveTransformedParam (move (std::declval()))); /////OOO ugly!!!! - template - using Decorated = WeavingBuilder>; - + /** 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() + static_assert (PROT::template isSuitableParamFun() ,"suitable as param-functor for given processing-functor"); // using AdaptedWeavingBuilder = Adapted; @@ -318,13 +313,22 @@ namespace engine { }; } - /** @todo */ + + /** type builder for FeedPrototype with remoulded parameter input */ + template + using DecoratedPrototype = typename PROT::template Decorated; + template + using Decorated = WeavingBuilder>; + + /** 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 auto adaptProcFunParam (DEC decorator) { -// static_assert (PROT::template isSuitable() -// ,"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() + ,"suitable to adapt the processing-functor's param argument"); // using AdaptedWeavingBuilder = Decorated; // diff --git a/tests/core/steam/engine/node-builder-test.cpp b/tests/core/steam/engine/node-builder-test.cpp index 483603bf5..9c4916dee 100644 --- a/tests/core/steam/engine/node-builder-test.cpp +++ b/tests/core/steam/engine/node-builder-test.cpp @@ -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)); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 7687401d5..9eb12a090 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -105542,18 +105542,20 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - + + + - + + - + - + @@ -105566,11 +105568,30 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + + + +

+ das geht, weil durch das constexpr-if die Funktion jedesmal erneut instantiiert wird, mit dann jeweils anderem deduziertem auto-Returntyp +

+ + +
+
+ + + +