From bcdcb3661546124fb9c6ac632a5662a4331a142f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 3 Feb 2025 03:27:06 +0100 Subject: [PATCH] Invocation: rearrange `MediaWeavingPattern` storage layout ...to create an ''access path for diagnostics'' and further evaluations while ''bypassing the VTable.'' It is a well-known downside of specifically typed, highly optimisable template-based code to create a dangerous leverage for generating spurious, mostly identical virtual function instances added for secondary concerns. Thus it is a consequence of this design choice, either to forego some diagnostic and analytical possibilities, or to exploit ''other means'' for retrieving internal data, which is needed for tangential purposes only. The solution pursued hereby exploits similar layout of various ''weaving pattern'' template instances to create an ''access backdoor'' for use cases beyond the primary performance-critical path. --- src/steam/engine/media-weaving-pattern.hpp | 51 ++-- src/steam/engine/param-weaving-pattern.hpp | 8 + src/steam/engine/turnout.hpp | 34 ++- tests/core/steam/engine/node-base-test.cpp | 1 + wiki/thinkPad.ichthyo.mm | 312 ++++++++++++++++++--- 5 files changed, 351 insertions(+), 55 deletions(-) diff --git a/src/steam/engine/media-weaving-pattern.hpp b/src/steam/engine/media-weaving-pattern.hpp index 06ce5a069..839d8d499 100644 --- a/src/steam/engine/media-weaving-pattern.hpp +++ b/src/steam/engine/media-weaving-pattern.hpp @@ -175,16 +175,18 @@ namespace engine { */ template struct MediaWeavingPattern - : INVO + : util::NonCopyable { using Feed = typename INVO::Feed; static_assert (_verify_usable_as_InvocationAdapter()); - Several leadPort; - Several outTypes; + Several leadPort_; + Several outTypes_; - uint resultSlot{0}; + uint resultSlot_{0}; + + INVO prototype_; /** forwarding-ctor to provide the detailed input/output connections */ template @@ -192,28 +194,28 @@ namespace engine { ,Several&& dr ,uint resultIdx ,ARGS&& ...args) - : INVO{forward(args)...} - , leadPort{move(pr)} - , outTypes{move(dr)} - , resultSlot{resultIdx} + : leadPort_{move(pr)} + , outTypes_{move(dr)} + , resultSlot_{resultIdx} + , prototype_{forward(args)...} { } Feed mount (TurnoutSystem& turnoutSys) { - ENSURE (leadPort.size() <= INVO::FAN_I); - ENSURE (outTypes.size() <= INVO::FAN_O); - return INVO::buildFeed (turnoutSys); + ENSURE (leadPort_.size() <= INVO::FAN_I); + ENSURE (outTypes_.size() <= INVO::FAN_O); + return prototype_.buildFeed (turnoutSys); } void pull (Feed& feed, TurnoutSystem& turnoutSys) { if constexpr (Feed::hasInput()) - for (uint i=0; i class Turnout @@ -140,7 +141,38 @@ namespace engine { return PAT::fix (feed, turnoutSys); } }; - + + + + /** + * @internal »Backdoor« for diagnostic + * @warning must be kept **layout compatible** with Turnout + */ + template + class _TurnoutDiagnostic + : public Port + , public PAT + { + BuffHandle + weave (TurnoutSystem&, OptionalBuff =std::nullopt) override + { + throw err::Fatal{"Diagnostic class -- must not be invoked"}; + } + + public: + /** + * Access to internals of the _Weaving Pattern_ bypassing the VTable. + * @remark a huge number of different _Weaving Pattern instances_ will be created, + * as result of implementing render functionality by delegating to some + * external media processing library. Each time, a highly optimised and + * tailored instance of Turnout::weave() is generated. However, by all + * means we must avoid generating additional repetitive generic code, + * which is only used occasionally and for unit-testing. + * Rather, with the help of this »backdoor«, diagnostic code can exploit + * the similar basic layout of weaving pattern templates to gain access + * to some common infrastructure, notably the predecessor ports. + */ + }; diff --git a/tests/core/steam/engine/node-base-test.cpp b/tests/core/steam/engine/node-base-test.cpp index b6b0cdd65..1319232bf 100644 --- a/tests/core/steam/engine/node-base-test.cpp +++ b/tests/core/steam/engine/node-base-test.cpp @@ -73,6 +73,7 @@ namespace test { { Time nomTime{rani(10'000),0}; // drive test with a random »nominal Time« <10s with ms granularity TurnoutSystem invoker{nomTime}; // a time spec is mandatory, all further parameters are optional + ////////////////////////////////OOO unfinished - demonstrate simple accesses to the TurnoutSystem } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 281c45724..7d88700f7 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -85267,7 +85267,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + @@ -94606,10 +94608,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + @@ -94649,9 +94654,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + @@ -94664,7 +94668,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -94673,6 +94677,22 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + @@ -100726,7 +100746,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + @@ -100859,7 +100881,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + @@ -102799,10 +102823,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - - - + + + + @@ -104811,7 +104835,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -104876,6 +104900,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)

+ + + + @@ -105346,7 +105374,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
- + @@ -105434,7 +105462,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -105479,7 +105507,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -105667,7 +105695,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -105856,6 +105884,56 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + +

+ Extended Attributes sollen diverse anderweitige Beschränkungen auffangen +

+ + +
+
+ + + + +

+ Wenn ein komplexer Sachverhalt überhaupt erst erschlossen werden soll, durch das Aufbauen einer orientierenden Struktur, so muß ein Vorgriff gemacht werden, der leider nur in den seltensten Fällen der Sache adäquat ist. Infolgedessen ist man dann an untaugliche Strukturen gebunden, deren Reparatur zu kostspielig wäre. Stattdessen hilft man sich mit darüber gelegten Layern, die Metadaten und erweiterte Attribute als Ankerpunkt verwenden +

+ + +
+ +
+ + + + +

+ Design-Paradoxon: das Design besonders relevanter Funktionalität ist selten adäquat +

+ + +
+
+ + + + + + + + + + + + + +
@@ -105907,13 +105985,20 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - + + + - + + + + + + + @@ -105965,31 +106050,179 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + - + + - + + + + + + + + + + + + + + + + + + + + + + +

+ das ist ein gradezu absurdes Unterfangen, +

+

+ den Konsequenzen des gewählten Designs +

+

+ zu entgehen.... +

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

+ aber all die damit ausgeschlossenen Möglichkeiten +

+

+ will ich dann doch auch noch haben... +

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

+ oder ein Trampolin? aber auf Basis welcher Laufzeit-Information? +

+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -106005,15 +106238,19 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
+ + +
- + + - - + + @@ -106026,15 +106263,20 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + - - - + + + + - + + + @@ -106637,6 +106879,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + @@ -106754,11 +107000,11 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - - + + - - + +