diff --git a/src/steam/engine/node-builder.hpp b/src/steam/engine/node-builder.hpp index 75007a2cb..e3c0320ec 100644 --- a/src/steam/engine/node-builder.hpp +++ b/src/steam/engine/node-builder.hpp @@ -61,6 +61,21 @@ ** build walk will traverse the connectivity graph depth-first, and then start invoking the ** Level-2 builder operations bottom-up to generate and wire up the corresponding Render Nodes. ** + ** ## Using custom allocators + ** + ** Since the low-level-Model is a massive data structure comprising thousands of nodes, each with + ** specialised parametrisation for some media handling library, and a lot of cross-linking pointers, + ** it is important to care for efficient usage of memory with good locality. Furthermore, the higher + ** levels of the build process will generate additional temporary data structures, which is gradually + ** refined until the actual render node network can be emitted. Each builder level can thus be + ** outfitted with a custom allocator — typically an instance of lib::AllocationCluster. Notably + ** the higher levels can be attached to a separate AllocationCluster instance, which will be + ** discarded when the build process is complete, while Level-2 (and below) uses the allocator + ** for the actual target data structure, which will be retained and until a complete segment + ** of the timeline is superseded and has been re-built. + ** @remark syntactically, the custom allocator specification is given after opening a top-level + ** builder, by means of the builder function `.withAllocator (args...)` + ** ** @todo WIP-WIP-WIP 7/2024 Node-Invocation is reworked from ground up -- some parts can not be ** spelled out completely yet, since we have to build this tightly interlocked system of ** code moving bottom up, and then filling in further details later working top-down. @@ -90,8 +105,8 @@ namespace engine { using std::move; using std::forward; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - namespace { // policy configuration + + namespace { // policy configuration for allocator template class ALO =std::void_t, typename...INIT> struct AlloPolicySelector @@ -120,13 +135,37 @@ namespace engine { template using BuilderType = lib::SeveralBuilder; }; - - template - using DataBuilder = typename POL::template BuilderType; - + // }//(End) internal policy configuration + /** + * Convenience builder to collect working data. + * Implemented through a suitable configuration of lib::SeveralBuilder, + * such as to embed and connect to the configured custom allocator, which + * serves the goal to package all generated node configuration data together + * into a compact memory block, which can be discarded in bulk, once a given + * segment of the low-level-Model has been superseded. + * @tparam POL policy configuration pick the desired allocator + * @tparam I interface type for lib::Several + * @remark in essence, this wrapper class creates the following setup + * \code + * makeSeveral() + * .withAllocator (args...); + * \endcode + */ + template + class DataBuilder + : public POL::template BuilderType + { + public: + template + DataBuilder (INIT&& ...alloInit) + : POL::template BuilderType{forward (alloInit)...} + { } + }; + + template class PortBuilder; @@ -134,24 +173,20 @@ namespace engine { class NodeBuilder : util::MoveOnly { - template - static auto - setupBuilder (INIT&& ...alloInit) - { - return POL::template setupBuilder (forward (alloInit)...); - } - - using PortData = DataBuilder; + using LeadRefs = DataBuilder; PortData ports_; - std::vector leads_{}; + LeadRefs leads_; + public: template NodeBuilder (INIT&& ...alloInit) - : ports_{setupBuilder (forward (alloInit)...)} + : ports_{forward (alloInit)...} + , leads_{forward (alloInit)...} { } + NodeBuilder addLead (ProcNode const& lead) { @@ -168,25 +203,39 @@ namespace engine { } - /** cross-builder function to specify usage of a dedicated *node allocator* */ + /** + * cross-builder function to specify usage of a dedicated *node allocator* + * @tparam ALO (optional) spec for the allocator to use + * @tparam INIT (optional) initialisation arguments for the allocator + * @remarks this is a front-end to the extension point for allocator specification + * exposed through lib::SeveralBuilder::withAllocator(). The actual meaning + * of the given parameters and the choice of the actual allocator happens + * through resolution of partial template specialisations of the extension + * point lib::allo::SetupSeveral. Some notable examples + * - withAllocator() attaches to a _monostate_ allocator type. + * - `withAllocator (ALO allo)` uses a C++ standard allocator + * instance `allo`, dedicated to produce objects of type `X` + * - `withAllocator (AllocationCluster&)` attaches to a specific + * AllocationCluster; this is the most relevant usage pattern + */ template class ALO =std::void_t, typename...INIT> auto withAllocator (INIT&& ...alloInit) { - return NodeBuilder>{forward(alloInit)...}; + using AllocatorPolicy = AlloPolicySelector; + return NodeBuilder{forward(alloInit)...}; } - /****************************************************//** - * Terminal: complete the Connectivity defined thus far. + /************************************************************//** + * Terminal: complete the ProcNode Connectivity defined thus far. */ Connectivity build() { - /////////////////////////////////////////////////////////////////////OOO actually use the collected data to build return Connectivity{ports_.build() - ,lib::makeSeveral().build() - ,NodeID{}}; + ,leads_.build() + ,NodeID{}}; //////////////////////////////////////OOO what's the purpose of the NodeID?? } }; @@ -232,13 +281,19 @@ namespace engine { /** * Entrance point for building actual Render Node Connectivity (Level-2) + * @note when using a custom allocator, the first follow-up builder function + * to apply should be `withAllocator(args...)`, prior to adding + * any further specifications and data elements. */ inline auto prepareNode() { return NodeBuilder{}; } - + + + + class ProcBuilder : util::MoveOnly diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 47293d759..a09e7e603 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -290,9 +290,7 @@ - - - +

...hängt am UI-Bus, @@ -322,9 +320,7 @@ - - - +

Sicht "von unten" @@ -359,9 +355,7 @@ - - - +

...es könnte auch den Feedback des Users meinen @@ -1422,9 +1416,7 @@ - - - +

und arbeitet asynchron @@ -2644,9 +2636,7 @@ - - - +

besserer Name: NotificationHub @@ -3955,9 +3945,7 @@ - - - +

#1174 UI self diagnostics window @@ -6322,9 +6310,7 @@ - - - +

z.B. in den Block mit den "default-Regeln" @@ -87409,7 +87395,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -87468,15 +87454,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + - - + + @@ -87501,9 +87487,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + @@ -87546,9 +87532,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

nicht als template-template-Parameter... @@ -87557,9 +87541,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...denn sonst wird man die ALO, INIT... - Parameter nicht los, sondern sie werden Teil des Builder-Typs (wir wollen aber, daß sie nur implizit in den Builder-Typ eingehen) @@ -87572,9 +87554,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

auf das muß sich der Builder abstützen, nicht auf den lib::SeveralBuilder oder dessen Policy @@ -87585,9 +87565,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...nicht versuchen, die beiden zu verbinden oder irgendwie durch default-Parameter ausdrücken @@ -87598,9 +87576,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

tja... und jedes nested template braucht ein Präfix "template <fun>" in der Syntax @@ -87610,6 +87586,35 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + +

+ ...und dann kann man es noch rund machen... +

+ +
+ + + + + + + + + + + + +

+ weil dieser Typ in die tatsächliche Linkage der Objektfelder eingeht +

+ +
+
+
+