Lumiera  0.pre.03
»edit your freedom«
placement-ref-test.cpp
Go to the documentation of this file.
1 /*
2  PlacementRef(Test) - generic reference to a Placement within the Session
3 
4  Copyright (C) Lumiera.org
5  2009, 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"
29 #include "lib/test/test-helper.hpp"
36 #include "lib/time/timevalue.hpp"
37 #include "lib/format-cout.hpp"
38 #include "lib/util.hpp"
39 
40 
41 namespace steam {
42 namespace mobject {
43 namespace session {
44 namespace test {
45 
46  using namespace mobject::test;
47 
48  using util::isSameObject;
49  using LERR_(NOT_IN_SESSION);
50  using LERR_(BOTTOM_PLACEMENTREF);
51 
52  using PSub = TestPlacement<TestSubMO21>;
53  using P_ID = PlacementMO::ID;
54 
55 
56 
57  /***********************************************************************/
69  class PlacementRef_test : public Test
70  {
71 
72  virtual void
73  run (Arg)
74  {
75  PSub testPlacement1(*new TestSubMO21);
76  PSub testPlacement2(*new TestSubMO21);
77 
78  lib::time::Time twoSec(0,2);
79  testPlacement2.chain (twoSec); // define start time of Placement-2 to be at t=2sec
80 
81  // Prepare an (test)Index backing the PlacementRefs
83  PMO& root = index->getRoot();
84 
85  P_ID id1 = index->insert (testPlacement1, root);
86  P_ID tmpID = index->insert (testPlacement2, root);
87  CHECK (2 == index->size());
88 
89  // References to the "live" placements within our test index
90  PMO& p1 = index->find(id1);
91  PMO& p2 = index->find(tmpID);
92 
93  PlacementMO::Id<TestSubMO21> id2 = p2.recastID<TestSubMO21>();
94  CHECK (id2);
95  CHECK (id2 != p1.getID());
96 
97  // create placement refs
98  PlacementRef<TestSubMO21> ref1 (p1);
99  PlacementRef<TestSubMO21> ref2 (id2);
100 
101  PlacementRef<MObject> refX (ref2);
102 
103  CHECK (ref1);
104  CHECK (ref2);
105  CHECK (refX);
106  CHECK (ref1 != ref2);
107  CHECK (ref2 == refX);
108 
109  // indeed a "reference": resolves to the same memory location
110  CHECK (isSameObject (p1, *ref1));
111  CHECK (isSameObject (p2, *ref2));
112  CHECK (isSameObject (p2, *refX));
113 
114  cout << *ref1 << endl;
115  cout << *ref2 << endl;
116  cout << *refX << endl;
117 
118  // PlacementRef mimics placement behaviour
119  ref1->specialAPI();
120  CHECK (2 == ref1.use_count());
121  CHECK (2 == ref2.use_count());
122  ExplicitPlacement exPla = refX.resolve();
123  CHECK (exPla.time == twoSec); // indeed get back the time we set on p2 above
124  CHECK (3 == ref2.use_count()); // exPla shares ownership with p2
125 
126  CHECK (index->contains(ref1)); // ref can stand-in for a placement-ID
127  CHECK (sizeof(id2) == sizeof(ref2)); // (and is actually implemented based on an ID)
128 
129  // assignment on placement refs
130  refX = ref1;
131  CHECK (ref1 != ref2);
132  CHECK (ref1 == refX);
133  CHECK (ref2 != refX);
134 
135  // re-assignment with a new placement
136  refX = p2;
137  CHECK (refX == ref2);
138  CHECK (isSameObject (*refX, p2));
139  refX = p1.getID();
140  CHECK (refX == ref1);
141  CHECK (refX != ref2);
142  CHECK (isSameObject (*refX, p1));
143 
144  LumieraUid luid2 (p2.getID().get());
145  refX = luid2; // assignment works even based on a plain LUID
146  ref2 = ref1;
147  ref1 = refX; // dynamic type check when downcasting
148  CHECK (isSameObject (p1, *ref2));
149  CHECK (isSameObject (p2, *ref1));
150  refX = ref2;
151  ref2 = ref1;
152  ref1 = refX;
153  CHECK (isSameObject (p1, *ref1));
154  CHECK (isSameObject (p1, *refX));
155  CHECK (isSameObject (p2, *ref2));
156  CHECK (ref1 != ref2);
157  CHECK (ref1 == refX);
158  CHECK (ref2 != refX);
159 
160  // resolution is indeed "live", we see changes to the referred placement
161  CHECK (refX.resolve().time == lib::time::Time::MIN);
162  p1.chain = p2.chain; // do a change on the placement within index....
163  CHECK (refX.resolve().time == twoSec); // now we get the time tie we originally set on p2
164 
165  CHECK (p1.getID() != p2.getID()); // but the instance identities are still unaltered
166  CHECK (2 == ref1.use_count());
167  CHECK (3 == ref2.use_count()); // one more because of shared ownership with exPla
168 
169 
170  // actively removing p2 invalidates the other refs to
171  index->remove (ref1);
172  CHECK (!ref1); // checks invalidity without throwing
173  CHECK (!refX);
174  VERIFY_ERROR(NOT_IN_SESSION, *ref1 );
175 
176  // deliberately create an invalid PlacementRef
178  CHECK (!bottom);
179  VERIFY_ERROR(BOTTOM_PLACEMENTREF, *bottom );
180  VERIFY_ERROR(BOTTOM_PLACEMENTREF, bottom->specialAPI() );
181  VERIFY_ERROR(BOTTOM_PLACEMENTREF, bottom.resolve() );
182 
183  //consistency check; then reset PlacementRef index to default
184  CHECK (1 == index->size());
185  CHECK (index->isValid());
186  index.reset();
187  }
188  };
189 
190 
192  LAUNCHER (PlacementRef_test, "unit session");
193 
194 
195 }}}} // namespace steam::mobject::session::test
Reference tag denoting a placement attached to the session.
Automatically use custom string conversion in C++ stream output.
Core abstraction: completely resolved placement of an MObject Within the session model, all media objects are attached with the help of mobject::Placement elements.
Definition: run.hpp:49
Core abstraction: placement of a media object into session context.
Special kind of Placement, where the location of the MObject has been nailed down to a fixed position...
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Steam-Layer implementation namespace root.
Namespace of Session and user visible high-level objects.
Definition: sequence.hpp:74
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:308
Core of the session implementation datastructure.
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
A hierarchy of simple dummy-Media-Objects for easy unit testing.
Implementation level session API: PlacementIndex mock for tests.
A generic reference mechanism for Placements, as added to the current session.
static PPIdx install()
Re-define the implicit PlacementIndex temporarily, e.g.
a family of time value like entities and their relationships.
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:372