diff --git a/src/steam/engine/proc-node.cpp b/src/steam/engine/proc-node.cpp index c6d407742..f8d16e22a 100644 --- a/src/steam/engine/proc-node.cpp +++ b/src/steam/engine/proc-node.cpp @@ -218,4 +218,27 @@ namespace engine { } + lib::Several + PortDiagnostic::srcPorts() + { + UNIMPLEMENTED ("intrude into the Turnout and find out about source connectivity"); + } + + /** + * @return the symbolic string representing this processing port, + * as [provided by Node-identification](\ref ProcID::genProcSpec()) + */ + string + PortDiagnostic::getProcSpec() + { + p_.procID.genProcSpec(); + } + + HashVal + PortDiagnostic::getProcHash() ///< @return as [calculated by Node-identification](\ref ProcID) + { + UNIMPLEMENTED ("calculate an unique, stable and reproducible hash-key to identify the Turnout"); + } + + }} // namespace steam::engine diff --git a/src/steam/engine/proc-node.hpp b/src/steam/engine/proc-node.hpp index db38c551b..62ba708cc 100644 --- a/src/steam/engine/proc-node.hpp +++ b/src/steam/engine/proc-node.hpp @@ -200,15 +200,9 @@ namespace engine { /** - * Key abstraction of the Render Engine: A Data processing Node + * Key abstraction of the Render Engine: A Data processing Node. * - * @todo it's not clear as of 9/09 if ProcNode shall be an ABC/Interface - * It might be used as ABC (as was the original intention) when implementing - * several query/information functions. In that case, the ctor will become protected. - * The alternative would be to push down these information-retrieval part into a - * configurable element within Connectivity, in which case we even might drop - * ProcNode as a frontend entirely. - * @todo WIP-WIP-WIP 2024 Node-Invocation is reworked from ground up for the »Playback Vertical Slice« + * @todo WIP 2025 Node-Invocation is reworked from ground up for the »Playback Vertical Slice« */ class ProcNode : util::NonCopyable @@ -217,16 +211,10 @@ namespace engine { Connectivity wiring_; public: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation ProcNode (Connectivity&& con) : wiring_(move(con)) { } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - - - public: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation Port& getPort (uint portIdx) @@ -258,14 +246,14 @@ namespace engine { TurnoutSystem turnoutSystem{nomTime, procKey}; return getPort(portIdx).weave (turnoutSystem, output); } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation /// „backdoor“ to watch internals from tests friend class ProcNodeDiagnostic; }; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation + /* ========== Diagnostic and Testing ========== */ + class ProcNodeDiagnostic : util::MoveOnly { @@ -302,5 +290,31 @@ namespace engine { } + + class PortDiagnostic + : util::MoveOnly + { + Port& p_; + + public: + PortDiagnostic (Port& thePort) + : p_{thePort} + { } + + lib::Several srcPorts(); + + bool isSrc() { return srcPorts().empty(); } + + string getProcSpec(); ///< generate a descriptive diagnostic Spec for the Turnout sitting behind this Port + HashVal getProcHash(); ///< calculate an unique, stable and reproducible hash-key to identify the associated operation + }; + + inline PortDiagnostic + watch (Port& thePort) + { + return PortDiagnostic{thePort}; + } + + }} // namespace steam::engine #endif /*STEAM_ENGINE_PROC_NODE_H*/ diff --git a/tests/core/steam/engine/node-link-test.cpp b/tests/core/steam/engine/node-link-test.cpp index 58f0d14b8..75e8557d2 100644 --- a/tests/core/steam/engine/node-link-test.cpp +++ b/tests/core/steam/engine/node-link-test.cpp @@ -23,7 +23,9 @@ #include "lib/test/diagnostic-output.hpp"/////////////////TODO #include "lib/util.hpp" +#include +using std::array; using util::isnil; //using std::string; using util::isSameObject; @@ -122,31 +124,79 @@ namespace test { void build_connected_nodes() { - auto srcOp = [](int param, int* res){ *res = param; }; + // This operation emulates a data source + auto src_op = [](int param, int* res){ *res = param; }; // A Node with two (source) ports ProcNode n1{prepareNode("n1") .preparePort() - .invoke("a(int)", srcOp) + .invoke("a(int)", src_op) .setParam(5) .completePort() .preparePort() - .invoke("b(int)", srcOp) + .invoke("b(int)", src_op) .setParam(23) .completePort() .build()}; - auto add1Op = [](int* src, int* res){ *res = 1 + *src; }; + // A node to add some "processing" to each data chain + auto add1_op = [](int* src, int* res){ *res = 1 + *src; }; ProcNode n2{prepareNode("n2") .preparePort() - .invoke("+1(int)(int)", add1Op) + .invoke("+1(int)(int)", add1_op) .connectLead(n1) .completePort() .preparePort() - .invoke("+1(int)(int)", add1Op) + .invoke("+1(int)(int)", add1_op) .connectLead(n1) .completePort() .build()}; + + // Need a secondary source, this time with three ports + ProcNode n1b{prepareNode("n1b") + .preparePort() + .invoke("a(int)", src_op) + .setParam(7) + .completePort() + .preparePort() + .invoke("b(int)", src_op) + .setParam(13) + .completePort() + .preparePort() + .invoke("c(int)", src_op) + .setParam(17) + .completePort() + .build()}; + + // This operation emulates mixing of two source chains + auto mix_op = [](array src, int* res){ *res = (*src[0] + *src[1]) / 2; }; + + // Wiring for the Mix, building up three ports + // Since the first source-chain has only two ports, + // for the third result port we'll re-use the second source + ProcNode n3{prepareNode("n2") + .preparePort() + .invoke("A.mix(int/2)(int)", mix_op) + .connectLead(n2) + .connectLead(n1b) + .completePort() + .preparePort() + .invoke("B.mix(int/2)(int)", mix_op) + .connectLead(n2) + .connectLead(n1b) + .completePort() + .preparePort() + .invoke("C.mix(int/2)(int)", mix_op) + .connectLeadPort(n2,1) + .connectLead(n1b) + .completePort() + .build()}; + +SHOW_EXPR(watch(n1).getNodeSpec()) +SHOW_EXPR(watch(n1).getPortSpec(0)) +SHOW_EXPR(watch(n1).getPortSpec(1)) +SHOW_EXPR(watch(n1.getPort(0)).getProcSpec()) +SHOW_EXPR(watch(n1.getPort(0)).isSrc()) } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index be2d03b53..e81753204 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -98899,6 +98899,16 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + + + + + @@ -98911,6 +98921,17 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + + + + + + @@ -99292,8 +99313,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + @@ -99509,6 +99530,68 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ...und zwar bewußt; +

+

+ zunächst wollte ich ja einen Routing-Descriptor, um damit nochemal eine zweite Indirektion / Flexibilisierung gegenüber dem InvocationAdapter zu machen. Dann hat sich aber die Bedeutung des Invocation-Adapters so verschoben, daß ein Teil seiner Rolle mit der FeedManifold verschmolzen ist, dafür aber ein rigideres Belegungsschema dem Binding-Functor abverlangt wird. Damit wurde explizite oder schematische Routing-Info eigentlich irrelevant, und ich habe sie durch direkte Referenzen ersetzt. Und das ist nun das Problem. +

+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
@@ -99666,9 +99749,9 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - + - + @@ -99685,8 +99768,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) in der friend-Deklaration, sowie im Argument des intendierten Konstruktors (wenigstens bin ich konsequent...)

- - +
@@ -99696,8 +99778,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) ...denn die einzelnen Klauseln werden nur instantiiert wenn angesprochen. In einem bisher nie aktivierten Codepfad können ganz banale Fehler lange überdauern ...

- -
+ @@ -99717,8 +99798,49 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
- - + + + + + + + + + + + +

+ Das ist ein realistisches Beispiel: +

+
    +
  • + zwei Clips +
  • +
  • + der erste Quell-Clip ist noch mit einem Effekt belegt +
  • +
  • + allerdings ist der erste Clip auch nur in zwei Ports aufbereitet (warum auch immer) +
  • +
  • + der Mix soll jedoch für drei Ports bereitgestellt werden (warum auch immer — beispielsweise könnten die Unterschiede nur im 2.Chain tatsächlich bestehen, weil dieser ein anderes Farbformat hat) +
  • +
+ + +
+ +
+ + + + + + + + + +
@@ -102077,8 +102199,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) Im Rückblick ist das, was mir dann passiert ist, also folgerichtig, und ich habe mich richtig verhalten, indem ich den Ansatz „hängen ließ“....

- - +
@@ -102103,7 +102224,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension) - +