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)
5  2009, 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 
14 
50 #ifndef MOBJECT_MOBJECT_REF_H
51 #define MOBJECT_MOBJECT_REF_H
52 
53 #include "lib/handle.hpp"
57 
58 #include <string>
59 
60 
62 
63 namespace lumiera {
64 namespace error {
65  LUMIERA_ERROR_DECLARE (BOTTOM_MOBJECTREF);
66 }}
67 
68 namespace steam {
69 namespace mobject {
70 
71  namespace error = lumiera::error;
72 
73  class MObject;
74 
75 
84  template<class MO =MObject>
85  class MORef
86  : public lib::Handle<MO>
87  {
88  typedef lib::Handle<MO> _Handle;
89  typedef PlacementMO::Id<MO> _Id;
90 
91 
92  PlacementRef<MO> pRef_;
93  using _Handle::smPtr_;
94 
95 
96 
97  public:
98 
99  MO*
100  operator-> () const
101  {
102  if (!smPtr_)
103  throw error::State("Lifecycle error: MObject ref not activated"
104  , LERR_(BOTTOM_MOBJECTREF));
105 
106  ENSURE (INSTANCEOF (MO, smPtr_.get()));
107  return smPtr_.operator-> ();
108  }
109 
110 
111  Placement<MO>& getPlacement() const
112  {
113  if (!isValid())
114  throw error::State("Accessing inactive MObject ref"
115  , LERR_(BOTTOM_MOBJECTREF));
116 
117  ENSURE (INSTANCEOF (MO, smPtr_.get()));
118  return *pRef_;
119  }
120 
121 
124  PlacementRef<MO> const&
125  getRef() const
126  {
127  return pRef_;
128  }
129 
134  operator _Id const&() const
135  {
136  return pRef_;
137  }
138 
139 
140 
146  {
147  return pRef_.resolve().time;
148  }
149 
150 
156  template<class MOX>
157  MORef<MOX>
158  attach (Placement<MOX> const& newPlacement)
159  {
160  if (!isValid())
161  throw error::State("Attempt to attach a child to an inactive MObject ref"
162  , LERR_(BOTTOM_MOBJECTREF));
163  MORef<MOX> newInstance;
164  PlacementMO::ID thisScope = pRef_;
165  return newInstance.activate (
166  session::SessionServiceMutate::attach_toModel (newPlacement, thisScope));
167  }
168 
169 
174  void
175  purge ()
176  {
177  if (isValid())
179 
180  ENSURE (!isValid());
181  }
182 
183 
184 
185  /* === Lifecycle === */
186 
194  MORef&
195  activate (Placement<MO> const& placement)
196  {
197  ASSERT (placement.isValid());
198  pRef_ = placement; // STRONG exception safe
199  placement.extendOwnershipTo(smPtr_); // never throws
200  return *this;
201  }
202 
213  template<typename REF>
214  MORef&
215  activate (REF const& pRefID)
216  {
217  PlacementRef<MO> newRef (pRefID);
218 
219  if (isValid() && pRef_ == newRef )
220  return *this; // self assignment detected
221  else
222  return activate (*newRef); // STRONG exception safe
223  }
224 
231  MORef&
232  activate (MORef const& oRef)
233  {
234  return activate (oRef.getPlacement());
235  }
236 
237  template<typename MOX>
238  MORef&
239  activate (MORef<MOX> const& oRef)
240  {
241  return activate (oRef.getPlacement().getID());
242  }
243 
251  template<typename MOX>
252  MORef&
253  operator= (MORef<MOX> const& oRef)
254  {
255  return activate (oRef);
256  }
257 
258 
259 
260 
261  /* == diagnostics == */
262  bool
263  isValid() const
264  {
265  return _Handle::isValid()
266  && pRef_.isValid();
267  }
268 
269  size_t
270  use_count() const
271  {
272  return isValid()? pRef_.use_count() : 0;
273  }
274 
275  template<class MOX>
276  bool
277  isCompatible() const
278  {
279  return pRef_
280  && (*pRef_).template isCompatible<MOX>();
281  }
282 
283  operator string() const
284  {
285  return isValid()? string(getPlacement())
286  : "MRef-NIL";
287  }
288 
289 
290 
291 
292  /* == equality comparisons == */
293 
294  template<class MOX>
295  bool
296  operator== (MORef<MOX> const& oRef) const
297  {
298  return isValid()
299  && oRef == this->pRef_;
300  }
301 
302  template<class MOX>
303  bool
304  operator!= (MORef<MOX> const& oRef) const
305  {
306  return not isValid()
307  or oRef != this->pRef_;
308  }
309 
310  template<class MOX>
311  friend bool
312  operator== (MORef const& oRef, PlacementRef<MOX> const& pRef)
313  {
314  return oRef.isValid()
315  and oRef.pRef_ == pRef;
316  }
317 
318  template<class MOX>
319  friend bool
320  operator!= (MORef const& oRef, PlacementRef<MOX> const& pRef)
321  {
322  return not oRef.isValid()
323  or oRef.pRef_ != pRef;
324  }
325 
326  template<class MOX>
327  friend bool
328  operator== (PlacementRef<MOX> const& pRef, MORef const& oRef)
329  {
330  return oRef.isValid()
331  and pRef == oRef.pRef_;
332  }
333 
334  template<class MOX>
335  friend bool
336  operator!= (PlacementRef<MOX> const& pRef, MORef const& oRef)
337  {
338  return not oRef.isValid()
339  or pRef != oRef.pRef_;
340  }
341 
342  bool
343  operator== (PlacementMO::ID const& pID) const
344  {
345  return isValid()
346  and PlacementMO::ID (pRef_) == pID;
347  }
348 
349  bool
350  operator!= (PlacementMO::ID const& pID) const
351  {
352  return not isValid()
353  or PlacementMO::ID (pRef_) != pID;
354  }
355 
356  };
357 
358 
359  typedef MORef<MObject> MObjectRef;
360 
361 
362  /* === convenience shortcuts === */
363 
368  template<class MOX, class MOY>
369  inline bool
370  isSharedPointee (MORef<MOX> const& ref1, MORef<MOY> const& ref2)
371  {
372  return ref1.isValid() && ref2.isValid()
373  && isSharedPointee (ref1.getPlacement(), ref2.getPlacement());
374  }
375 
377  template<class MOX, class MOY>
378  inline bool
379  isEquivalentPlacement (MORef<MOX> const& ref1, MORef<MOY> const& ref2)
380  {
381  return ref1.isValid() && ref2.isValid()
382  && isSameDef (ref1.getPlacement(), ref2.getPlacement());
383  }
384 
385 
386 }} // namespace steam::mobject
387 #endif
A refcounting Handle to an MObject of type MO, used to constrain or explicitly specify the location w...
Definition: trait.hpp:82
Generic opaque reference counting handle, for accessing a service and managing its lifecycle...
Definition: handle.hpp:63
An active (smart-ptr like) external reference to a specifically placed MObject "instance" within the ...
Definition: mobject-ref.hpp:85
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:514
MORef< MOX > attach(Placement< MOX > const &newPlacement)
attach a child element to the model
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...
#define LUMIERA_ERROR_DECLARE(err)
Forward declare an error constant.
Definition: error.h:62
Steam-Layer implementation namespace root.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:299
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
bool isSameDef(PlacementMO const &pl1, PlacementMO const &pl2)
compare the properties of placement
Definition: placement.cpp:68
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.
Lumiera public interface.
Definition: advice.cpp:104
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