From d73b316eadd020250b50eecb9ae9ff653ffeea66 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 27 Apr 2023 19:38:37 +0200 Subject: [PATCH] Segmentation: consider preliminary data structure ...and consider how that can be extended later into the full structure, which has to support a transactional switch --- src/lib/time/time.cpp | 1 + src/lib/time/timevalue.hpp | 2 + src/steam/fixture/fixture.hpp | 4 +- src/steam/fixture/segment.hpp | 19 ++- src/steam/fixture/segmentation.hpp | 17 ++- tests/46engine.tests | 10 ++ tests/core/steam/engine/mock-dispatcher.hpp | 4 +- tests/core/steam/engine/mock-support-test.cpp | 139 ++++++++++++++++++ wiki/renderengine.html | 16 +- wiki/thinkPad.ichthyo.mm | 84 +++++++++++ 10 files changed, 280 insertions(+), 16 deletions(-) create mode 100644 tests/core/steam/engine/mock-support-test.cpp diff --git a/src/lib/time/time.cpp b/src/lib/time/time.cpp index 8ea0c97e7..2a8a4c7b4 100644 --- a/src/lib/time/time.cpp +++ b/src/lib/time/time.cpp @@ -296,6 +296,7 @@ namespace time { return reinterpret_cast (maxDelta); }(); + const TimeSpan TimeSpan::ALL {Time::MIN, Duration::MAX}; }} // namespace lib::Time diff --git a/src/lib/time/timevalue.hpp b/src/lib/time/timevalue.hpp index 47de5cfd7..0e9548eae 100644 --- a/src/lib/time/timevalue.hpp +++ b/src/lib/time/timevalue.hpp @@ -600,6 +600,8 @@ namespace time { TimeSpan conform() const; ///< @return a copy conformed to time domain limits + static const TimeSpan ALL; + Duration& duration() { diff --git a/src/steam/fixture/fixture.hpp b/src/steam/fixture/fixture.hpp index 28a931c51..4f6aa69c5 100644 --- a/src/steam/fixture/fixture.hpp +++ b/src/steam/fixture/fixture.hpp @@ -77,11 +77,11 @@ namespace fixture { : util::NonCopyable { protected: - /////////////////////////////////////////////////TODO: placeholder code + ///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #725 : placeholder code list content_; unique_ptr partitioning_; - /////////////////////////////////////////////////TICKET #573 who creates the fixture? + ///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #573 who creates the fixture? public: list & getPlaylistForRender () ; diff --git a/src/steam/fixture/segment.hpp b/src/steam/fixture/segment.hpp index a6dd17cb3..4e3e3d200 100644 --- a/src/steam/fixture/segment.hpp +++ b/src/steam/fixture/segment.hpp @@ -43,31 +43,38 @@ namespace steam { namespace fixture { using mobject::ExplicitPlacement; + using lib::time::TimeSpan; /** * For the purpose of building and rendering, the fixture (for each timeline) - * is partitioned such that each segment is structurally constant. - * For each segment there is a RenderGraph (unit of the render engine) which - * is able to render all ExitNodes for this segment. + * is partitioned such that each segment is _structurally constant._ + * For each segment there is a RenderGraph (unit of the render engine) + * which is able to render all ExitNodes for this segment. * * @ingroup fixture * @todo 1/2012 Just a Placeholder. The real thing is not yet implemented. + * @todo WIP-WIP as of 4/2023 -- about to pull up the engine backbone * @see http://lumiera.org/wiki/renderengine.html#Fixture */ class Segment { protected: - typedef lib::time::TimeSpan Span; /** begin of this timeline segment. */ - Span span_; + TimeSpan span_; + ///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #725 : placeholder code /** relevant MObjects comprising this segment. */ list elements; // TODO: actually necessary?? // TODO: ownership?? + ///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #725 : placeholder code + public: + Segment (TimeSpan covered =TimeSpan::ALL) + : span_{covered} + { } - /////////////////////////////////////////////////TODO: placeholder code + // default copy acceptable }; diff --git a/src/steam/fixture/segmentation.hpp b/src/steam/fixture/segmentation.hpp index fb6a4d087..601f7d704 100644 --- a/src/steam/fixture/segmentation.hpp +++ b/src/steam/fixture/segmentation.hpp @@ -48,6 +48,7 @@ #include "steam/fixture/segment.hpp" +#include "lib/nocopy.hpp" #include @@ -72,14 +73,28 @@ namespace fixture { * @see http://lumiera.org/wiki/renderengine.html#Fixture */ class Segmentation + : util::NonCopyable { - /////////////////////////////////////////////////TODO: placeholder code + ///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1243 : preliminary implementation /** segments of the engine in ordered sequence. */ list segments_; public: virtual ~Segmentation(); ///< this is an interface + + protected: + Segmentation() ///< there is always a single cover-all Segment initially + : segments_{1} + { } + + public: + size_t + size() const + { + return segments_.size(); + } + }; diff --git a/tests/46engine.tests b/tests/46engine.tests index 968639754..06c2e8262 100644 --- a/tests/46engine.tests +++ b/tests/46engine.tests @@ -49,6 +49,16 @@ return: 0 END +PLANNED "Setup for render job planning" JobPlanningSetup_test < specs) - : tickets_{} + : MockSegmentation{} { UNIMPLEMENTED ("populate mock sequence structure"); } diff --git a/tests/core/steam/engine/mock-support-test.cpp b/tests/core/steam/engine/mock-support-test.cpp new file mode 100644 index 000000000..0d2acd358 --- /dev/null +++ b/tests/core/steam/engine/mock-support-test.cpp @@ -0,0 +1,139 @@ +/* + MockSupport(Test) - verify test support for fixture and job dispatch + + 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 mock-support-test.cpp + ** unit test \ref MockSupport_test + */ + + +#include "lib/test/run.hpp" +#include "lib/error.hpp" +#include "steam/engine/mock-dispatcher.hpp" +#include "vault/engine/dummy-job.hpp" + +#include "lib/format-cout.hpp"///////////////////////TODO + +//#include "steam/engine/job-planning.hpp" + +//#include + +using test::Test; +//using std::rand; + + +namespace steam { +namespace engine{ +namespace test { + + using vault::engine::DummyJob; + + namespace { // test fixture... + + } // (End) test fixture + + + + /**********************************************************************//** + * @test validate test support for render job planning and dispatch. + * - creating and invoking mock render jobs + * - a mocked JobTicket, generating mock render jobs + * - configurable test setup for a mocked Segmentation datastructure + * + * @todo WIP-WIP-WIP 4/2023 + * + * @see JobPlanningSetup_test + * @see Dispatcher + * @see vault::engine::Job + * @see steam::fixture::Segmentation + */ + class MockSupport_test : public Test + { + + virtual void + run (Arg) + { + simpleUsage(); + verify_MockJob(); + verify_MockJobTicket(); + verify_MockSegmentation(); + } + + + /** @test simple usage example of the test helpers */ + void + simpleUsage() + { + TODO ("simple usage example"); + } + + + /** @test document and verify usage of a mock render job */ + void + verify_MockJob() + { + Time nominalTime = lib::test::randTime(); + int additionalKey = rand() % 5000; + Job mockJob = DummyJob::build (nominalTime, additionalKey); + CHECK (mockJob.getNominalTime() == nominalTime); + CHECK (not DummyJob::was_invoked (mockJob)); + + mockJob.triggerJob(); + CHECK ( DummyJob::was_invoked (mockJob)); + CHECK (RealClock::wasRecently (DummyJob::invocationTime (mockJob))); + CHECK (nominalTime == DummyJob::invocationNominalTime (mockJob) ); + CHECK (additionalKey == DummyJob::invocationAdditionalKey(mockJob)); + + Time prevInvocation = DummyJob::invocationTime (mockJob); + mockJob.triggerJob(); + CHECK (prevInvocation < DummyJob::invocationTime (mockJob)); // invoked again, recorded new invocation time + CHECK (nominalTime == DummyJob::invocationNominalTime (mockJob) ); // all other Job parameter recorded again unaltered + CHECK (additionalKey == DummyJob::invocationAdditionalKey(mockJob)); + } + + + /** @test document and verify usage of a mock JobTicket for frame dispatch */ + void + verify_MockJobTicket() + { + MockJobTicket mockTick; + CHECK (mockTick.discoverPrerequisites().empty()); + TODO ("cover details of MockJobTicket"); + } + + + /** @test document and verify usage of a complete mocked Segmentation to back frame dispatch */ + void + verify_MockSegmentation() + { + MockSegmentation mockSeg; + CHECK (1 == mockSeg.size()); + TODO ("cover details of MockSegmentation"); + } + }; + + + /** Register this test class... */ + LAUNCHER (MockSupport_test, "unit engine"); + + + +}}} // namespace steam::engine::test diff --git a/wiki/renderengine.html b/wiki/renderengine.html index a0913389e..ab37cd62d 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -2303,7 +2303,7 @@ Any feed corresponds to a specific ModelPort, which in turn typically correspond When starting playback or render, a play process (with a PlayController front-end for client code) is established to coordinate the processing. This ongoing data production might encompass multiple media streams, i.e. multiple feeds pulled from several model ports and delivered into several [[output slots|OutputSlot]]. Each feed in turn might carry structured MultichannelMedia, and is thus further structured into individual [[streams of calculation|CalcStream]]. Since the latter are //stateless descriptors,// while the player and play process obviously is stateful, it's the feed's role to mediate between a state-based (procedural) and a stateless (functional and parallelised) organisation model -- ensuring a seamless data feed even during modification of the playback parameters. -
+
a specially configured view -- joining together high-level and low-level model.
 The Fixture acts as //isolation layer// between the two models, and as //backbone to attach the render nodes.//
 * all MObjects have their position, length and configuration set up ready for rendering.
@@ -2335,9 +2335,13 @@ The fixture is like a grid, where one dimension is given by the [[model ports|Mo
 ;Exit Nodes
 :Each segment holds an ExitNode for each relevant ModelPort of the corresponding timeline.
 :Thus the exit nodes are keyed by ~Pipe-ID as well (and consequently have a distinct [[stream type|StreamType]]) -- each model port coresponds to {{{<number_of_segments>}}} separate exit nodes, but of course an exit node may be //mute//&nbsp; in some segmehts.
+
+!!!Dependencies
+At architecture level, the Fixture is seen as //interface// between Steam-Layer and Vault-Layer.
+This raises the question: {{red{(WIP 4/23) where is the fixture data structure defined, in terms of code dependencies?}}}
 
-
+
Generally speaking, the datastructure to implement the ''Fixture'' (&rarr; see a more general description [[here|Fixture]]) is comprised of a ModelPortRegistry and a set of [[segmentations|Segmentation]] per Timeline.
 This page focusses on the actual data structure and usage details on that level. See also &rarr; [[storage|FixtureStorage]] considerations.
 
@@ -2345,6 +2349,7 @@ This page focusses on the actual data structure and usage details on that level.
 A key point to note is the fact that the fixture is frequently [[re-built|BuildFixture]] by the [[Builder]], while render processes may be going on in parallel. Thus, when a build process is finished, a transactional ''commit'' happens to ''hot swap'' the new parts of the model. This is complemented by a clean-up of tainted render processes; finally, storage can be reclaimed.
 
 To support this usage pattern, the Fixture implementation makes use of the [[PImpl pattern|http://c2.com/cgi/wiki?PimplIdiom]]
+Ongoing [[Builder]] activity especially can remould the Segmentation on a copy of the implementation structure, which is then swapped as a whole.
 
 !Collecting usage scenarios {{red{WIP 12/10}}}
 * ModelPort access
@@ -2362,9 +2367,10 @@ To support this usage pattern, the Fixture implementation makes use of the [[PIm
 ** commit a transaction
  
 
-!Conclusions about the structure {{red{WIP 12/10}}}
-* the ~PImpl needs to be a single (language) pointer. This necessitates having a monolithic Fixture implementation holder
-* moreover, this necessitates a tight integration down to implementation level, both with the clean-up and the render processes themselves
+!Conclusions about the structure {{red{WIP 12/10 … update 4/23}}}
+* the ~PImpl needs to be a single ''atomic pointer''. This necessitates having a monolithic Fixture implementation holder
+* consequently we need a tailored memory management -- requiring some (limited) knowledge about the usage pattern
+* this kind of information is available within the scheduling process ⟹ the [[Scheduler]] must support triggering on dependency events
 
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 99a1c7041..023bfc325 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -69577,6 +69577,9 @@ + + + @@ -69687,6 +69690,44 @@ + + + + + + + + + + + + + + + +

+ ...das wird dann später die Basis für die Implementierung des Change-Builders +

+
    +
  • + diese Operation untersucht die bestehende Segmentation +
  • +
  • + und spaltet bestehende Segmente auf +
  • +
  • + sie kann unterscheiden zwischen Umbau(=replacement) und Kürzen bzw. Klonen eines Segments +
  • +
  • + Schlußfolgerung: ein Segment selbst darf nichts über seine Zeitspanne wissen +
  • +
+ +
+ +
+
+
@@ -69821,6 +69862,13 @@ + + + + + + + @@ -70260,7 +70308,43 @@ + + + + + + + + +

+ es gibt einen commit +

+ +
+
+ + + + + + + +

+ Einträge sind woanders alloziert +

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