Invocation: fill in the wiring for a nested Port builder
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.
This commit is contained in:
parent
e131320a81
commit
4e0af307fa
2 changed files with 90 additions and 11 deletions
|
|
@ -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<typename FUN>
|
||||
auto invoke (StrView portSpec, FUN fun);
|
||||
|
||||
/** specify an `InvocationAdapter` to use explicitly. */
|
||||
template<class ADA, typename...ARGS>
|
||||
auto adaptInvocation(ARGS&& ...args);
|
||||
/** setup a »ParamAgentNode« to compute additional parameters
|
||||
* and then delegate into an existing node invocation. */
|
||||
template<class SPEC>
|
||||
auto computeParam(SPEC&&);
|
||||
|
||||
|
||||
private:
|
||||
|
|
@ -461,15 +464,91 @@ namespace engine {
|
|||
using WeavingBuilder_FUN = WeavingBuilder<POL, Prototype>;
|
||||
return PortBuilder<POL,DAT, WeavingBuilder_FUN>{move(*this), move(fun), portSpec};
|
||||
}
|
||||
/*
|
||||
template<class POL>
|
||||
template<class ADA, typename...ARGS>
|
||||
auto
|
||||
PortBuilderRoot<POL>::adaptInvocation(ARGS&& ...args)
|
||||
{
|
||||
return move(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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 POL, class DAT, class SPEC>
|
||||
class ParamAgentBuilder
|
||||
: public PortBuilderRoot<POL,DAT>
|
||||
{
|
||||
using _Par = PortBuilderRoot<POL,DAT>;
|
||||
|
||||
using BlockBuilder = typename SPEC::BlockBuilder;
|
||||
using PostProcessor = function<void(TurnoutSystem&)>;
|
||||
|
||||
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<SPEC>;
|
||||
using TurnoutWeaving = Turnout<WeavingPattern>;
|
||||
using PortDataBuilder = DataBuilder<POL, Port>;
|
||||
|
||||
return NodeBuilder ( static_cast<NodeBuilder<POL,DAT>&&> (*this) // slice away PortBulder subclass data
|
||||
, SizMark<sizeof(TurnoutWeaving)>{}
|
||||
,// 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<TurnoutWeaving> (procID
|
||||
,move(builder)
|
||||
,move(postProc)
|
||||
,*delegate
|
||||
);
|
||||
});
|
||||
} // chain back up to Node-Builder with extended patternData
|
||||
|
||||
private:
|
||||
template<typename FUN>
|
||||
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<POL,DAT>;
|
||||
};
|
||||
|
||||
|
||||
template<class POL, class DAT>
|
||||
template<class SPEC>
|
||||
auto
|
||||
PortBuilderRoot<POL,DAT>::computeParam(SPEC&& spec)
|
||||
{
|
||||
using ParamBuildSpec = std::decay_t<SPEC>;
|
||||
return ParamAgentBuilder<POL,DAT,ParamBuildSpec>{spec.makeBlockBuilder()};
|
||||
}
|
||||
|
||||
/**
|
||||
* Entrance point for building actual Render Node Connectivity (Level-2)
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ namespace engine {
|
|||
}
|
||||
};
|
||||
|
||||
auto
|
||||
inline auto
|
||||
buildParamSpec()
|
||||
{
|
||||
return ParamBuildSpec<TurnoutSystem::FrontBlock>{tuple<>{}};
|
||||
|
|
|
|||
Loading…
Reference in a new issue