From 7d5c32e6b6b8cbe382feabc98917663ce021b6f2 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 5 Jun 2023 18:09:42 +0200 Subject: [PATCH] Dispatcher-Pipeline: draft test for JobTicket access --- src/lib/iter-tree-explorer.hpp | 9 ++ src/steam/engine/dispatcher.hpp | 63 ++++---- .../steam/engine/job-planning-setup-test.cpp | 16 +- wiki/thinkPad.ichthyo.mm | 140 +++++++++++++----- 4 files changed, 164 insertions(+), 64 deletions(-) diff --git a/src/lib/iter-tree-explorer.hpp b/src/lib/iter-tree-explorer.hpp index 18e7efc5c..f3da7df8f 100644 --- a/src/lib/iter-tree-explorer.hpp +++ b/src/lib/iter-tree-explorer.hpp @@ -1506,6 +1506,15 @@ namespace lib { return TreeExplorer (ResCore {move(*this)}); } + /** shortcut notation to invoke \ref expand(expandFunctor) followed by \ref expandAll() */ + template + auto + expandAll (FUN&& expandFunctor) + { + return this->expand (forward (expandFunctor)) + .expandAll(); + } + /** extension functionality to be used on top of expand(), to perform expansion on next iteration. * When configured, an expandChildren() call will not happen immediately, but rather in place of diff --git a/src/steam/engine/dispatcher.hpp b/src/steam/engine/dispatcher.hpp index 7004ecae1..8c6cfc2df 100644 --- a/src/steam/engine/dispatcher.hpp +++ b/src/steam/engine/dispatcher.hpp @@ -81,11 +81,10 @@ namespace engine { * instance for operating this planning process. Instead, together with each chunk of * planned jobs we generate a continuation job, which -- on activation -- will pick up * the planning of the next chunk. The Dispatcher interface was shaped especially to - * support this process, with a local JobBuilder for use within the continuation job, - * and a TimeAnchor to represent the continuation point. All the complexities of - * actually planning the jobs are hidden within the JobPlanningSequence, - * which, for the purpose of dispatching a series of jobs just looks - * like a sequence of job descriptors + * support this process, with a local PlanningPipeline for use within the RenderDrive + * incorporated into each CalcStream. All the complexities of actually planning the + * jobs are hidden within this pipeline, which, for the purpose of dispatching a + * series of jobs just looks like a sequence of job descriptors * * @todo 6/23 API is remoulded from ground up (»Playback Vertical Slice« integration effort) */ @@ -111,7 +110,6 @@ namespace engine { }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsolete struct PipeFrameTick; - struct PipeExpander; template struct PipelineBuilder; @@ -121,25 +119,33 @@ namespace engine { public: virtual ~Dispatcher(); ///< this is an interface + + /** + * Start a builder sequence to assemble a job-planning pipeline, backed by this Dispatcher. + * @param timings the frame-grid and further specs to use for a specific CalcStream + * @remark the given #PipelineBuilder object shall be used to supply the further parameters, + * thereby qualifying the actual planning steps necessary to arrive at a sequence + * of Jobs; these can be retrieved from the resulting iterator, ready for dispatch. + */ PipelineBuilder forCalcStream (Timings timings); + /** + * A complete job-planning pipeline: this »Lumiera Forward Iterator« drives the actual + * job-planning process on-demand. At the end of the pipeline, a sequence of render Jobs + * appears, ready for hand-over to the Scheduler. The PlanningPipeline itself wraps a + * »state-core« holding the current planning state; for operation it should be placed + * at a fixed location (typically in the CalcStream) and not duplicated, since this + * internal state ensures the generation of a distinct and unique sequence of Jobs + * for one specific data feed. During the lifetime of this iterator, the backing + * data structures in the Fixture must be kept alive and fixed in memory. + */ template class PlanningPipeline : public IT { - + ////////////////////////////////////////////////////////////////////////////////////////////TICKET #1275 : what further API-functions are necessary to control a running CalcStream? }; - /** - * access a special JobTicket to build a »FrameDropper« Job. - * @todo 6/2023 WIP and totally unclear if this is even a good idea to start with.... - */ - JobTicket& - getSinkTicketFor (play::DataSink sink) - { - UNIMPLEMENTED ("WTF is a SinkTicket???"); - } - protected: /** core dispatcher operation: based on the coordinates of a reference point, @@ -244,7 +250,7 @@ namespace engine { auto timeRange (Time start, Time after) { - PipelineBuilder::activate (start,after); + SRC::activate (start,after); return buildPipeline (lib::treeExplore (move(*this))); } // expected next to invoke pullFrom(port,sink) @@ -283,17 +289,16 @@ namespace engine { expandPrerequisites() { return buildPipeline ( - this->expand([](TicketDepend& currentLevel) + this->expandAll([](TicketDepend& currentLevel) { JobTicket const* parent = currentLevel.second; return lib::transformIterator (parent->getPrerequisites(0) ,[&parent](JobTicket const& prereqTicket) - { + { // parent shifted up to first pos return TicketDepend{parent, &prereqTicket}; } ); - }) - .expandAll()); + })); } /** @@ -303,12 +308,11 @@ namespace engine { auto feedTo (play::DataSink sink) { - auto pipeline = this->transform([sink](TicketDepend& currentLevel) + return terminatePipeline ( + this->transform([sink](TicketDepend& currentLevel) { return currentLevel.second; ///////////////////////////////OOO construct a JobPlanning here - }); - using PipeIter = decltype(pipeline); - return PlanningPipeline{move (pipeline)}; + })); } @@ -329,6 +333,13 @@ namespace engine { { return PipelineBuilder {move (treeExplorer)}; } + + template + PlanningPipeline + terminatePipeline(PIP&& treeExplorer) + { + return PlanningPipeline {move (treeExplorer)}; + } }; diff --git a/tests/core/steam/engine/job-planning-setup-test.cpp b/tests/core/steam/engine/job-planning-setup-test.cpp index 90bb392e5..51453d2e4 100644 --- a/tests/core/steam/engine/job-planning-setup-test.cpp +++ b/tests/core/steam/engine/job-planning-setup-test.cpp @@ -33,6 +33,7 @@ #include "lib/format-cout.hpp"///////////////////////TODO #include "lib/iter-tree-explorer.hpp" #include "lib/format-util.hpp" +#include "lib/util.hpp" //#include "steam/engine/job-planning.hpp" @@ -44,6 +45,7 @@ using lib::eachNum; using lib::treeExplore; using lib::time::PQuant; using lib::time::FrameRate; +using util::isnil; namespace steam { @@ -188,9 +190,21 @@ namespace test { void accessTopLevelJobTicket() { + play::Timings timings (FrameRate::PAL); MockDispatcher dispatcher; auto [port,sink] = dispatcher.getDummyConnection(0); - UNIMPLEMENTED ("transform into job ticket access"); + + auto pipeline = dispatcher.forCalcStream (timings) + .timeRange(Time{200,0}, Time{300,0}) + .pullFrom (port); + + CHECK (not isnil (pipeline)); + CHECK (nullptr == pipeline->first); + JobTicket const& ticket = *pipeline->second; + + FrameCoord dummy; + Job job = ticket.createJobFor(dummy); + CHECK (MockJobTicket::isAssociated (job, ticket)); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 58e6f57e1..ef8d828e5 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -73589,14 +73589,14 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - - - + + + @@ -73607,18 +73607,18 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

- + - + - + - - + + @@ -73634,7 +73634,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -73645,13 +73645,28 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

+ +
+ + + + + + +

+ So macht es der TreeExplorer selber, und nach etlichen Versuchen bin ich auch hier bei dieser Lösung gelandet (und zufrieden damit) +

+ +
+
- - + + - - + + + @@ -73692,11 +73707,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - - + + @@ -73823,9 +73838,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + @@ -73855,24 +73870,50 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - + + + + + + + + +

+ Der expand()-Mechanismus im TreeExplorer ist kein monadisches flatMap  — sondern nur ähnlich (aber an den intendierten Nutzen angepaßt): das Vater-Element erscheint zunächst selbst im Resultat-Iterator, und dann erst folgen expandierte Kind-Elemente; monadisches flatMap würde den Vater sofort konsumieren und rekursives flatMap würde sofort bis auf unterste Blatt-Ebene entfalten. Aber die Konsequenz ist: da wir den Vater selber einmal durchreichen, müssen Ergebnistyp und Quelltyp kompatibel sein +

+ +
+
- - + + - - + + + + + + + + + + + +

+ Fazit: in diesem dritten Anlauf konnte ich das Problem befriedigend lösen +

+ +
+ +
- + + - @@ -73886,13 +73927,19 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + + - + + + + + + @@ -73904,11 +73951,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + @@ -73916,6 +73963,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+
@@ -73929,7 +73977,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- +
@@ -73959,14 +74007,32 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + + + + + + + + + + + + + + + + + + +