From 3b2e5db7b4439292eae0ec8050ddce8145a50e68 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 6 Jun 2023 04:25:12 +0200 Subject: [PATCH] Dispatcher-Pipeline: consider how to access render nodes from job ...this opens up yet another difficult question and a host of new problems - how are prerequisites detected or arranged by the Builder - how are prerequisites represented? - what is an ExitNode in terms of implementation? A subclass of ProcNode? - how will the actual implementation of JobTicket creation (on-demand) work? - how to adapt the Mock implementation, while retaining the Specification for Segments and prerequisites? --- src/steam/engine/exit-node.hpp | 74 ++++ src/steam/engine/job-ticket.hpp | 2 +- src/steam/engine/nodefactory.cpp | 5 + src/steam/fixture/node-graph-attachment.hpp | 77 ++++ src/steam/fixture/segment.hpp | 5 +- src/vault/engine/job.h | 2 +- .../steam/engine/job-planning-setup-test.cpp | 4 +- tests/core/steam/engine/mock-dispatcher.hpp | 8 + .../mobject/placement-hierarchy-test.cpp | 2 - wiki/thinkPad.ichthyo.mm | 335 +++++++++++++++++- 10 files changed, 495 insertions(+), 19 deletions(-) create mode 100644 src/steam/engine/exit-node.hpp create mode 100644 src/steam/fixture/node-graph-attachment.hpp diff --git a/src/steam/engine/exit-node.hpp b/src/steam/engine/exit-node.hpp new file mode 100644 index 000000000..3460335ca --- /dev/null +++ b/src/steam/engine/exit-node.hpp @@ -0,0 +1,74 @@ +/* + EXIT-NODE.hpp - top-level node of the render network to pull generated media + + Copyright (C) Lumiera.org + 2023, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** @file exit-node.hpp + ** Effective top-level exit point to pull rendered data from the nodes network. + ** + ** @todo 6/2023 WIP-WIP used as placeholder; relation to ProcNode not yet determined /////////////TICKET #1306 + ** @see procnode.hpp + */ + +#ifndef ENGINE_EXIT_NODE_H +#define ENGINE_EXIT_NODE_H + +#include "lib/error.hpp" +#include "lib/nocopy.hpp" +#include "lib/hash-value.h" + +#include + +using lib::HashVal; + + +namespace steam { +namespace engine { + + class ExitNode; + using ExitNodes = std::vector; + + + + /** + * A top-level point in the render node network where data generation can be driven. + * + * @todo 6/2023 for the »Playback Vertical Slice« we need somehow to represent "the nodes", + * while the final solution how to hook up ProcNode and how to represent prerequisites + * remains still to be settled. So this is a placeholder to support mock testing for now. + */ + class ExitNode + : util::NonCopyable + { + HashVal pipelineIdentity_; //////////////////////////////////////////////////////////TICKET #1293 : Hash-Chaining for invocation-ID... derive from ProcNode wiring + ExitNodes prerequisites_; ///////////////////////////////////////////////////////////TICKET #1306 : actual access to low-level-Model (ProcNode) + + public: + ExitNode() + : pipelineIdentity_{0} + , prerequisites_{} + { } + + static ExitNode NIL; + }; + + +}} // namespace steam::engine +#endif /*ENGINE_EXIT_NODE_H*/ diff --git a/src/steam/engine/job-ticket.hpp b/src/steam/engine/job-ticket.hpp index c6f96c0dc..9339745aa 100644 --- a/src/steam/engine/job-ticket.hpp +++ b/src/steam/engine/job-ticket.hpp @@ -118,7 +118,7 @@ using lib::LUID; Provision (JobFunctor& func, HashVal seed =0) : jobFunctor{func} , invocationSeed(static_cast(func).buildInstanceID(seed)) ////////////////TICKET #1287 : fix actual interface down to JobFunctor (after removing C structs) - { } + { } /////////////////TICKET #1293 : Hash-Chaining for invocation-ID... size_t hash? or a LUID? }; diff --git a/src/steam/engine/nodefactory.cpp b/src/steam/engine/nodefactory.cpp index 1bdb4bf63..5851b3b8a 100644 --- a/src/steam/engine/nodefactory.cpp +++ b/src/steam/engine/nodefactory.cpp @@ -29,6 +29,7 @@ */ +#include "steam/engine/exit-node.hpp" #include "steam/engine/nodefactory.hpp" #include "steam/mobject/session/effect.hpp" #include "lib/allocation-cluster.hpp" @@ -38,6 +39,10 @@ namespace steam { namespace engine { + /// storage for the »inactive« ExitNode marker + ExitNode ExitNode::NIL{}; + + namespace { // Details of node fabrication ////////////////////////////////////////////////TODO: still needed? diff --git a/src/steam/fixture/node-graph-attachment.hpp b/src/steam/fixture/node-graph-attachment.hpp new file mode 100644 index 000000000..d0e2d5c43 --- /dev/null +++ b/src/steam/fixture/node-graph-attachment.hpp @@ -0,0 +1,77 @@ +/* + NODE-GRAPH-ATTACHMENT.hpp - Binding from a Fixture-Segment into the low-level-Model + + Copyright (C) Lumiera.org + 2023, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file node-graph-attachment.hpp + ** Link from the Fixture datastructure into the render node network. + ** The Segmentation is a partitioning of the effective timeline into segments with + ** uniform processing structure; however this structure itself is defined as a graph + ** of [render nodes](\ref engine::ProcNode); any specifics and decisions how rendering + ** actually happens are represented in the way some ModelPort is connected to the model, + ** which is the purpose of this binding object, stored as part of each Segment. + ** + ** @todo 2023 WIP-WIP-WIP »Playback Vertical Slice« need at least a drafted model + */ + + +#ifndef STEAM_FIXTURE_NODE_GRAPH_ATTACHMENT_H +#define STEAM_FIXTURE_NODE_GRAPH_ATTACHMENT_H + +#include "steam/engine/exit-node.hpp" +//#include "lib/time/timevalue.hpp" + +#include + +namespace steam { +namespace fixture { + + using ExitNodes = engine::ExitNodes; + + + /** + * Binding and access point from a given Segment to access the actual render nodes. + * For each ModelPort, we can expect to get an ExitNode (the number of ports is fixed + * for the complete Timeline). However, this ExitNode does not need to be active, since + * parts of the timeline can be empty, or partially empty for some ModelPort. + * + * @todo WIP-WIP as of 4/2023 -- starting with a fake implementation /////////////////////TICKET #1306 : create an actual link to the low-level Model + */ + class NodeGraphAttachment + { + ExitNodes exitNodes_; + + public: + NodeGraphAttachment() + : exitNodes_{} + { } + + NodeGraphAttachment (ExitNodes&& exitNodes) + : exitNodes_{std::move (exitNodes)} + { } + + // default copy acceptable + }; + + + +}} // namespace steam::fixture +#endif /*STEAM_FIXTURE_NODE_GRAPH_ATTACHMENT_H*/ diff --git a/src/steam/fixture/segment.hpp b/src/steam/fixture/segment.hpp index a15ad7fdf..f414bdcd9 100644 --- a/src/steam/fixture/segment.hpp +++ b/src/steam/fixture/segment.hpp @@ -31,14 +31,14 @@ #ifndef STEAM_FIXTURE_SEGMENT_H #define STEAM_FIXTURE_SEGMENT_H -#include #include "steam/common.hpp" #include "steam/mobject/explicitplacement.hpp" #include "steam/engine/job-ticket.hpp" #include "lib/time/timevalue.hpp" -using std::list; +#include + namespace steam { namespace fixture { @@ -46,6 +46,7 @@ namespace fixture { using mobject::ExplicitPlacement; using lib::time::TimeSpan; using lib::time::Time; + using std::list; /** * For the purpose of building and rendering, the fixture (for each timeline) diff --git a/src/vault/engine/job.h b/src/vault/engine/job.h index 29a1ac126..ef54eddbb 100644 --- a/src/vault/engine/job.h +++ b/src/vault/engine/job.h @@ -245,7 +245,7 @@ namespace engine { virtual JobKind getJobKind() const =0; virtual bool verify (Time, InvocationInstanceID) const =0; virtual HashVal hashOfInstance(InvocationInstanceID) const =0; - virtual InvocationInstanceID buildInstanceID(HashVal)const =0; + virtual InvocationInstanceID buildInstanceID(HashVal)const =0; ////////////////////////////TICKET #1293 : a size_t hash? or a LUID? lib::HashVal hash_value (JobParameter) const; }; diff --git a/tests/core/steam/engine/job-planning-setup-test.cpp b/tests/core/steam/engine/job-planning-setup-test.cpp index 51453d2e4..8e8555a18 100644 --- a/tests/core/steam/engine/job-planning-setup-test.cpp +++ b/tests/core/steam/engine/job-planning-setup-test.cpp @@ -199,12 +199,12 @@ namespace test { .pullFrom (port); CHECK (not isnil (pipeline)); - CHECK (nullptr == pipeline->first); + CHECK (nullptr == pipeline->first); // is a top-level ticket JobTicket const& ticket = *pipeline->second; FrameCoord dummy; Job job = ticket.createJobFor(dummy); - CHECK (MockJobTicket::isAssociated (job, ticket)); + CHECK (dispatcher.verify(job, port, sink)); } diff --git a/tests/core/steam/engine/mock-dispatcher.hpp b/tests/core/steam/engine/mock-dispatcher.hpp index f57090e22..9ff3af6e8 100644 --- a/tests/core/steam/engine/mock-dispatcher.hpp +++ b/tests/core/steam/engine/mock-dispatcher.hpp @@ -316,6 +316,14 @@ namespace test { { return dummySetup_.getModelPort (index); } + + /** + * Test support: verify the given Job is consistent with this Dispatcher. + */ + bool verify(Job const& job, ModelPort const& port, play::DataSink const& sink) + { + UNIMPLEMENTED ("verify the job was plausibly created from this dispatcher"); + } }; #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1221 diff --git a/tests/core/steam/mobject/placement-hierarchy-test.cpp b/tests/core/steam/mobject/placement-hierarchy-test.cpp index 5b11dc786..cd0e2986e 100644 --- a/tests/core/steam/mobject/placement-hierarchy-test.cpp +++ b/tests/core/steam/mobject/placement-hierarchy-test.cpp @@ -38,8 +38,6 @@ #include "lib/util.hpp" -using lib::HashIndexed; - namespace steam { namespace mobject { diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index ef8d828e5..f57741424 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -70068,7 +70068,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -70261,7 +70261,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + @@ -70275,7 +70277,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -70285,6 +70287,30 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + +

+ auch wenn es irre scheint, sehr wahrscheinlich werde ich den ganzen Scheduler entwickeln können, ohne jemals ein reales low-level-Model anzufassen; daher ist die Port-Nummer wahrscheinlich völlig egal, und es gnügt, lediglich die APIs entsprechend zu erweitern... +

+ +
+
+
+
@@ -74026,11 +74052,129 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ ich gehe davon aus, daß praktisch alle Tests, die dieses Mock-Framework verwenden, lediglich prüfen daß eine gewisse Connection durchgereicht wurde +

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

+ ...auf irgend ein Objekt... +

+

+ Allerdings — da die Segmente vermutlich nicht gemockt werden (sondern nur die Segmentation), muß ich mich da schon um eine Allokation für ein Dummy-Objekt kümmern +

+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -74068,7 +74212,6 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- @@ -74133,6 +74276,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + +
@@ -74267,7 +74420,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + @@ -74275,6 +74432,24 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + +

+ das ist adäquat, da in diesem Bereich grundsätzlich nichts mehr gecheckt wird (das hat alles schon der Builder getan) +

+ +
+
+
@@ -74422,9 +74597,6 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - @@ -74459,7 +74631,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -74502,6 +74674,32 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -74512,8 +74710,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + + + + + + +

+ ...zur Übersetzung der internen Strukturen im JobTicket in eine Folge verschachtelter Prerequisite-JobTicket +

+ +
+
@@ -74531,6 +74742,39 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + +

+ denn diese wären rekursiv wieder JobTickets; würde man die Aufteilung nach ModelPort in das JobTicket selber hineinnehmen, dann wären auch die Prerequisites wieder nach ModelPort untergliedert; das wiederspricht den Freiheitsgraden der Struktur (Prerequisites sind an die einzelne ExitNode gebunden) +

+ +
+ +
+ + + + + + +

+ Grundsätzlich ist es erst mal egal, man braucht eben einen Descriptor-Record pro Segment pro ModelPort. Da aber JobTickets on-demand erzeugt werden, wird der Aufwand hierfür verschoben in die Job-Planung (und findet gar nicht statt, solange eine bestimmte ExitNode konkret noch gar nicht bespielt wurde) +

+ +
+ +
+ + + @@ -74719,6 +74963,30 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + @@ -74735,6 +75003,51 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + +

+ im low-level-Model selber gibt es keine Entscheidungslogik mehr; sofern es mehrere Ausprägungen oder Verzweigungen gibt, werden diese als Zweige im Modell explizit gemacht +

+ +
+
+ + + + + + +

+ die konkrete Ausprägung jedweder Eigenschaft findet im Node-Graph statt, nicht sonstwo in der Fixture. Beispielsweise ist im Node-Graph festgelegt, wo Caching stattfinden kann, oder welche Sub-Zweige als Prerequisites separat gescheduled werden. Die ExitNode aggregiert diese Informationen nur, und im JobTicket werden sie aufgehängt +

+ +
+
+ + + + + + +

+ sofern irgend eine Eigenschaft renderbar ist, gibt es eine Anknüpfung aus einem Segment per ModelPort-Nr in das Modell +

+ +
+
+
+