Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
session-modify-parts-test.cpp
Go to the documentation of this file.
1/*
2 SessionModifyParts(Test) - adding and removing elements, changing structure
3
4 Copyright (C)
5 2010, 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"
21#include "steam/fixture/fixture.hpp" // TODO only temporarily needed
22//#include "steam/assetmanager.hpp" //////??
23//#include "steam/asset/timeline.hpp"
25#include "lib/format-cout.hpp"
26#include "lib/util-foreach.hpp"
30#include "common/query.hpp"
31
32#include <functional>
33#include <set>
34
35using std::ref;
36using std::placeholders::_1;
38using util::and_all;
39using std::set;
40
41
42namespace steam {
43namespace mobject {
44namespace session {
45namespace test {
46
47// using proc_interface::AssetManager;
48 using proc_interface::PAsset;
49
50// using asset::PTimeline;
51 using asset::PSequence;
52 using asset::Sequence;
53
54 using lumiera::Query;
55
57 typedef PlacementMO::ID PID;
58
59
60
61 /***************************************************************************/
72 class SessionModifyParts_test : public Test
73 {
74 virtual void
75 run (Arg)
76 {
78 CHECK (Session::current.isUp());
79
80 addForks();
81 addObjects();
83
85 }
86
87
88 void
90 {
92 CHECK (sess->isValid());
93
94 PSequence seq = sess->defaults (Query<Sequence> ());
95 CHECK (seq);
96
97#if false
98 RFork fork1 = seq->attachFork();
99 RFork fork2 = seq->attachFork("fork-2");
100 RFork fork21 = seq->attachFork("fork-2.1", fork2);
101 RFork fork22 = seq->attachFork("fork-2.2", "fork-2");
102
103 QueryFocus& focus = sess->focus();
104 CHECK (fork22 == focus.getObject());
105
106 RFork fork3 = seq->attachFork("fork-3", "root");
107 CHECK (fork3 == focus.getObject());
108
109 RFork fork31 = sess->attach(
111
112
113 CHECK (fork31 == focus.getObject());
114 RFork rootFork = seq->rootFork();
115 CHECK (3 == rootFork->subForks.size());
116 CHECK (fork1 == rootFork->subForks[0]);
117 CHECK (fork2 == rootFork->subForks[1]);
118 CHECK (fork3 == rootFork->subForks[2]);
119 CHECK (0 == fork1->subForks.size());
120 CHECK (2 == fork2->subForks.size());
121 CHECK (fork21 == fork2->subForks[0]);
122 CHECK (fork22 == fork2->subForks[1]);
123 CHECK (1 == fork3->subForks.size());
124 CHECK (fork21 == fork3->subForks[0]);
125
126 set<RFork> allForks;
127 allForks.insert(fork1);
128 allForks.insert(fork2);
129 allForks.insert(fork21);
130 allForks.insert(fork22);
131 allForks.insert(fork3);
132 allForks.insert(fork31);
133
134 // verify we indeed covered all forks known to the session....
135 CHECK (and_all (sess->all<Fork>(), contains, ref(allForks), _1 ));
136#endif
137 }
138
139
140 void
142 {
143 PSess sess = Session::current;
144 CHECK (sess->isValid());
145
146#if false
147 QueryFocus& focus = sess->focus();
148 CHECK (focus.getObject().isCompatible<session::Fork>());
149 RClip clip1 = sess->attach (TestClip::create());
150
151 RTrack fork31 = clip.getParent();
152 CHECK (fork31);
153 CHECK ("fork31" == fork31->getNameID());
154
155 CHECK (1 == fork31->clips.size());
156 CHECK (clip1 == fork31->clips[0]);
157
158 RClip clip2 = fork31.attach (TestClip::create());
159 RClip clip3 = fork31.attach (clip1); // creates a clone instance
160
161 CHECK (clip1); CHECK (clip2); CHECK (clip3);
162 CHECK (clip1 != clip2);
163 CHECK (clip1 != clip3);
164 CHECK (clip2 != clip3);
165 CHECK (!isSharedPointee (clip1, clip2));
166 CHECK (!isSharedPointee (clip2, clip3));
167 CHECK ( isSharedPointee (clip1, clip3));
168 CHECK (isEquivalentPlacement (clip1, clip2));
169 CHECK (isEquivalentPlacement (clip2, clip3));
170 CHECK (isEquivalentPlacement (clip1, clip3));
171
172 RTrack fork2 = sess->sequences[0]
173 ->rootTrack()
174 ->subTracks[1];
175 RClip clip4 = fork2.attach (TestClip::create());
176
177 // now verify structure built up thus far
178 CHECK (focus.getObject() == fork2); // focus follows point-of-mutation
179 CHECK (focus.contains (clip4));
180 CHECK (!focus.contains (clip1));
181 CHECK (!focus.contains (clip2));
182 CHECK (!focus.contains (clip3));
183
184 focus.attach (fork31);
185 CHECK (focus.getObject() == fork31);
186 CHECK (focus.contains (clip1));
187 CHECK (focus.contains (clip2));
188 CHECK (focus.contains (clip3));
189 CHECK (!focus.contains (clip4));
190
191 focus.reset();
192 CHECK (focus.getObject() == sess->getRoot());
193 CHECK (focus.contains (clip1)); // containment test includes sub-scopes
194 CHECK (focus.contains (clip2));
195 CHECK (focus.contains (clip3));
196 CHECK (focus.contains (clip4));
197 CHECK (!focus.hasChild (clip1)); // but they are indeed nested more deeply
198 CHECK (!focus.hasChild (clip2));
199 CHECK (!focus.hasChild (clip3));
200 CHECK (!focus.hasChild (clip4));
201
202 focus.attach (sess->sequences[0]->rootTrack()->subTracks[2]->subTracks[0]); // train wreck. Don't try it at home!
203 CHECK (focus.getObject() == fork31); // (this test is an exception, as we know the structure precisely
204 // production code should always discover one level a time)
205 CHECK ( focus.hasChild (clip1));
206 CHECK ( focus.hasChild (clip2));
207 CHECK ( focus.hasChild (clip3));
208 CHECK (!focus.hasChild (clip4)); // ...because this one is on fork2, not fork31
209#endif
210 }
211
212
213 void
215 {
216#if false
217 PSess sess = Session::current;
218 CHECK (sess->isValid());
219
220 RTrack fork31 = sess->sequences[0]->rootTrack()->subTracks[2]->subTracks[0];
221 CHECK (fork31);
222 CHECK (3 == fork31->clips.size());
223 RClip clip2 = fork31->clips[1];
224
225 QueryFocus& focus = sess->focus();
226 focus.reset(); // navigate to root
227
228 CHECK (focus.contains (clip2));
229 CHECK (clip2);
230 clip2.purge();
231 CHECK (!clip2);
232 CHECK (!focus.contains (clip2));
233
234 CHECK (2 == fork31->clips.size());
235 CHECK (clip2 != fork31->clips[1]);
236
237 CHECK (focus.getObject() == fork31); // focus follows point-of-mutation
238
239 // Using the query-focus to explore the contents of this current object (fork31)
240 ScopeQuery<Clip>::iterator discoverClips = focus.explore<Clip>();
241 CHECK (discoverClips);
242 RClip clip1 = *discoverClips;
243 ++discoverClips;
244 RClip clip3 = *discoverClips;
245 ++discoverClips;
246 CHECK (!discoverClips);
247
248 CHECK (fork31->clips[0] == clip1);
249 CHECK (fork31->clips[1] == clip3);
250 /* please note: the clips aren't discovered in any defined order (hashtable!)
251 * especially, the order doesn't match the order of addition!
252 * thus, what's called clip1 here may or may not be
253 * what we called clip1 in addObjects()
254 */
255
256 RTrack fork3 = fork31.getParent();
257
258 focus.reset(); // back to root
259 CHECK (focus.contains (clip1));
260 CHECK (focus.contains (clip3));
261 CHECK (focus.contains (fork3));
262 CHECK (focus.contains (fork31));
263 CHECK (clip1);
264 CHECK (clip3);
265 CHECK (fork3);
266 CHECK (fork31);
267
268 sess->purge (fork31);
269
270 CHECK (focus.getObject() == fork3);
271 focus.reset();
272 CHECK ( focus.contains (fork3));
273
274 CHECK (!focus.contains (clip1));
275 CHECK (!focus.contains (clip3));
276 CHECK (!focus.contains (fork31));
277 CHECK (!clip1);
278 CHECK (!clip3);
279 CHECK (!fork31);
280 CHECK (fork3);
281
282 fork3.purge();
283 CHECK (!fork3);
284 PSequence aSequence = sess->sequences[0];
285 CHECK (focus.getObject() == aSequence->rootTrack());
286 CHECK (2 == aSequece->rootTrack()->subTracks.size());
287
288 CHECK ( contains (sess->sequences, aSequence));
289 aSequence->rootFork().purge(); // automatically kills the sequence as well (sequence == facade to the fork root)
290 CHECK (!contains (sess->sequences, aSequence));
291 CHECK (0 == sess->sequences.size());
292 CHECK (0 == sess->timelines.size()); // killing the sequence also cascaded to the timeline and binding
293 CHECK (!sess->isValid()); // thus effectively the session is now invalid (no timeline)
294
295 CHECK (focus.getObject() == sess->getRoot());
296
297 PID currRoot = sess->getRoot.getPlacement().getID();
298 sess->getRoot().purge(); // purging the root scope effectively resets the session to defaults
299 CHECK (currRoot == sess->getRoot.getPlacement.getID);
300 // but the root element itself is retained
301 CHECK (sess->isValid());
302 CHECK (1 == sess->timelines.size());
303 CHECK (1 == sess->sequences.size());
304 CHECK (aSequence != sess->sequences[0]);
305 CHECK (aSequence.use_count() == 1); // we're holding the last remaining reference
306#endif
307 }
308
309
310 void
312 {
313 TODO ("verify the commands issued by this test");
314 }
315
316 };
317
318
321
322
323
324}}}} // namespace steam::mobject::session::test
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition p.hpp:77
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition query.hpp:254
TODO type comment.
Definition sequence.hpp:86
static StructFactory retrieve
storage for the static StructFactory instance
Definition struct.hpp:107
An active (smart-ptr like) external reference to a specifically placed MObject "instance" within the ...
TimelineAccess timelines
collection of timelines (top level)
Definition session.hpp:124
DefaultsAccess defaults
manages default configured objects
Definition session.hpp:122
virtual bool isValid()=0
SequenceAccess sequences
collection of sequences
Definition session.hpp:125
static session::SessManager & current
access point to the current Session
Definition session.hpp:120
virtual MObjectRef attach(PMO const &placement)=0
virtual MObjectRef getRoot()=0
A user visible/editable Clip is a reference to a contiguous sequence of media data loaded as Asset in...
A Fork serves as grouping device within the Session.
Definition fork.hpp:95
Current focus location to use as point-of reference for contents and location discovery queries.
ScopeQuery< MO >::iterator explore() const
discover any matching object contained as immediate Child within current focus.
QueryFocus & reset()
discard any state and navigate current focus path to model root
creation, access and Session lifecycle Interface.
Definition session.hpp:154
virtual void reset()=0
reset all session config and start with a pristine default session.
static Placement< Clip > create()
Definition testclip.hpp:70
Backbone data structure of the low-level render node model The fixture defines the boundary between t...
Automatically use custom string conversion in C++ stream output.
External MObject/Placement reference.
Namespace of Session and user visible high-level objects.
Definition sequence.hpp:65
MORef< Fork > RFork
Definition sequence.hpp:68
bool isSharedPointee(MORef< MOX > const &ref1, MORef< MOY > const &ref2)
check if the two references actually share ownership on the same underlying MObject (as opposed to re...
bool isEquivalentPlacement(MORef< MOX > const &ref1, MORef< MOY > const &ref2)
check if the two references actually denote an equivalent placement
Steam-Layer implementation namespace root.
Test runner and basic definitions for tests.
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee's memory identities.
Definition util.hpp:421
bool and_all(IT i, IT end, FUN predicate)
All quantification: check if all elements of a collection satisfy the given predicate.
Core abstraction: placement of a media object into session context.
Basic and generic representation of an internal query.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
Structural building block of the session: a sequence of clips.
Primary Interface to the current Session.
A stub implementation of the Clip interface for unit testing.
Perform operations "for each element" of a collection.