GL Studio C++ Runtime API
weak_reference.h
Go to the documentation of this file.
1 /*! \file
2  \brief weak reference and related classes
3 
4  \par Copyright Information
5 
6  Copyright (c) 2016 by The DiSTI Corporation.<br>
7  11301 Corporate Blvd; Suite 100<br>
8  Orlando, Florida 32817<br>
9  USA<br>
10  <br>
11  All rights reserved.<br>
12 
13  This Software contains proprietary trade secrets of DiSTI and may not be
14 reproduced, in whole or part, in any form, or by any means of electronic,
15 mechanical, or otherwise, without the written permission of DiSTI. Said
16 permission may be derived through the purchase of applicable DiSTI product
17 licenses which detail the distribution rights of this content and any
18 Derivative Works based on this or other copyrighted DiSTI Software.
19 
20  NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
21 AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
22 PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
23 AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24 IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
25 PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
26 
27  LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
28 IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
29 INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
30 DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
31 INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
32 INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBILITY
33 OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
34 EXCEED FIVE DOLLARS (US$5.00).
35 
36  The aforementioned terms and restrictions are governed by the laws of the
37 State of Florida and the United States of America.
38 
39 */
40 #ifndef INCLUDED_WEAK_REFERENCE_H
41 #define INCLUDED_WEAK_REFERENCE_H
42 
43 #include "disti_assert.h"
44 #include "scoped_ptr.h"
45 
46 namespace disti
47 {
48 class WeakReferenceable;
49 
50 /** Interface for holding a weak reference to an object. This class should generally not be used directly. Use WeakRef instead */
52 {
53 public:
54  /** Get a pointer to the object. Returns NULL if the object was deleted */
55  virtual WeakReferenceable* GetReferent() const = 0;
56 
57  /** Notify this weak reference that the object destroyed */
58  virtual void NotifyReferentDestroyed() = 0;
59 
60  virtual ~WeakReference() {}
61 };
62 
63 /** Interface for getting a weak reference to an object. To implement this class, inherit from WeakReferenceableMixin (see DisplayObject as an example) */
65 {
66 public:
67  /** Add a weak reference to this object, that gets notified when this object is destroyed. Does not take ownership of weakRef.
68  * \param weakRef the weak reference to add.
69  */
70  virtual void AddWeakReference( WeakReference* weakRef ) = 0;
71 
72  /** Notify this object that its weak reference is being destroyed */
73  virtual void NotifyWeakReferenceDestroyed( WeakReference* weakReference ) = 0;
74 
75  virtual ~WeakReferenceable() {}
76 };
77 
78 /** helper class to simplify working with a weak reference
79  * Ex Usage:
80  * DisplayObject* obj = GetSomeDisplayObject();
81  * WeakRef< DisplayObject > weakRef = obj;
82  * ...
83  * ... some code that may or may not have deleted obj
84  * ...
85  * if( !weakRef.IsNull() )
86  * {
87  * weakRef.Get()->Location( 0, 0, 0 );
88  * }
89  */
90 template<class T>
91 class WeakRef
92 {
93 private:
94  /** Implementation for a weak reference */
95  class WeakReferenceImpl : virtual public WeakReference
96  {
97  public:
98  /** constructor
99  * \param referent a pointer to the WeakReferenceable object
100  */
101  WeakReferenceImpl( WeakReferenceable* referent )
102  : _referent( referent )
103  {
104  if( referent )
105  {
106  referent->AddWeakReference( this );
107  }
108  }
109 
110  /** destructor. Notifies the WeakReferenceable that this WeakReference is being deleted */
111  ~WeakReferenceImpl()
112  {
113  if( _referent )
114  {
115  _referent->NotifyWeakReferenceDestroyed( this );
116  }
117  }
118 
119  /** \see WeakReference */
120  WeakReferenceable* GetReferent() const DISTI_METHOD_OVERRIDE { return _referent; }
121 
122  /** notifies the WeakReference that the WeakReferenceable object is being destroyed so it can set its referent to NULL */
123  void NotifyReferentDestroyed() DISTI_METHOD_OVERRIDE
124  {
125  _referent = NULL;
126  }
127 
128  private:
129  /** pointer to the WeakReferenceable object */
130  WeakReferenceable* _referent;
131  };
132 
133 public:
134  /** default ctor -- initializes weak reference to NULL
135  */
137  {
138  GLS_ASSERT( IsNull() );
139  }
140 
141  /** construct from a WeakReferenceable pointer
142  * \param[in] weakReferenceable pointer to an WeakReferenceable interface ( can be NULL )
143  */
144  WeakRef( WeakReferenceable* weakReferenceable )
145  {
146  SetWeakReference( weakReferenceable );
147  }
148 
149  /** construct from an WeakRef< T >
150  * \param[in] w WeakRef< T > ( can be NULL )
151  */
152  WeakRef( const WeakRef& w )
153  {
154  SetWeakReference( w.GetWeakReferenceable() );
155  }
156 
157  /** construct from an WeakRef< U >
158  * \param[in] w WeakRef< U > ( can be NULL )
159  */
160  template<class U>
161  WeakRef( const WeakRef<U>& w )
162  {
163  SetWeakReference( w.GetWeakReferenceable() );
164  }
165 
166  /** assign this weak ref to reference the given WeakReferenceable*
167  * \param weakReferenceable WeakReferenceable* in question (can be NULL)
168  * \return a ref to this
169  */
170  WeakRef& operator=( WeakReferenceable* weakReferenceable )
171  {
172  SetWeakReference( weakReferenceable );
173  return *this;
174  }
175 
176  /** assign this pointer to point to the given WeakRef< T >
177  * \param w WeakRef< T > in question (can be NULL)
178  * \return a ref to this
179  */
180  WeakRef& operator=( const WeakRef& w )
181  {
182  SetWeakReference( w.GetWeakReferenceable() );
183  return *this;
184  }
185 
186  /** assign this pointer to point to the given WeakRef< U >
187  * \param w WeakRef< U > in question (can be NULL)
188  * \return a ref to this
189  */
190  template<class U>
192  {
193  SetWeakReference( w.GetWeakReferenceable() );
194  return *this;
195  }
196 
197  /** determine if weak reference is NULL
198  * \return true if weak ref is NULL else false
199  */
200  bool IsNull() const
201  {
202  return ( _weakReference.IsNull() || NULL == _weakReference->GetReferent() );
203  }
204 
205  /** Get a T*
206  * \return if referent exists and supports interface T then return a pointer to T, else return NULL
207  */
208  T* Get() const
209  {
210  T* ret = NULL;
211 
212  // if there is still a weak ref, see if it has a referent that supports interface T
213  if( !IsNull() )
214  {
215  ret = dynamic_cast<T*>( _weakReference->GetReferent() );
216  }
217 
218  return ret;
219  }
220 
221  /** get the WeakReferenceable* contained in this weak ref
222  * \return the WeakReferenceable pointer contained in this weak ref ( can be NULL )
223  */
225  {
226  return !_weakReference.IsNull() ? _weakReference->GetReferent() : NULL;
227  }
228 
229 private:
230  void SetWeakReference( WeakReferenceable* weakReferenceable )
231  {
232  WeakReference* weakRef = NULL;
233  if( weakReferenceable )
234  {
235  // Important - this weak reference must be allocated in the same unit that will delete it, which is
236  // why its only allocated here, right before we store it in the object that will delete it.
237  weakRef = new WeakReferenceImpl( weakReferenceable );
238  GLS_ASSERT( NULL != weakRef->GetReferent() );
239  }
240 
241  _weakReference.Reset( weakRef );
242  }
243 
244  ScopedPtr<WeakReference> _weakReference; /**< weak reference else NULL */
245 };
246 
247 } // namespace disti
248 
249 #endif
WeakRef(const WeakRef &w)
Definition: weak_reference.h:152
virtual WeakReferenceable * GetReferent() const =0
WeakRef & operator=(WeakReferenceable *weakReferenceable)
Definition: weak_reference.h:170
WeakRef & operator=(const WeakRef< U > &w)
Definition: weak_reference.h:191
virtual void AddWeakReference(WeakReference *weakRef)=0
WeakRef(const WeakRef< U > &w)
Definition: weak_reference.h:161
WeakRef()
Definition: weak_reference.h:136
T * Get() const
Definition: weak_reference.h:208
Definition: weak_reference.h:51
WeakRef(WeakReferenceable *weakReferenceable)
Definition: weak_reference.h:144
Definition: weak_reference.h:64
#define GLS_ASSERT(exp)
Definition: disti_assert.h:135
virtual void NotifyReferentDestroyed()=0
WeakReferenceable * GetWeakReferenceable() const
Definition: weak_reference.h:224
Definition: weak_reference.h:91
bool IsNull() const
Definition: weak_reference.h:200
A smart pointer with unique ownership – poor man's std::unique_ptr.
Contains the DistiAssert macro.
WeakRef & operator=(const WeakRef &w)
Definition: weak_reference.h:180
virtual void NotifyWeakReferenceDestroyed(WeakReference *weakReference)=0
Definition: bmpimage.h:46