| 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 */
51 class WeakReference
52{
53 public:
54 /// \return 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) */
64 class WeakReferenceable
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 virtual void AddWeakReference( WeakReference* weakRef ) = 0;
70
71 /// Notify this object that its weak reference is being destroyed.
72 /// \param weakReference The weak reference to notify.
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 */
136 WeakRef()
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>
191 WeakRef& operator=( const WeakRef<U>& w )
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 */
224 WeakReferenceable* GetWeakReferenceable() const
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
disti::WeakRef
Definition: weak_reference.h:92
disti::WeakRef::operator=
WeakRef & operator=(const WeakRef< U > &w)
Definition: weak_reference.h:191
disti::WeakRef::WeakRef
WeakRef(WeakReferenceable *weakReferenceable)
Definition: weak_reference.h:144
disti::WeakRef::Get
T * Get() const
Definition: weak_reference.h:208
disti::WeakRef::WeakRef
WeakRef(const WeakRef< U > &w)
Definition: weak_reference.h:161
disti::WeakRef::WeakRef
WeakRef()
Definition: weak_reference.h:136
disti::WeakRef::operator=
WeakRef & operator=(const WeakRef &w)
Definition: weak_reference.h:180
disti::WeakRef::IsNull
bool IsNull() const
Definition: weak_reference.h:200
disti::WeakRef::GetWeakReferenceable
WeakReferenceable * GetWeakReferenceable() const
Definition: weak_reference.h:224
disti::WeakRef::WeakRef
WeakRef(const WeakRef &w)
Definition: weak_reference.h:152
disti::WeakRef::operator=
WeakRef & operator=(WeakReferenceable *weakReferenceable)
Definition: weak_reference.h:170
disti::WeakReference
Definition: weak_reference.h:52
disti::WeakReference::NotifyReferentDestroyed
virtual void NotifyReferentDestroyed()=0
Notify this weak reference that the object destroyed.
disti::WeakReference::GetReferent
virtual WeakReferenceable * GetReferent() const =0
disti::WeakReferenceable
Definition: weak_reference.h:65
disti::WeakReferenceable::AddWeakReference
virtual void AddWeakReference(WeakReference *weakRef)=0
disti::WeakReferenceable::NotifyWeakReferenceDestroyed
virtual void NotifyWeakReferenceDestroyed(WeakReference *weakReference)=0
disti_assert.h
Contains the DistiAssert macro.
GLS_ASSERT
#define GLS_ASSERT(exp)
Definition: disti_assert.h:150
DISTI_METHOD_OVERRIDE
#define DISTI_METHOD_OVERRIDE
Macro to wrap the override keyword, removed on compilers that don't support it.
Definition: gls_cpp_lang_support.h:222
disti
Definition: bmpimage.h:47
scoped_ptr.h
A smart pointer with unique ownership – poor man's std::unique_ptr.