Lumiera  0.pre.03
»edit your freedom«
dispatcher-interface-test.cpp
Go to the documentation of this file.
1 /*
2  DispatcherInterface(Test) - document and verify dispatcher for frame job creation
3 
4  Copyright (C) Lumiera.org
5  2012, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
30 #include "steam/play/timings.hpp"
31 #include "lib/time/timevalue.hpp"
32 #include "lib/util.hpp"
33 
34 #include <utility>
35 
36 using test::Test;
37 
38 
39 namespace steam {
40 namespace engine{
41 namespace test {
42 
44  using lib::time::Offset;
45  using lib::time::Time;
46  using play::Timings;
47 
48  using asset::Pipe;
49  using PID = asset::ID<Pipe>;
50  using mobject::ModelPort;
51  using lumiera::error::LUMIERA_ERROR_LOGIC;
52 
53 
54 
55 
56 
57 
58  /***************************************************************/
68  {
69 
70  virtual void
71  run (Arg)
72  {
76  }
77 
78 
83  void
85  {
86  MockDispatcher dispatcher;
87  auto [port,sink] = dispatcher.getDummyConnection(1);
88  CHECK (1 == dispatcher.resolveModelPort (port));
89 
90  // but when using some arbitrary unrelated ModelPort...
91  PID dazedPipe = Pipe::query ("id(dazed)");
92  ModelPort evil = reinterpret_cast<ModelPort&> (dazedPipe);
93  VERIFY_ERROR (LOGIC, dispatcher.resolveModelPort(evil));
94  }
95 
96 
97 
103  void
105  {
106  MockDispatcher dispatcher{MakeRec() // a first active segment
107  .attrib("start", Time{0,10}) // covering the time [10s ... 20s[
108  .attrib("after", Time{0,20})
109  .attrib("mark", 23) // pipeline-Hash used as marker to verify proper access
110  .genNode()
111  ,MakeRec() // add a second Segment
112  .attrib("start", Time{0,20}) // covering the rest of the timeline from 20s on
113  .attrib("mark", 45)
114  .genNode()};
115  size_t portIDX = 1;
116  // Dispatcher-Interface: access JobTicket
117  JobTicket& ticket0 = dispatcher.getJobTicketFor (portIDX, -Time{0,5});
118  JobTicket& ticket1 = dispatcher.getJobTicketFor (portIDX, Time{0,15});
119  JobTicket& ticket2 = dispatcher.getJobTicketFor (portIDX, Time{0,25});
120 
121  CHECK ( ticket0.empty()); // this ticket was drawn from an undefined part of the timeline
122  CHECK (not ticket1.empty()); // while this ticket belongs to the first segment
123  CHECK (not ticket2.empty()); // and this to the second segment
124 
125  Job job0 = ticket0.createJobFor(-Time{0,5});
126  Job job1 = ticket1.createJobFor(Time{0,15});
127  Job job2 = ticket2.createJobFor(Time{0,25});
128 
129  CHECK (MockJob::isNopJob(job0));
130 
131  CHECK (Time(0,15) == job1.parameter.nominalTime);
132  CHECK (23 == job1.parameter.invoKey.part.a); // proof that this job is connected to segment #1
133 
134  CHECK (Time(0,25) == job2.parameter.nominalTime);
135  CHECK (45 == job2.parameter.invoKey.part.a); // and this one to segment #2
136  }
137 
138 
139 
145  void
147  {
148  MockDispatcher dispatcher{MakeRec() // a single segment covering the complete time-axis
149  .attrib("mark", 555) // marker to demonstrate proper connectivity
150  .genNode()};
151 
152  play::Timings timings (FrameRate::PAL);
153  auto [port,sink] = dispatcher.getDummyConnection(1);
154 
155  // Dispatcher-Interface: pipeline builder...
156  auto pipeline = dispatcher.forCalcStream (timings)
157  .timeRange(Time{200,0}, Time{300,0})
158  .pullFrom (port)
159  .feedTo (sink);
160 
161  CHECK (not isnil (pipeline));
162  CHECK (5 == pipeline.currFrameNr()); // 5 * 1/25sec = 200ms
163 
164  Job job = pipeline.buildJob(); // invoke the JobPlanning to build a Job for the first frame
165  CHECK (Time(200,0) == job.parameter.nominalTime);
166  CHECK (555 == job.parameter.invoKey.part.a); // the marker shows that this job is connected properly
167 
168  ++pipeline; // iterate to advance to the next frame
169  CHECK (not isnil (pipeline));
170  CHECK (6 == pipeline.currFrameNr());
171  job = pipeline.buildJob(); // build job for the next frame
172  CHECK (Time(240,0) == job.parameter.nominalTime);
173  CHECK (555 == job.parameter.invoKey.part.a);
174 
175  ++pipeline;
176  CHECK (7 == pipeline.currFrameNr());
177  job = pipeline.buildJob();
178  CHECK (Time(280,0) == job.parameter.nominalTime);
179 
180  ++pipeline; // iterate beyond end point
181  CHECK (isnil (pipeline)); // pipeline exhausted
182  }
183  };
184 
185 
187  LAUNCHER (DispatcherInterface_test, "unit engine");
188 
189 
190 
191 }}} // namespace steam::engine::test
size_t resolveModelPort(ModelPort modelPort) override
translate a generic ModelPort spec into the specific index number applicable at the Timeline referred...
Mock data structures to support implementation testing of render job planning and frame dispatch...
Definition: run.hpp:49
Framerate specified as frames per second.
Definition: timevalue.hpp:664
Generic frame timing specification.
Definition: timings.hpp:95
A mocked frame Dispatcher setup without any backing model.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
play::test::DummyOutputLink getDummyConnection(uint index)
The faked builder/playback setup provides some preconfigured ModelPort and corresponding DataSink han...
Steam-Layer implementation namespace root.
structural asset corresponding to the part of the model forming a processing pipe for generating medi...
Definition: pipe.hpp:79
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:308
Abstract Base Class for all testcases.
Definition: run.hpp:62
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
static PPipe query(string const &properties)
convenience shortcut for retrieving default configured pipes
Definition: pipe.cpp:66
Handle designating a point within the model, where actually output data can be pulled.
Definition: model-port.hpp:104
static bool isNopJob(Job const &)
Offset measures a distance in time.
Definition: timevalue.hpp:367
How to define a timing specification or constraint.
Individual frame rendering task, forwarding to a closure.
Definition: job.h:277
a family of time value like entities and their relationships.
static const FrameRate PAL
predefined constant for PAL framerate
Definition: timevalue.hpp:680
execution plan for pulling a specific exit node.
Definition: job-ticket.hpp:87
Job createJobFor(Time nominalTime)
Core operation: build a concrete render job based on this blueprint.
Definition: job-ticket.cpp:79