Lumiera  0.pre.03
»edit your freedom«
mobject-ref.hpp
Go to the documentation of this file.
1 /*
2  MOBJECT-REF.hpp - active external reference to an MObject 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 
23 
59 #ifndef MOBJECT_MOBJECT_REF_H
60 #define MOBJECT_MOBJECT_REF_H
61 
62 #include "lib/handle.hpp"
66 
67 #include <string>
68 
69 
71 
72 namespace steam {
73 namespace mobject {
74 
75  namespace error = lumiera::error;
76 
77 
78 
79  class MObject;
80 
81 
82  LUMIERA_ERROR_DECLARE (BOTTOM_MOBJECTREF);
83 
92  template<class MO =MObject>
93  class MORef
94  : public lib::Handle<MO>
95  {
96  typedef lib::Handle<MO> _Handle;
97  typedef PlacementMO::Id<MO> _Id;
98 
99 
100  PlacementRef<MO> pRef_;
101  using _Handle::smPtr_;
102 
103 
104 
105  public:
106 
107  MO*
108  operator-> () const
109  {
110  if (!smPtr_)
111  throw error::State("Lifecycle error: MObject ref not activated"
112  , LERR_(BOTTOM_MOBJECTREF));
113 
114  ENSURE (INSTANCEOF (MO, smPtr_.get()));
115  return smPtr_.operator-> ();
116  }
117 
118 
119  Placement<MO>& getPlacement() const
120  {
121  if (!isValid())
122  throw error::State("Accessing inactive MObject ref"
123  , LERR_(BOTTOM_MOBJECTREF));
124 
125  ENSURE (INSTANCEOF (MO, smPtr_.get()));
126  return *pRef_;
127  }
128 
129 
132  PlacementRef<MO> const&
133  getRef() const
134  {
135  return pRef_;
136  }
137 
142  operator _Id const&() const
143  {
144  return pRef_;
145  }
146 
147 
148 
154  {
155  return pRef_.resolve().time;
156  }
157 
158 
164  template<class MOX>
165  MORef<MOX>
166  attach (Placement<MOX> const& newPlacement)
167  {
168  if (!isValid())
169  throw error::State("Attempt to attach a child to an inactive MObject ref"
170  , LERR_(BOTTOM_MOBJECTREF));
171  MORef<MOX> newInstance;
172  PlacementMO::ID thisScope = pRef_;
173  return newInstance.activate (
174  session::SessionServiceMutate::attach_toModel (newPlacement, thisScope));
175  }
176 
177 
182  void
183  purge ()
184  {
185  if (isValid())
187 
188  ENSURE (!isValid());
189  }
190 
191 
192 
193  /* === Lifecycle === */
194 
202  MORef&
203  activate (Placement<MO> const& placement)
204  {
205  ASSERT (placement.isValid());
206  pRef_ = placement; // STRONG exception safe
207  placement.extendOwnershipTo(smPtr_); // never throws
208  return *this;
209  }
210 
221  template<typename REF>
222  MORef&
223  activate (REF const& pRefID)
224  {
225  PlacementRef<MO> newRef (pRefID);
226 
227  if (isValid() && pRef_ == newRef )
228  return *this; // self assignment detected
229  else
230  return activate (*newRef); // STRONG exception safe
231  }
232 
239  MORef&
240  activate (MORef const& oRef)
241  {
242  return activate (oRef.getPlacement());
243  }
244 
245  template<typename MOX>
246  MORef&
247  activate (MORef<MOX> const& oRef)
248  {
249  return activate (oRef.getPlacement().getID());
250  }
251 
259  template<typename MOX>
260  MORef&
261  operator= (MORef<MOX> const& oRef)
262  {
263  return activate (oRef);
264  }
265 
266 
267 
268 
269  /* == diagnostics == */
270  bool
271  isValid() const
272  {
273  return _Handle::isValid()
274  && pRef_.isValid();
275  }
276 
277  size_t
278  use_count() const
279  {
280  return isValid()? pRef_.use_count() : 0;
281  }
282 
283  template<class MOX>
284  bool
285  isCompatible() const
286  {
287  return pRef_
288  && (*pRef_).template isCompatible<MOX>();
289  }
290 
291  operator string() const
292  {
293  return isValid()? string(getPlacement())
294  : "MRef-NIL";
295  }
296 
297 
298 
299 
300  /* == equality comparisons == */
301 
302  template<class MOX>
303  bool
304  operator== (MORef<MOX> const& oRef) const
305  {
306  return isValid()
307  && oRef == this->pRef_;
308  }
309 
310  template<class MOX>
311  bool
312  operator!= (MORef<MOX> const& oRef) const
313  {
314  return not isValid()
315  or oRef != this->pRef_;
316  }
317 
318  template<class MOX>
319  friend bool
320  operator== (MORef const& oRef, PlacementRef<MOX> const& pRef)
321  {
322  return oRef.isValid()
323  and oRef.pRef_ == pRef;
324  }
325 
326  template<class MOX>
327  friend bool
328  operator!= (MORef const& oRef, PlacementRef<MOX> const& pRef)
329  {
330  return not oRef.isValid()
331  or oRef.pRef_ != pRef;
332  }
333 
334  template<class MOX>
335  friend bool
336  operator== (PlacementRef<MOX> const& pRef, MORef const& oRef)
337  {
338  return oRef.isValid()
339  and pRef == oRef.pRef_;
340  }
341 
342  template<class MOX>
343  friend bool
344  operator!= (PlacementRef<MOX> const& pRef, MORef const& oRef)
345  {
346  return not oRef.isValid()
347  or pRef != oRef.pRef_;
348  }
349 
350  bool
351  operator== (PlacementMO::ID const& pID) const
352  {
353  return isValid()
354  and PlacementMO::ID (pRef_) == pID;
355  }
356 
357  bool
358  operator!= (PlacementMO::ID const& pID) const
359  {
360  return not isValid()
361  or PlacementMO::ID (pRef_) != pID;
362  }
363 
364  };
365 
366 
367  typedef MORef<MObject> MObjectRef;
368 
369 
370  /* === convenience shortcuts === */
371 
376  template<class MOX, class MOY>
377  inline bool
378  isSharedPointee (MORef<MOX> const& ref1, MORef<MOY> const& ref2)
379  {
380  return ref1.isValid() && ref2.isValid()
381  && isSharedPointee (ref1.getPlacement(), ref2.getPlacement());
382  }
383 
385  template<class MOX, class MOY>
386  inline bool
387  isEquivalentPlacement (MORef<MOX> const& ref1, MORef<MOY> const& ref2)
388  {
389  return ref1.isValid() && ref2.isValid()
390  && isSameDef (ref1.getPlacement(), ref2.getPlacement());
391  }
392 
393 
394 }} // namespace steam::mobject
395 #endif
LUMIERA_ERROR_DECLARE(BUILDER_LIFECYCLE)
Builder activated while in non operational state.
A refcounting Handle to an MObject of type MO, used to constrain or explicitly specify the location w...
Definition: trait.hpp:89
Generic opaque reference counting handle, for accessing a service and managing its lifecycle...
Definition: handle.hpp:72
An active (smart-ptr like) external reference to a specifically placed MObject "instance" within the ...
Definition: mobject-ref.hpp:93
void purge()
detach this object instance from model, including all child elements.
Core abstraction: placement of a media object into session context.
#define INSTANCEOF(CLASS, EXPR)
shortcut for subclass test, intended for assertions only.
Definition: util.hpp:447
MORef< MOX > attach(Placement< MOX > const &newPlacement)
attach a child element to the model
MORef & operator=(MORef< MOX > const &oRef)
cross assignment.
lib::time::Time getStartTime()
resolves the referred placement to an ExplicitPlacement and returns the found start time ...
MORef & activate(MORef const &oRef)
build and activate an MObject reference based on an existing reference of the same pointee type ...
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...
Steam-Layer implementation namespace root.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:305
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:196
bool isSameDef(PlacementMO const &pl1, PlacementMO const &pl2)
compare the properties of placement
Definition: placement.cpp:77
static PID attach_toModel(PMO, PID)
attach an object by placement onto the session.
A generic reference mechanism for Placements, as added to the current session.
MORef & activate(REF const &pRefID)
build and activate an MObject reference, based on anything which might be assigned to an PlarementRef...
static bool detach_and_clear(PID)
detach the denoted element from the model including all children.
MORef & activate(Placement< MO > const &placement)
activate an MObject reference, based on an existing placement, which needs to be contained (added to)...
A generic opaque handle to an implementation entity, including lifecycle management.
PlacementRef< MO > const & getRef() const
allow to use a MObjectRef like a (bare) PlacementRef
Implementation level session API: add or remove Session contents.
bool isEquivalentPlacement(MORef< MOX > const &ref1, MORef< MOY > const &ref2)
check if the two references actually denote an equivalent placement