diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp index 14b49ec77..e41bc56a5 100644 --- a/src/steam/engine/node-builder.hpp +++ b/src/steam/engine/node-builder.hpp @@ -307,7 +307,7 @@ namespace engine { } - /****************************************************//** + /*************************************************************//** * Terminal: complete the Port wiring and return to the node level. */ NodeBuilder diff --git a/src/steam/engine/turnout.hpp b/src/steam/engine/turnout.hpp index ea0cd9991..6ae7032fc 100644 --- a/src/steam/engine/turnout.hpp +++ b/src/steam/engine/turnout.hpp @@ -274,159 +274,19 @@ namespace engine { } - struct WeavingPatternBase ///////OOO seems to be obsolete...?? - //////////////////////////////OOO non-copyable? move-only?? - { - using Feed = FeedManifold<0>; - - Feed mount() { return Feed{}; } - void pull (Feed&, TurnoutSystem&) { /* NOP */ } - void shed (Feed&) { /* NOP */ } - void weft (Feed&) { /* NOP */ } - void fix (Feed&) { /* NOP */ } - }; - namespace {// Introspection helpers.... - - using lib::meta::_Fun; - using lib::meta::is_BinaryFun; - using std::remove_reference_t; - - /** 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 - struct _ProcFun - { - static_assert(_Fun() , "something funktion-like required"); - static_assert(is_BinaryFun() , "function with two arguments expected"); - - using ArgI = remove_reference_t::Args::List::Head>; - using ArgO = remove_reference_t::Args::List::Tail::Head>; - - template - struct MatchBuffArray - { - static_assert(not sizeof(ARG), "processing function expected to take array-of-buffer-pointers"); - }; - template - struct MatchBuffArray> - { - using Buff = BUF; - enum{ SIZ = N }; - }; - - using BuffI = typename MatchBuffArray::Buff; - using BuffO = typename MatchBuffArray::Buff; - - enum{ FAN_I = MatchBuffArray::SIZ - , FAN_O = MatchBuffArray::SIZ - }; - }; - - /** - * Pick a suitable size for the FeedManifold to accommodate the given function. - * @remark only returning one of a small selection of sizes, to avoid - * excessive generation of template instances. - * @todo 10/24 this is a premature safety guard; - * need to assess if there is actually a problem - * (chances are that the optimiser absorbs most of the combinatoric complexity, - * or that, to the contrary, other proliferation mechanisms cause more harm) + * Standard implementation for a _Weaving Pattern_ to connect + * the input and output data feeds (buffers) into a processing function. + * @tparam CONF a configuration / policy base class + * @note assumptions made regarding the overall structure + * - CONF::Feed defines an _invocation adapter_ for the processing function + * - CONF::buildFeed is a functor to (repeatedly) build `Feed` instances + * - this adapter in turn embeds a `FeedManifold` to hold + * + an array of input buffer pointers + * + an array of output buffer pointers + * + `CONF::MAX_SIZ` limits both arrays */ - template - inline constexpr uint - manifoldSiz() - { - using _F = _ProcFun; - auto bound = std::max (_F::FAN_I, _F::FAN_O); - static_assert (bound <= 10, - "Limitation of template instances exceeded"); - return bound < 3? bound - : bound < 6? 5 - : 10; - } - }//(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 - struct SimpleFunctionInvocationAdapter - : MAN - { - using BuffI = typename _ProcFun::BuffI; - using BuffO = typename _ProcFun::BuffO; - - enum{ N = MAN::inBuff::size() - , FAN_I = _ProcFun::FAN_I - , FAN_O = _ProcFun::FAN_O - }; - - static_assert(FAN_I <= N and FAN_O <= N); - - using ArrayI = std::array; - using ArrayO = std::array; - - - FUN process; - - ArrayI inParam; - ArrayO outParam; - - template - SimpleFunctionInvocationAdapter (INIT&& ...funSetup) - : FUN{forward (funSetup)...} - { } - - - void - connect (uint fanIn, uint fanOut) - { - REQUIRE (fanIn >= FAN_I and fanOut >= FAN_O); - for (uint i=0; i(); - for (uint i=0; i(); - } - - void - invoke() - { - process (inParam, outParam); - } - }; - - /** - * 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 - struct Conf_DirectFunctionInvocation - : util::MoveOnly - { - using Manifold = FeedManifold; - using Feed = SimpleFunctionInvocationAdapter; - enum{ MAX_SIZ = N }; - }; - - template struct SimpleWeavingPattern : CONF @@ -441,8 +301,9 @@ namespace engine { uint resultSlot{0}; //////////////////////////////////////////OOO builder must set-up those descriptors - SimpleWeavingPattern(Several&& pr, Several dr) - : CONF{} + template + SimpleWeavingPattern(Several&& pr, Several dr, ARGS&& ...args) + : CONF{forward(args)...} , leadPort{move(pr)} , outTypes{move(dr)} { } @@ -451,7 +312,7 @@ namespace engine { Feed mount() { - return Feed{}; //////////////////////OOO cant work this way ... need to pass-in a processing functor for the ctor + return CONF::buildFeed(); } void diff --git a/src/steam/engine/weaving-pattern-builder.hpp b/src/steam/engine/weaving-pattern-builder.hpp index 0b480a914..f912e6cba 100644 --- a/src/steam/engine/weaving-pattern-builder.hpp +++ b/src/steam/engine/weaving-pattern-builder.hpp @@ -61,6 +61,152 @@ namespace engine { using std::forward; using lib::Several; + + namespace {// Introspection helpers.... + + using lib::meta::_Fun; + using lib::meta::is_BinaryFun; + using std::remove_reference_t; + + /** 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 + struct _ProcFun + { + static_assert(_Fun() , "something funktion-like required"); + static_assert(is_BinaryFun() , "function with two arguments expected"); + + using ArgI = remove_reference_t::Args::List::Head>; + using ArgO = remove_reference_t::Args::List::Tail::Head>; + + template + struct MatchBuffArray + { + static_assert(not sizeof(ARG), "processing function expected to take array-of-buffer-pointers"); + }; + template + struct MatchBuffArray> + { + using Buff = BUF; + enum{ SIZ = N }; + }; + + using BuffI = typename MatchBuffArray::Buff; + using BuffO = typename MatchBuffArray::Buff; + + enum{ FAN_I = MatchBuffArray::SIZ + , FAN_O = MatchBuffArray::SIZ + }; + }; + + + /** + * Pick a suitable size for the FeedManifold to accommodate the given function. + * @remark only returning one of a small selection of sizes, to avoid + * excessive generation of template instances. + * @todo 10/24 this is a premature safety guard; + * need to assess if there is actually a problem + * (chances are that the optimiser absorbs most of the combinatoric complexity, + * or that, to the contrary, other proliferation mechanisms cause more harm) + */ + template + inline constexpr uint + manifoldSiz() + { + using _F = _ProcFun; + auto bound = std::max (_F::FAN_I, _F::FAN_O); + static_assert (bound <= 10, + "Limitation of template instances exceeded"); + return bound < 3? bound + : bound < 6? 5 + : 10; + } + }//(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 + struct SimpleFunctionInvocationAdapter + : MAN + { + using BuffI = typename _ProcFun::BuffI; + using BuffO = typename _ProcFun::BuffO; + + enum{ N = MAN::inBuff::size() + , FAN_I = _ProcFun::FAN_I + , FAN_O = _ProcFun::FAN_O + }; + + static_assert(FAN_I <= N and FAN_O <= N); + + using ArrayI = std::array; + using ArrayO = std::array; + + + FUN process; + + ArrayI inParam; + ArrayO outParam; + + template + SimpleFunctionInvocationAdapter (INIT&& ...funSetup) + : FUN{forward (funSetup)...} + { } + + + void + connect (uint fanIn, uint fanOut) + { + REQUIRE (fanIn >= FAN_I and fanOut >= FAN_O); + for (uint i=0; i(); + for (uint i=0; i(); + } + + void + invoke() + { + process (inParam, outParam); + } + }; + + /** + * 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 + struct Conf_DirectFunctionInvocation + : util::MoveOnly + { + using Manifold = FeedManifold; + using Feed = SimpleFunctionInvocationAdapter; + enum{ MAX_SIZ = N }; + + std::function buildFeed; + }; + + + + template using DataBuilder = lib::SeveralBuilder; @@ -92,6 +238,12 @@ namespace engine { }; ServiceCtx ctx; //////////////////////////////////////////OOO need to wire that top-down through all builders! + FUN fun_; + + WeavingBuilder(FUN&& init) + : fun_{move(init)} + { } + WeavingBuilder attachToLeadPort(ProcNode& lead, uint portNr) { @@ -134,7 +286,7 @@ namespace engine { using Product = Turnout>; ///////////////////////////////OOO need a way to prepare SeveralBuilder-instances for leadPort and outDescr --> see NodeBuilder - return Product{leadPort.build(), outTypes.build()}; + return Product{leadPort.build(), outTypes.build(), move(fun_)}; } private: diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 459f9450a..ca378323b 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -89326,7 +89326,31 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + + + + + + + + + + + + + + + + + + + + +