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<>{}};