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 lumiera {
73 namespace error {
74  LUMIERA_ERROR_DECLARE (BOTTOM_MOBJECTREF);
75 }}
76 
77 namespace steam {
78 namespace mobject {
79 
80  namespace error = lumiera::error;
81 
82  class MObject;
83 
84 
93  template<class MO =MObject>
94  class MORef
95  : public lib::Handle<MO>
96  {
97  typedef lib::Handle<MO> _Handle;
98  typedef PlacementMO::Id<MO> _Id;
99 
100 
101  PlacementRef<MO> pRef_;
102  using _Handle::smPtr_;
103 
104 
105 
106  public:
107 
108  MO*
109  operator-> () const
110  {
111  if (!smPtr_)
112  throw error::State("Lifecycle error: MObject ref not activated"
113  , LERR_(BOTTOM_MOBJECTREF));
114 
115  ENSURE (INSTANCEOF (MO, smPtr_.get()));
116  return smPtr_.operator-> ();
117  }
118 
119 
120  Placement<MO>& getPlacement() const
121  {
122  if (!isValid())
123  throw error::State("Accessing inactive MObject ref"
124  , LERR_(BOTTOM_MOBJECTREF));
125 
126  ENSURE (INSTANCEOF (MO, smPtr_.get()));
127  return *pRef_;
128  }
129 
130 
133  PlacementRef<MO> const&
134  getRef() const
135  {
136  return pRef_;
137  }
138 
143  operator _Id const&() const
144  {
145  return pRef_;
146  }
147 
148 
149 
155  {
156  return pRef_.resolve().time;
157  }
158 
159 
165  template<class MOX>
166  MORef<MOX>
167  attach (Placement<MOX> const& newPlacement)
168  {
169  if (!isValid())
170  throw error::State("Attempt to attach a child to an inactive MObject ref"
171  , LERR_(BOTTOM_MOBJECTREF));
172  MORef<MOX> newInstance;
173  PlacementMO::ID thisScope = pRef_;
174  return newInstance.activate (
175  session::SessionServiceMutate::attach_toModel (newPlacement, thisScope));
176  }
177 
178 
183  void
184  purge ()
185  {
186  if (isValid())
188 
189  ENSURE (!isValid());
190  }
191 
192 
193 
194  /* === Lifecycle === */
195 
203  MORef&
204  activate (Placement<MO> const& placement)
205  {
206  ASSERT (placement.isValid());
207  pRef_ = placement; // STRONG exception safe
208  placement.extendOwnershipTo(smPtr_); // never throws
209  return *this;
210  }
211 
222  template<typename REF>
223  MORef&
224  activate (REF const& pRefID)
225  {
226  PlacementRef<MO> newRef (pRefID);
227 
228  if (isValid() && pRef_ == newRef )
229  return *this; // self assignment detected
230  else
231  return activate (*newRef); // STRONG exception safe
232  }
233 
240  MORef&
241  activate (MORef const& oRef)
242  {
243  return activate (oRef.getPlacement());
244  }
245 
246  template<typename MOX>
247  MORef&
248  activate (MORef<MOX> const& oRef)
249  {
250  return activate (oRef.getPlacement().getID());
251  }
252 
260  template<typename MOX>
261  MORef&
262  operator= (MORef<MOX> const& oRef)
263  {
264  return activate (oRef);
265  }
266 
267 
268 
269 
270  /* == diagnostics == */
271  bool
272  isValid() const
273  {
274  return _Handle::isValid()
275  && pRef_.isValid();
276  }
277 
278  size_t
279  use_count() const
280  {
281  return isValid()? pRef_.use_count() : 0;
282  }
283 
284  template<class MOX>
285  bool
286  isCompatible() const
287  {
288  return pRef_
289  && (*pRef_).template isCompatible<MOX>();
290  }
291 
292  operator string() const
293  {
294  return isValid()? string(getPlacement())
295  : "MRef-NIL";
296  }
297 
298 
299 
300 
301  /* == equality comparisons == */
302 
303  template<class MOX>
304  bool
305  operator== (MORef<MOX> const& oRef) const
306  {
307  return isValid()
308  && oRef == this->pRef_;
309  }
310 
311  template<class MOX>
312  bool
313  operator!= (MORef<MOX> const& oRef) const
314  {
315  return not isValid()
316  or oRef != this->pRef_;
317  }
318 
319  template<class MOX>
320  friend bool
321  operator== (MORef const& oRef, PlacementRef<MOX> const& pRef)
322  {
323  return oRef.isValid()
324  and oRef.pRef_ == pRef;
325  }
326 
327  template<class MOX>
328  friend bool
329  operator!= (MORef const& oRef, PlacementRef<MOX> const& pRef)
330  {
331  return not oRef.isValid()
332  or oRef.pRef_ != pRef;
333  }
334 
335  template<class MOX>
336  friend bool
337  operator== (PlacementRef<MOX> const& pRef, MORef const& oRef)
338  {
339  return oRef.isValid()
340  and pRef == oRef.pRef_;
341  }
342 
343  template<class MOX>
344  friend bool
345  operator!= (PlacementRef<MOX> const& pRef, MORef const& oRef)
346  {
347  return not oRef.isValid()
348  or pRef != oRef.pRef_;
349  }
350 
351  bool
352  operator== (PlacementMO::ID const& pID) const
353  {
354  return isValid()
355  and PlacementMO::ID (pRef_) == pID;
356  }
357 
358  bool
359  operator!= (PlacementMO::ID const& pID) const
360  {
361  return not isValid()
362  or PlacementMO::ID (pRef_) != pID;
363  }
364 
365  };
366 
367 
368  typedef MORef<MObject> MObjectRef;
369 
370 
371  /* === convenience shortcuts === */
372 
377  template<class MOX, class MOY>
378  inline bool
379  isSharedPointee (MORef<MOX> const& ref1, MORef<MOY> const& ref2)
380  {
381  return ref1.isValid() && ref2.isValid()
382  && isSharedPointee (ref1.getPlacement(), ref2.getPlacement());
383  }
384 
386  template<class MOX, class MOY>
387  inline bool
388  isEquivalentPlacement (MORef<MOX> const& ref1, MORef<MOY> const& ref2)
389  {
390  return ref1.isValid() && ref2.isValid()
391  && isSameDef (ref1.getPlacement(), ref2.getPlacement());
392  }
393 
394 
395 }} // namespace steam::mobject
396 #endif
A refcounting Handle to an MObject of type MO, used to constrain or explicitly specify the location w...
Definition: trait.hpp:91
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:94
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:492
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:71
Steam-Layer implementation namespace root.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:308
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:199
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.
Lumiera public interface.
Definition: advice.cpp:113
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