From 4e0af307fac18ccbde250bfd327715818d23a39a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 3 Jan 2025 23:43:51 +0100 Subject: [PATCH] Invocation: fill in the wiring for a nested Port builder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit unfortunately the "mechanics" of this builder setup are quite convoluted, due to constrains with the memory manager, which basically force us to collect a set of ''builder-λ'', together with summing up all the required storage, so that the actual allocation of all Ports can be done into one contiguous block of memory, to be connected to the actual Node. For the regular `PortBuilder`, we use a helper subclass, the `WeavingBuilder`, to construct this builderλ. But here, for the setup of an ''Param Agent Node,'' the actual wiring is much simpler and it is not justified to use a delegate builder; rather we perfrom the complete setup directly in the terminal sub-builder operation, prior to returning up to the NodeBuilder, which controls the overall build. --- src/steam/engine/node-builder.hpp | 99 +++++++++++++++++++--- src/steam/engine/param-weaving-pattern.hpp | 2 +- 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp index 20e0f4eb3..288d28790 100644 --- a/src/steam/engine/node-builder.hpp +++ b/src/steam/engine/node-builder.hpp @@ -86,6 +86,8 @@ #include "lib/error.hpp" #include "lib/nocopy.hpp" #include "steam/engine/weaving-pattern-builder.hpp" +#include "steam/engine/media-weaving-pattern.hpp" +#include "steam/engine/param-weaving-pattern.hpp" #include "steam/engine/proc-node.hpp" #include "steam/engine/turnout.hpp" #include "lib/several-builder.hpp" @@ -240,9 +242,10 @@ namespace engine { template auto invoke (StrView portSpec, FUN fun); - /** specify an `InvocationAdapter` to use explicitly. */ - template - auto adaptInvocation(ARGS&& ...args); + /** setup a »ParamAgentNode« to compute additional parameters + * and then delegate into an existing node invocation. */ + template + auto computeParam(SPEC&&); private: @@ -461,15 +464,91 @@ namespace engine { using WeavingBuilder_FUN = WeavingBuilder; return PortBuilder{move(*this), move(fun), portSpec}; } -/* - template - template - auto - PortBuilderRoot::adaptInvocation(ARGS&& ...args) + + + + + /** + * Nested sub-Builder analogous to \ref PortBuilder, but for building a _»Param Agent Node«._ + * This will compute additional parameters and make them temporarily accessible through the + * TurnoutSystem of the invocation, but only while delegating recursively to another + * computation node, which can then draw upon these additional parameter values. + * @tparam SPEC a ParamBuildSpec, which is a sub-builder to define the parameter-functors + * evaluated on each invocation to retrieve the actual parameter values + */ + template + class ParamAgentBuilder + : public PortBuilderRoot { - return move(*this); + using _Par = PortBuilderRoot; + + using BlockBuilder = typename SPEC::BlockBuilder; + using PostProcessor = function; + + BlockBuilder blockBuilder_; + PostProcessor postProcessor_; + Port* delegatePort_; + uint defaultPortNr_; + + public: + + /*********************************************************************//** + * Terminal: complete the Param-Agent wiring and return to the node level. + * @remark this prepares a suitable Turnout instance for a port; it will + * actually built later, together with other ports of this Node. + */ + auto + completePort() + { + if (not delegatePort_) + throw err::Logic{"Building a ParamAgentNode requires a delegate node " + "to perform within the scope with extended parameters" + ,LERR_(BOTTOM_VALUE)}; + string portSpec = "Par+"+delegatePort_->procID.genProcSpec(); + + using WeavingPattern = ParamWeavingPattern; + using TurnoutWeaving = Turnout; + using PortDataBuilder = DataBuilder; + + return NodeBuilder ( static_cast&&> (*this) // slice away PortBulder subclass data + , SizMark{} + ,// prepare a builder-λ to construct the actual Turnout-object + [procID = ProcID::describe(_Par::symbol_,portSpec) + ,builder = move(blockBuilder_) + ,postProc = move(postProcessor_) + ,delegate = delegatePort_ + ] + (PortDataBuilder& portData) mutable -> void + { + portData.template emplace (procID + ,move(builder) + ,move(postProc) + ,*delegate + ); + }); + } // chain back up to Node-Builder with extended patternData + + private: + template + ParamAgentBuilder(_Par&& base, BlockBuilder&& builder) + : _Par{move(base)} + , blockBuilder_{move(builder)} + , delegatePort_{nullptr} + , defaultPortNr_{_Par::patternData_.size()} + { } // ^^^ by default use next free port + + friend class PortBuilderRoot; + }; + + + template + template + auto + PortBuilderRoot::computeParam(SPEC&& spec) + { + using ParamBuildSpec = std::decay_t; + return ParamAgentBuilder{spec.makeBlockBuilder()}; } - */ /** * Entrance point for building actual Render Node Connectivity (Level-2) diff --git a/src/steam/engine/param-weaving-pattern.hpp b/src/steam/engine/param-weaving-pattern.hpp index 280b4b298..adb3a9d4d 100644 --- a/src/steam/engine/param-weaving-pattern.hpp +++ b/src/steam/engine/param-weaving-pattern.hpp @@ -184,7 +184,7 @@ namespace engine { } }; - auto + inline auto buildParamSpec() { return ParamBuildSpec{tuple<>{}};