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) Lumiera.org
5  2008, 2011, 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"
32 //#include "steam/mobject/session/fixture.hpp" // TODO only temporarily needed
33 #include "steam/assetmanager.hpp"
34 #include "steam/asset/timeline.hpp"
35 #include "steam/asset/sequence.hpp"
36 #include "steam/asset/pipe.hpp"
37 #include "common/query.hpp"
38 #include "lib/util.hpp"
39 
40 
41 using util::isSameObject;
42 using util::contains;
43 
44 
45 namespace steam {
46 namespace mobject {
47 namespace session {
48 namespace test {
49 
51  using proc_interface::PAsset;
52 
53  using asset::Timeline;
54  using asset::PTimeline;
55  using asset::Sequence;
56  using asset::PSequence;
57  using asset::Pipe;
58 
59  using lumiera::Query;
60 
61 
62  /****************************************************************************/
79  class TimelineSequenceHandling_test : public Test
80  {
81  virtual void
82  run (Arg)
83  {
85  CHECK (Session::current.isUp());
86 
87  verify_retrieval();
88  verify_creation();
89  verify_removalTimeline();
90  verify_removalBinding();
91  verify_removalSequence();
92 
93  indirect_SequenceHandling();
94  }
95 
96 
97  void
98  verify_retrieval()
99  {
100  PSess sess = Session::current;
101  CHECK (sess->isValid());
102  CHECK (0 < sess->timelines.size());
103 
104  PTimeline defaultTimeline = sess->defaults (Query<Timeline> ());
105 #if false
106  Query<Timeline> query1 = "id("+defaultTimeline->getNameID()+").";
107 
108  PTimeline queriedTimeline = asset::Struct::retrieve (query1);
109  CHECK (queriedTimeline);
110  CHECK (queriedTimeline == defaultTimeline); // retrieved the existing timeline asset again
111  CHECK (queriedTimeline == sess->timelines[0]);
112 
113  Query<Sequence> query2 = "id("+defaultTimeline->getSequence()->getNameID()+").";
114  PSequence queriedSequence = asset::Struct::retrieve (query2);
115  CHECK (queriedSequence);
116  CHECK (queriedSequence == sess->sequences[0]);
117  CHECK (queriedSequence == sess->timelines[0]->getSequence());
118  CHECK (queriedSequence == defaultTimeline->getSequence());
119 #endif
120  }
121 
122 
123  void
124  verify_creation()
125  {
126  PSess sess = Session::current;
127  CHECK (sess->isValid());
128 
129  uint num_timelines = sess->timelines.size();
130  CHECK (0 < num_timelines);
131 
132 #if false
133  Query<Timeline> special = "id(aSillyName), sequence("
134  + sess->sequences[0]->getNameID()
135  + "), pipe(ambiance).";
136 
137  PTimeline specialTimeline (asset::Struct::retrieve (special));
138  CHECK (specialTimeline);
139  CHECK (num_timelines + 1 == sess->timelines.size());
140  CHECK (specialTimeline == session->timelines[num_timelines]); // new one got appended at the end
141 
142  // verify the properties
143  CHECK (specialTimeline->getSequence() == sess->sequences[0]); // the already existing sequence got bound into that timeline too
144  CHECK (contains (specialTimeline->pipes, Pipe::query("pipe(ambiance)")));
145 
146  CHECK (specialTimeline.use_count() == 3); // we, the AssetManager and the session
147 #endif
148  }
149 
150 
151  void
152  verify_removalTimeline()
153  {
154  PSess sess (Session::current);
156 
157  CHECK (sess->isValid());
158  uint num_timelines = sess->timelines.size();
159  CHECK (2 <= num_timelines);
160 
161  PTimeline specialTimeline = sess->timelines[num_timelines-1];
162 #if false
163  CHECK ("aSillyName" == specialTimeline->getNameID());
164 
165  RBinding binding = specialTimeline->getBinding();
166  CHECK (binding);
167 
168  PSequence theSeq = binding->getSequence();
169  CHECK (theSeq == sess->sequences[0]);
170  CHECK (theSeq == specialTimeline->getSequence());
171  CHECK (assetM.known (theSeq->getID()));
172 
173  // cause removal of the timeline
174  assetM.remove (specialTimeline->getID());
175 
176  CHECK (!assetM.known (specialTimeline->getID()));
177  CHECK (1 == specialTimeline.use_count()); // we hold the only remaining ref
178  CHECK ( assetM.known (theSeq->getID())); // bound sequence isn't affected
179  CHECK (theSeq == sess->sequences[0]);
180 
181  CHECK (num_timelines - 1 == sess->timelines.size());
182  CHECK (!binding); // got purged from the model
183 #endif
184  }
185 
186 
187  void
188  verify_removalBinding()
189  {
190  PSess sess (Session::current);
192 
193  CHECK (sess->isValid());
194  uint num_timelines = sess->timelines.size();
195  CHECK (0 < num_timelines);
196 
197  // create a new Timeline to play with, using the default sequence...
198 #if false
199  PTimeline aTimeline (asset::Struct::retrieve (Query<Timeline> ("sequence("+
200  + sess->sequences[0]->getNameID()
201  + ").")));
202  CHECK (num_timelines + 1 == sess->timelines.size());
203  RBinding binding = aTimeline->getBinding();
204  CHECK (binding);
205 
206  PSequence theSeq = binding->getSequence();
207  CHECK (theSeq == sess->sequences[0]);
208  CHECK (theSeq == aTimeline->getSequence());
209  CHECK (assetM.known (aTimeline->getID()));
210  CHECK (assetM.known (theSeq->getID()));
211 
212  // indirectly cause removal of the timeline by dropping the binding
213  sess->remove(binding);
214  CHECK (!binding);
215 
216  CHECK (!assetM.known (aTimeline->getID()));
217  CHECK (1 == aTimeline.use_count());
218  CHECK ( assetM.known (theSeq->getID()));
219 
220  CHECK (num_timelines == sess->timelines.size());
221  CHECK (!contains (sess->timelines, aTimeline));
222  CHECK ( contains (sess->sequences, theSeq)); // unaffected
223 #endif
224  }
225 
226 
227  void
228  verify_removalSequence()
229  {
230  PSess sess (Session::current);
232 
233  CHECK (sess->isValid());
234  uint num_timelines = sess->timelines.size();
235  uint num_sequences = sess->sequences.size();
236 
237  // create a new timeline, bound to a new sequence...
238  PTimeline aTimeline (asset::Struct::retrieve (Query<Timeline> ()));
239 #if false
240  PSequence aSequence (aTimeline->getSequence());
241  CHECK (num_timelines + 1 == sess->timelines.size());
242  CHECK (num_sequences + 1 == sess->sequences.size());
243 
244  RBinding binding = aTimeline->getBinding();
245  RTrack rootTrack = aSequence->getTracks();
246  CHECK (rootTrack);
247  CHECK (binding);
248 
249  CHECK (aSequence == binding->getSequence());
250  CHECK (assetM.known (aTimeline->getID()));
251  CHECK (assetM.known (aSequence->getID()));
252 
253  // purging the sequence cascades to all linked entities
254  assetM.remove (aSequence->getID());
255 
256  CHECK (!assetM.known (aTimeline->getID()));
257  CHECK (!assetM.known (aSequence->getID()));
258  CHECK (!rootTrack);
259  CHECK (!binding);
260 
261  CHECK (num_timelines == sess->timelines.size());
262  CHECK (num_sequences == sess->sequences.size());
263  CHECK (!contains (sess->timelines, aTimeline));
264  CHECK (!contains (sess->sequences, aSequence));
265 
266  CHECK (1 == aTimeline.use_count());
267  CHECK (1 == aSequence.use_count());
268 #endif
269  }
270 
271 
272  void
273  indirect_SequenceHandling()
274  {
275  PSess sess (Session::current);
277 
278  CHECK (sess->isValid());
279  uint num_sequences = sess->sequences.size();
280 
281 #if false
282  RFork someFork = sess->sequences[0]->getForks();
283 
284  // indirectly cause a new sequence to come to life...
285  RFork newFork = sess->getRoot().attach (someFork); // attach new Placement<Fork> to root scope
286  CHECK (newFork != someFork); // it's a new placement
287 
288  CHECK (num_sequences + 1 == sess->sequences.size()); // this root-attachment created a new sequence by sideeffect
289  PSequence aSequence = sess->sequences[num_sequences];
290  CHECK (newFork == aSequence->getForks());
291  CHECK (newFork);
292  CHECK (someFork);
293  CHECK (assetM.known (aSequence->getID()));
294 
295  //TODO maybe even bind it into a new timeline. Then verify this new timeline gets removed alongside with the sequence below!
296 
297  // just moving the new fork away from root position
298  // causes the sequence to disappear
299  newFork.getPlacement().chain (someFork, Time(20));
300 
301  //TODO 3/2010 not finally decided *if* we want this behaviour
302  //TODO how to verify the changed placement??
303 
304  CHECK (!assetM.known (aSequence->getID()));
305  CHECK (num_sequences == sess->sequences.size());
306  CHECK (!contains (sess->sequences, aSequence));
307 
308  CHECK (someFork);
309  CHECK (newFork);
310 #endif
311  }
312  };
313 
314 
316  LAUNCHER (TimelineSequenceHandling_test, "unit session");
317 
318 
319 
320 }}}} // 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:94
TODO type comment.
Definition: sequence.hpp:92
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:49
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:129
Steam-Layer implementation namespace root.
DefaultsAccess defaults
manages default configured objects
Definition: session.hpp:131
Namespace of Session and user visible high-level objects.
Definition: sequence.hpp:74
structural asset corresponding to the part of the model forming a processing pipe for generating medi...
Definition: pipe.hpp:79
static lib::Depend< AssetManager > instance
get at the system-wide asset manager instance.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:308
static StructFactory retrieve
storage for the static StructFactory instance
Definition: struct.hpp:116
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.
Simple 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:161
SequenceAccess sequences
collection of sequences
Definition: session.hpp:134
static PPipe query(string const &properties)
convenience shortcut for retrieving default configured pipes
Definition: pipe.cpp:66
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition: trait.hpp:80
Primary Interface to the current Session.
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition: query.hpp:279
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:133
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:372