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
14reproduced, in whole or part, in any form, or by any means of electronic,
15mechanical, or otherwise, without the written permission of DiSTI. Said
16permission may be derived through the purchase of applicable DiSTI product
17licenses which detail the distribution rights of this content and any
18Derivative Works based on this or other copyrighted DiSTI Software.
19
20 NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
21AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
22PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
23AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
25PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
26
27 LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
28IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
29INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
30DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
31INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
32INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBILITY
33OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
34EXCEED FIVE DOLLARS (US$5.00).
35
36 The aforementioned terms and restrictions are governed by the laws of the
37State 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
46namespace disti
47{
48class WeakReferenceable;
49
50/** Interface for holding a weak reference to an object. This class should generally not be used directly. Use WeakRef instead */
52{
53public:
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) */
65{
66public:
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 */
90template<class T>
92{
93private:
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
133public:
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 */
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
229private:
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
Definition: weak_reference.h:92
WeakRef & operator=(const WeakRef< U > &w)
Definition: weak_reference.h:191
WeakRef(WeakReferenceable *weakReferenceable)
Definition: weak_reference.h:144
T * Get() const
Definition: weak_reference.h:208
WeakRef(const WeakRef< U > &w)
Definition: weak_reference.h:161
WeakRef()
Definition: weak_reference.h:136
WeakRef & operator=(const WeakRef &w)
Definition: weak_reference.h:180
bool IsNull() const
Definition: weak_reference.h:200
WeakReferenceable * GetWeakReferenceable() const
Definition: weak_reference.h:224
WeakRef(const WeakRef &w)
Definition: weak_reference.h:152
WeakRef & operator=(WeakReferenceable *weakReferenceable)
Definition: weak_reference.h:170
Definition: weak_reference.h:52
virtual void NotifyReferentDestroyed()=0
Notify this weak reference that the object destroyed.
virtual WeakReferenceable * GetReferent() const =0
Definition: weak_reference.h:65
virtual void AddWeakReference(WeakReference *weakRef)=0
virtual void NotifyWeakReferenceDestroyed(WeakReference *weakReference)=0
Contains the DistiAssert macro.
#define GLS_ASSERT(exp)
Definition: disti_assert.h:150
#define DISTI_METHOD_OVERRIDE
Macro to wrap the override keyword, removed on compilers that don't support it.
Definition: gls_cpp_lang_support.h:214
Force inclusion of the DirectShow library.
Definition: bmpimage.h:47
A smart pointer with unique ownership – poor man's std::unique_ptr.