Lumiera  0.pre.03
»edit your freedom«
timeline-sequence-handling-test.cpp
Go to the documentation of this file.
1 /*
2  TimelineSequenceHandling(Test) - managing the top level session facade objects
3 
4  Copyright (C)
5  2008, 2011, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
19 #include "lib/test/run.hpp"
23 //#include "steam/mobject/session/fixture.hpp" // TODO only temporarily needed
24 #include "steam/assetmanager.hpp"
25 #include "steam/asset/timeline.hpp"
26 #include "steam/asset/sequence.hpp"
27 #include "steam/asset/pipe.hpp"
28 #include "common/query.hpp"
29 #include "lib/util.hpp"
30 
31 
32 using util::isSameObject;
33 using util::contains;
34 
35 
36 namespace steam {
37 namespace mobject {
38 namespace session {
39 namespace test {
40 
42  using proc_interface::PAsset;
43 
44  using asset::Timeline;
45  using asset::PTimeline;
46  using asset::Sequence;
47  using asset::PSequence;
48  using asset::Pipe;
49 
50  using lumiera::Query;
51 
52 
53  /****************************************************************************/
70  class TimelineSequenceHandling_test : public Test
71  {
72  virtual void
73  run (Arg)
74  {
76  CHECK (Session::current.isUp());
77 
78  verify_retrieval();
79  verify_creation();
80  verify_removalTimeline();
81  verify_removalBinding();
82  verify_removalSequence();
83 
84  indirect_SequenceHandling();
85  }
86 
87 
88  void
89  verify_retrieval()
90  {
91  PSess sess = Session::current;
92  CHECK (sess->isValid());
93  CHECK (0 < sess->timelines.size());
94 
95  PTimeline defaultTimeline = sess->defaults (Query<Timeline> ());
96 #if false
97  Query<Timeline> query1 = "id("+defaultTimeline->getNameID()+").";
98 
99  PTimeline queriedTimeline = asset::Struct::retrieve (query1);
100  CHECK (queriedTimeline);
101  CHECK (queriedTimeline == defaultTimeline); // retrieved the existing timeline asset again
102  CHECK (queriedTimeline == sess->timelines[0]);
103 
104  Query<Sequence> query2 = "id("+defaultTimeline->getSequence()->getNameID()+").";
105  PSequence queriedSequence = asset::Struct::retrieve (query2);
106  CHECK (queriedSequence);
107  CHECK (queriedSequence == sess->sequences[0]);
108  CHECK (queriedSequence == sess->timelines[0]->getSequence());
109  CHECK (queriedSequence == defaultTimeline->getSequence());
110 #endif
111  }
112 
113 
114  void
115  verify_creation()
116  {
117  PSess sess = Session::current;
118  CHECK (sess->isValid());
119 
120  uint num_timelines = sess->timelines.size();
121  CHECK (0 < num_timelines);
122 
123 #if false
124  Query<Timeline> special = "id(aSillyName), sequence("
125  + sess->sequences[0]->getNameID()
126  + "), pipe(ambiance).";
127 
128  PTimeline specialTimeline (asset::Struct::retrieve (special));
129  CHECK (specialTimeline);
130  CHECK (num_timelines + 1 == sess->timelines.size());
131  CHECK (specialTimeline == session->timelines[num_timelines]); // new one got appended at the end
132 
133  // verify the properties
134  CHECK (specialTimeline->getSequence() == sess->sequences[0]); // the already existing sequence got bound into that timeline too
135  CHECK (contains (specialTimeline->pipes, Pipe::query("pipe(ambiance)")));
136 
137  CHECK (specialTimeline.use_count() == 3); // we, the AssetManager and the session
138 #endif
139  }
140 
141 
142  void
143  verify_removalTimeline()
144  {
145  PSess sess (Session::current);
147 
148  CHECK (sess->isValid());
149  uint num_timelines = sess->timelines.size();
150  CHECK (2 <= num_timelines);
151 
152  PTimeline specialTimeline = sess->timelines[num_timelines-1];
153 #if false
154  CHECK ("aSillyName" == specialTimeline->getNameID());
155 
156  RBinding binding = specialTimeline->getBinding();
157  CHECK (binding);
158 
159  PSequence theSeq = binding->getSequence();
160  CHECK (theSeq == sess->sequences[0]);
161  CHECK (theSeq == specialTimeline->getSequence());
162  CHECK (assetM.known (theSeq->getID()));
163 
164  // cause removal of the timeline
165  assetM.remove (specialTimeline->getID());
166 
167  CHECK (!assetM.known (specialTimeline->getID()));
168  CHECK (1 == specialTimeline.use_count()); // we hold the only remaining ref
169  CHECK ( assetM.known (theSeq->getID())); // bound sequence isn't affected
170  CHECK (theSeq == sess->sequences[0]);
171 
172  CHECK (num_timelines - 1 == sess->timelines.size());
173  CHECK (!binding); // got purged from the model
174 #endif
175  }
176 
177 
178  void
179  verify_removalBinding()
180  {
181  PSess sess (Session::current);
183 
184  CHECK (sess->isValid());
185  uint num_timelines = sess->timelines.size();
186  CHECK (0 < num_timelines);
187 
188  // create a new Timeline to play with, using the default sequence...
189 #if false
190  PTimeline aTimeline (asset::Struct::retrieve (Query<Timeline> ("sequence("+
191  + sess->sequences[0]->getNameID()
192  + ").")));
193  CHECK (num_timelines + 1 == sess->timelines.size());
194  RBinding binding = aTimeline->getBinding();
195  CHECK (binding);
196 
197  PSequence theSeq = binding->getSequence();
198  CHECK (theSeq == sess->sequences[0]);
199  CHECK (theSeq == aTimeline->getSequence());
200  CHECK (assetM.known (aTimeline->getID()));
201  CHECK (assetM.known (theSeq->getID()));
202 
203  // indirectly cause removal of the timeline by dropping the binding
204  sess->remove(binding);
205  CHECK (!binding);
206 
207  CHECK (!assetM.known (aTimeline->getID()));
208  CHECK (1 == aTimeline.use_count());
209  CHECK ( assetM.known (theSeq->getID()));
210 
211  CHECK (num_timelines == sess->timelines.size());
212  CHECK (!contains (sess->timelines, aTimeline));
213  CHECK ( contains (sess->sequences, theSeq)); // unaffected
214 #endif
215  }
216 
217 
218  void
219  verify_removalSequence()
220  {
221  PSess sess (Session::current);
223 
224  CHECK (sess->isValid());
225  uint num_timelines = sess->timelines.size();
226  uint num_sequences = sess->sequences.size();
227 
228  // create a new timeline, bound to a new sequence...
229  PTimeline aTimeline (asset::Struct::retrieve (Query<Timeline> ()));
230 #if false
231  PSequence aSequence (aTimeline->getSequence());
232  CHECK (num_timelines + 1 == sess->timelines.size());
233  CHECK (num_sequences + 1 == sess->sequences.size());
234 
235  RBinding binding = aTimeline->getBinding();
236  RTrack rootTrack = aSequence->getTracks();
237  CHECK (rootTrack);
238  CHECK (binding);
239 
240  CHECK (aSequence == binding->getSequence());
241  CHECK (assetM.known (aTimeline->getID()));
242  CHECK (assetM.known (aSequence->getID()));
243 
244  // purging the sequence cascades to all linked entities
245  assetM.remove (aSequence->getID());
246 
247  CHECK (!assetM.known (aTimeline->getID()));
248  CHECK (!assetM.known (aSequence->getID()));
249  CHECK (!rootTrack);
250  CHECK (!binding);
251 
252  CHECK (num_timelines == sess->timelines.size());
253  CHECK (num_sequences == sess->sequences.size());
254  CHECK (!contains (sess->timelines, aTimeline));
255  CHECK (!contains (sess->sequences, aSequence));
256 
257  CHECK (1 == aTimeline.use_count());
258  CHECK (1 == aSequence.use_count());
259 #endif
260  }
261 
262 
263  void
264  indirect_SequenceHandling()
265  {
266  PSess sess (Session::current);
268 
269  CHECK (sess->isValid());
270  uint num_sequences = sess->sequences.size();
271 
272 #if false
273  RFork someFork = sess->sequences[0]->getForks();
274 
275  // indirectly cause a new sequence to come to life...
276  RFork newFork = sess->getRoot().attach (someFork); // attach new Placement<Fork> to root scope
277  CHECK (newFork != someFork); // it's a new placement
278 
279  CHECK (num_sequences + 1 == sess->sequences.size()); // this root-attachment created a new sequence by sideeffect
280  PSequence aSequence = sess->sequences[num_sequences];
281  CHECK (newFork == aSequence->getForks());
282  CHECK (newFork);
283  CHECK (someFork);
284  CHECK (assetM.known (aSequence->getID()));
285 
286  //TODO maybe even bind it into a new timeline. Then verify this new timeline gets removed alongside with the sequence below!
287 
288  // just moving the new fork away from root position
289  // causes the sequence to disappear
290  newFork.getPlacement().chain (someFork, Time(20));
291 
292  //TODO 3/2010 not finally decided *if* we want this behaviour
293  //TODO how to verify the changed placement??
294 
295  CHECK (!assetM.known (aSequence->getID()));
296  CHECK (num_sequences == sess->sequences.size());
297  CHECK (!contains (sess->sequences, aSequence));
298 
299  CHECK (someFork);
300  CHECK (newFork);
301 #endif
302  }
303  };
304 
305 
307  LAUNCHER (TimelineSequenceHandling_test, "unit session");
308 
309 
310 
311 }}}} // namespace steam::mobject::session::test
Steam-Layer Interface: Asset Lookup and Organisation.
A "processing pipe" represented as Asset.
An active (smart-ptr like) external reference to a specifically placed MObject "instance" within the ...
Definition: mobject-ref.hpp:85
TODO type comment.
Definition: sequence.hpp:83
virtual void reset()=0
reset all session config and start with a pristine default session.
Basic and generic representation of an internal query.
Definition: run.hpp:40
MORef< MOX > attach(Placement< MOX > const &newPlacement)
attach a child element to the model
void remove(IDA id)
remove the given asset from the internal DB.
Facade for the Asset subsystem.
static session::SessManager & current
access point to the current Session
Definition: session.hpp:120
Steam-Layer implementation namespace root.
DefaultsAccess defaults
manages default configured objects
Definition: session.hpp:122
Namespace of Session and user visible high-level objects.
Definition: sequence.hpp:65
structural asset corresponding to the part of the model forming a processing pipe for generating medi...
Definition: pipe.hpp:70
static lib::Depend< AssetManager > instance
get at the system-wide asset manager instance.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:299
static StructFactory retrieve
storage for the static StructFactory instance
Definition: struct.hpp:107
Structural building block of the session: a sequence of clips.
External MObject/Placement reference.
MObject in session to represent the top-level binding of a sequence.
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
creation, access and Session lifecycle Interface.
Definition: session.hpp:152
SequenceAccess sequences
collection of sequences
Definition: session.hpp:125
static PPipe query(string const &properties)
convenience shortcut for retrieving default configured pipes
Definition: pipe.cpp:57
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition: trait.hpp:71
Primary Interface to the current Session.
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition: query.hpp:270
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
Definition: util.hpp:255
Top level structural element within the session.
TimelineAccess timelines
collection of timelines (top level)
Definition: session.hpp:124
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee&#39;s memory identities. ...
Definition: util.hpp:421