diff --git a/src/steam/engine/exit-node.hpp b/src/steam/engine/exit-node.hpp index aea5a412d..60423a005 100644 --- a/src/steam/engine/exit-node.hpp +++ b/src/steam/engine/exit-node.hpp @@ -54,9 +54,13 @@ namespace engine { * @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. + * @warning ExitNode should ideally be NonCopyable, since it is referred by the JobTicket + * However, we need to clone-and-remould Segments (Split-Splice-Algo), and this implies + * that the render nodes can be shared among multiple Segments. If all these assessments + * are correct an only be decided when the actual memory management is settled. */ class ExitNode - : util::MoveOnly + : util::Cloneable { HashVal pipelineIdentity_; //////////////////////////////////////////////////////////TICKET #1293 : Hash-Chaining for invocation-ID... derive from ProcNode wiring ExitNodes prerequisites_; ///////////////////////////////////////////////////////////TICKET #1306 : actual access to low-level-Model (ProcNode) diff --git a/src/steam/fixture/node-graph-attachment.hpp b/src/steam/fixture/node-graph-attachment.hpp index 257f3e568..b7b453714 100644 --- a/src/steam/fixture/node-graph-attachment.hpp +++ b/src/steam/fixture/node-graph-attachment.hpp @@ -53,6 +53,9 @@ namespace fixture { * 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. + * @warning while this descriptor object is freely copyable, the referred ExitNode(s) are + * move-only, and will be referred by the JobTicket. Thus a Segment in the Fixture + * must remain fixed in memory as long as any derived render jobs are alive. * * @todo WIP-WIP as of 4/2023 -- starting with a fake implementation /////////////////////TICKET #1306 : create an actual link to the low-level Model */ diff --git a/src/steam/fixture/segment.hpp b/src/steam/fixture/segment.hpp index f414bdcd9..9cfbd05d1 100644 --- a/src/steam/fixture/segment.hpp +++ b/src/steam/fixture/segment.hpp @@ -33,10 +33,12 @@ #include "steam/common.hpp" +#include "steam/fixture/node-graph-attachment.hpp" #include "steam/mobject/explicitplacement.hpp" #include "steam/engine/job-ticket.hpp" #include "lib/time/timevalue.hpp" +#include #include @@ -47,6 +49,7 @@ namespace fixture { using lib::time::TimeSpan; using lib::time::Time; using std::list; + using std::move; /** * For the purpose of building and rendering, the fixture (for each timeline) @@ -56,7 +59,7 @@ namespace fixture { * * @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 + * @todo WIP-WIP as of 6/2023 -- about to establish the engine backbone * @see http://lumiera.org/wiki/renderengine.html#Fixture */ class Segment @@ -76,15 +79,23 @@ namespace fixture { // TODO: ownership?? ///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #725 : placeholder code public: +/////////////////////////////////////////////////////////////////////////////////////////////////////////////OOO : Obsolet ... nur für Umbau erhalten!! Segment (TimeSpan covered =TimeSpan::ALL ,const engine::JobTicket* ticket =nullptr) : span_{covered} , jobTicket_{ticket? ticket : &engine::JobTicket::NOP} //////////////////////////////////////////TICKET #1297 : ensure to provide a JobTicket for each ModelPort in initialisation { } +/////////////////////////////////////////////////////////////////////////////////////////////////////////////TODO Obsolet ... nur für Umbau erhalten!! + Segment (TimeSpan covered + ,NodeGraphAttachment&& modelLink) + : span_{covered} + , exitNode{move (modelLink)} + { } Segment (Segment const& original, TimeSpan changed) : span_{changed} , jobTicket_{original.jobTicket_} + , exitNode{original.exitNode} /////////////////////////////////////////////////////////////////////OOO really? cloning ExitNodes? { } // default copy acceptable @@ -92,6 +103,10 @@ namespace fixture { Time start() const { return span_.start(); } Time after() const { return span_.end(); } + /** connection to the render nodes network */ + NodeGraphAttachment exitNode; + + engine::JobTicket const& jobTicket() const /////////////////////////////////////////////////////////////////TICKET #1297 : introduce additional key per ModelPort here { diff --git a/src/steam/fixture/segmentation.cpp b/src/steam/fixture/segmentation.cpp index 472073daf..0c54202c0 100644 --- a/src/steam/fixture/segmentation.cpp +++ b/src/steam/fixture/segmentation.cpp @@ -72,6 +72,7 @@ namespace fixture { * creating a second (copied) part of the encompassing old Segment. * - in case the JobTicket is omitted, the new Segment will be marked as _passive_ * and any job created from such a Segment will then be a »NOP-job« + * @see SplitSplice_test */ Segment const& Segmentation::splitSplice (OptTime start, OptTime after, const engine::JobTicket* jobTicket) diff --git a/tests/46fixture.tests b/tests/46fixture.tests index 9b65cc882..b22666aa4 100644 --- a/tests/46fixture.tests +++ b/tests/46fixture.tests @@ -6,6 +6,11 @@ return: 0 END +PLANNED "A Segment in the Fixture" FixtureSegment_test < + + 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-test.cpp + ** unit test \ref NodeGraphAttachment_test + */ + + +#include "lib/test/run.hpp" +#include "steam/fixture/node-graph-attachment.hpp" +#include "steam/engine/mock-dispatcher.hpp" +#include "steam/engine/exit-node.hpp" +#include "lib/util.hpp" + +#include + + +namespace steam { +namespace fixture { +namespace test { + + using std::move; + using util::isnil; + using util::isSameObject; + using engine::ExitNode; + using lib::diff::MakeRec; + using engine::test::MockSegmentation; + + + /*****************************************************************************//** + * @test Verify properties and behaviour of a single Segment in the Segmentation + * - construction of a mocked Segment + * - TODO + * - TODO + * @see steam::fixture::Segment + * @see JobPlanningSetup_test + * @see MockSupport_test + */ + class FixtureSegment_test : public Test + { + + virtual void + run (Arg) + { + fabricate_MockSegment(); + retrieve_JobTicket(); + } + + + /** @test setup a properly structured ExitNode graph using the + * specification scheme supported by MockSegmentation + * @see MockSupport_test::verify_MockSegmentation + */ + void + fabricate_MockSegment() + { + // Build a Segmentation partitioned at 10s + MockSegmentation segmentation{MakeRec() + .attrib ("start", Time{0,10} + ,"mark", 101010) + .genNode()}; + CHECK (2 == segmentation.size()); + Segment const& seg = segmentation[Time{0,20}]; // access anywhere >= 10s + CHECK (Time(0,10) == seg.start()); + CHECK (Time::NEVER == seg.after()); + CHECK (101010 == seg.exitNode[0].getPipelineIdentity()); + } + + + /** @test on-demand generate a JobTicket from an existing NodeGraphAttachment + */ + void + retrieve_JobTicket() + { + MockSegmentation segmentation{MakeRec() + .attrib("mark", 13) // top-level: marked with hash/id = 13 + .scope(MakeRec() // ... defines two nested prerequisites + .attrib("mark",23) // + Prerequisite-1 hash/id = 23 + .genNode() + ,MakeRec() + .attrib("mark",55) // + Prerequisite-2 hash/id = 55 + .genNode() + ) + .genNode()}; + UNIMPLEMENTED("fabricate JobTicket from ExitNode-Graph"); +// // verify generated Node is assembled according to above spec... +// CHECK (13 == node.getPipelineIdentity()); +// auto feed = node.getPrerequisites(); +// CHECK (not isnil (feed)); +// CHECK (23 == feed->getPipelineIdentity()); +// ++feed; +// CHECK (55 == feed->getPipelineIdentity()); +// ++feed; +// CHECK (isnil (feed)); + } + }; + + + /** Register this test class... */ + LAUNCHER (FixtureSegment_test, "unit fixture"); + + + +}}} // namespace steam::fixture::test diff --git a/tests/core/steam/fixture/node-graph-attachment-test.cpp b/tests/core/steam/fixture/node-graph-attachment-test.cpp index c39f0b810..d370eb8cb 100644 --- a/tests/core/steam/fixture/node-graph-attachment-test.cpp +++ b/tests/core/steam/fixture/node-graph-attachment-test.cpp @@ -26,10 +26,9 @@ #include "lib/test/run.hpp" -//#include "lib/test/test-helper.hpp" #include "steam/fixture/node-graph-attachment.hpp" -#include "steam/engine/exit-node.hpp" #include "steam/engine/mock-dispatcher.hpp" +#include "steam/engine/exit-node.hpp" #include "lib/util.hpp" #include @@ -39,35 +38,21 @@ namespace steam { namespace fixture { namespace test { -// using util::isSameObject; using std::move; using util::isnil; -// -// using asset::Pipe; -// using asset::PPipe; -// using asset::Struct; -// using asset::Timeline; -// using asset::PTimeline; -// using lumiera::Query; + using util::isSameObject; using engine::ExitNode; -// -// typedef asset::ID PID; -// typedef asset::ID TID; -// -// typedef ModelPortRegistry::ModelPortDescriptor const& MPDescriptor; - - - namespace { // test environment - - } - - /*****************************************************************************//** * @test Verify the facade object used to connect from the Segments in the Fixture * into the actual render nodes network - * @see mobject::builder::FixtureChangeDetector + * - construction of ExitNode + * - composition of the NodeGraphAttachment including prerequisites + * - generation of a complete setup of fake ExitNodes from a test spec. + * @see steam::fixture::Segment + * @see JobPlanningSetup_test + * @see MockSupport_test */ class NodeGraphAttachment_test : public Test { @@ -75,7 +60,7 @@ namespace test { virtual void run (Arg) { - access_ExitNode(); + access_ExitNodeTree(); fabricate_MockExitNode(); } @@ -89,7 +74,7 @@ namespace test { * - access existing and non-existing index positions */ void - access_ExitNode() + access_ExitNodeTree() { CHECK (0 == ExitNode::NIL.getPipelineIdentity()); CHECK (isnil (ExitNode::NIL.getPrerequisites())); @@ -111,6 +96,8 @@ namespace test { CHECK (13 == succubus[0].getPipelineIdentity()); CHECK (23 == succubus[1].getPipelineIdentity()); CHECK (55 == succubus[1].getPrerequisites()->getPipelineIdentity()); + + CHECK (isSameObject (succubus[5], ExitNode::NIL)); // out-of-index access falls back to ExitNode::NIL } @@ -126,16 +113,17 @@ namespace test { engine::test::MockSegmentation builder; ExitNode node = builder.buildExitNodeFromSpec(MakeRec() - .attrib("mark", 13) - .scope(MakeRec() - .attrib("mark",23) + .attrib("mark", 13) // top-level: marked with hash/id = 13 + .scope(MakeRec() // ... defines two nested prerequisites + .attrib("mark",23) // + Prerequisite-1 hash/id = 23 .genNode() ,MakeRec() - .attrib("mark",55) + .attrib("mark",55) // + Prerequisite-2 hash/id = 55 .genNode() ) .genNode()); + // verify generated Node is assembled according to above spec... CHECK (13 == node.getPipelineIdentity()); auto feed = node.getPrerequisites(); CHECK (not isnil (feed)); diff --git a/tests/core/steam/fixture/segmentation-datastructure-test.cpp b/tests/core/steam/fixture/segmentation-integration-test.cpp similarity index 72% rename from tests/core/steam/fixture/segmentation-datastructure-test.cpp rename to tests/core/steam/fixture/segmentation-integration-test.cpp index 4c89888aa..728e613c8 100644 --- a/tests/core/steam/fixture/segmentation-datastructure-test.cpp +++ b/tests/core/steam/fixture/segmentation-integration-test.cpp @@ -1,5 +1,5 @@ /* - SegmentationDatastructure(Test) - verify basic properties of the Segmentation + SegmentationIntegration(Test) - verify basic properties of the Segmentation Copyright (C) Lumiera.org 2010, Hermann Vosseler @@ -20,8 +20,8 @@ * *****************************************************/ -/** @file segmentation-datastructure-test.cpp - ** unit test \ref SegmentationDatastructure_test +/** @file segmentation-integration-test.cpp + ** integration test \ref SegmentationIntegration_test */ @@ -86,11 +86,18 @@ namespace test { /*****************************************************************************//** - * @test TODO blubb - * + * @test Properties and behaviour of a complete Segmentation data structure. + * - access segments keyed by nominal time + * - determine the index-Nr of a ModelPort + * - transactional remoulding of the Segmentation + * - retrieve effective changes after remoulding + * - integration with AllocationCluster memory managment + * @todo 2010 ⁐ 2023 a sketch for a test setup, which was meanwhile elaborated + * into the DummyPlayConnection; indeed such a component integration test + * is still required to document and cover the fixture data structure.... * @see mobject::builder::FixtureChangeDetector */ - class SegmentationDatastructure_test : public Test + class SegmentationIntegration_test : public Test { virtual void @@ -110,7 +117,7 @@ namespace test { /** Register this test class... */ - LAUNCHER (SegmentationDatastructure_test, "unit fixture"); + LAUNCHER (SegmentationIntegration_test, "unit fixture"); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 5928dbb14..e346571dd 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -74105,6 +74105,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ @@ -74211,6 +74212,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + @@ -74262,6 +74274,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + @@ -74275,6 +74291,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + @@ -75104,6 +75125,64 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +

+ Nach aktuellem Stand verweist das JobTicket per Pointer oder Referenz auf ein ExitNode-Objekt, und diese Referenz wird später an den JobFunktor durchgereicht. Irgendwo dahinter verbirgt sich ein Element mit fester Identität (Referenz-Semantik), aber ich weiß noch nicht wo genau. Meine Vorstellung ist, daß das Segment an einer festen Position im Speicher fixiert bleibt, solange noch CalcStreams bzw. Jobs aktiv sind, die die dahinter hängenden Render-Nodes referenzieren — das ist die Grundidee hinter dem »AllocationCluster« +

+ +
+ +
+ + + + + + +

+ ...und zwar, um den Umgang mit der Datenstrutur und das Testing nicht unnötig zu verkomplizieren; ich hoffe, der Umstand, daß ExitNode als MoveOnly markiert ist, sorgt für ausreichend Sicherheit (deshalb dürfte sich die Collection der ExitNodes nicht ohne Weiteres kopieren lassen) +

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

+ Also konkret die Frage: kann ein-und-diesselbe ProcNode mit allen darunter hängenden Strukturen gleichzeitig von mehreren Segmenten verwendet werden? Das klingt zunächst einmal durchaus nach einer plausiblen Möglichkeit, da ja die Render-Nodes selber nichts über ihre nominelle Zeit wissen sollen; demnach wären die Render-Nodes eine persistente Datenstruktur +

+ +
+ +
+ + + + + + +

+ ⟹ Render-Nodes als persistente Datenstruktur behandeln? +

+ +
+
+