OpenShot Library | OpenShotAudio 0.2.2
juce_WeakReference.h
1
2/** @weakgroup juce_core-memory
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 The code included in this file is provided under the terms of the ISC license
15 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16 To use, copy, modify, and/or distribute this software for any purpose with or
17 without fee is hereby granted provided that the above copyright notice and
18 this permission notice appear in all copies.
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29
30//==============================================================================
31/**
32 This class acts as a pointer which will automatically become null if the object
33 to which it points is deleted.
34
35 To accomplish this, the source object needs to cooperate by performing a couple of simple tasks.
36 It must embed a WeakReference::Master object, which stores a shared pointer object, and must clear
37 this master pointer in its destructor.
38
39 Note that WeakReference is not designed to be thread-safe, so if you're accessing it from
40 different threads, you'll need to do your own locking around all uses of the pointer and
41 the object it refers to.
42
43 E.g.
44 @code
45 class MyObject
46 {
47 public:
48 MyObject() {}
49
50 ~MyObject()
51 {
52 // This will zero all the references - you need to call this in your destructor.
53 masterReference.clear();
54 }
55
56 private:
57 // You need to embed a variable of this type, with the name "masterReference" inside your object. If the
58 // variable is not public, you should make your class a friend of WeakReference<MyObject> so that the
59 // WeakReference class can access it.
60 WeakReference<MyObject>::Master masterReference;
61 friend class WeakReference<MyObject>;
62 };
63
64 OR: just use the handy JUCE_DECLARE_WEAK_REFERENCEABLE macro to do all this for you.
65
66 // Here's an example of using a pointer..
67
68 auto* n = new MyObject();
69 WeakReference<MyObject> myObjectRef = n;
70
71 auto pointer1 = myObjectRef.get(); // returns a valid pointer to 'n'
72 delete n;
73 auto pointer2 = myObjectRef.get(); // now returns nullptr
74 @endcode
75
76 @see WeakReference::Master
77
78 @tags{Core}
79*/
80template <class ObjectType, class ReferenceCountingType = ReferenceCountedObject>
82{
83public:
84 /** Creates a null WeakReference. */
85 inline WeakReference() = default;
86
87 /** Creates a WeakReference that points at the given object. */
88 WeakReference (ObjectType* object) : holder (getRef (object)) {}
89
90 /** Creates a copy of another WeakReference. */
91 WeakReference (const WeakReference& other) noexcept : holder (other.holder) {}
92
93 /** Move constructor */
94 WeakReference (WeakReference&& other) noexcept : holder (std::move (other.holder)) {}
95
96 /** Copies another pointer to this one. */
97 WeakReference& operator= (const WeakReference& other) { holder = other.holder; return *this; }
98
99 /** Copies another pointer to this one. */
100 WeakReference& operator= (ObjectType* newObject) { holder = getRef (newObject); return *this; }
101
102 /** Move assignment operator */
103 WeakReference& operator= (WeakReference&& other) noexcept { holder = std::move (other.holder); return *this; }
104
105 /** Returns the object that this pointer refers to, or null if the object no longer exists. */
106 ObjectType* get() const noexcept { return holder != nullptr ? holder->get() : nullptr; }
107
108 /** Returns the object that this pointer refers to, or null if the object no longer exists. */
109 operator ObjectType*() const noexcept { return get(); }
110
111 /** Returns the object that this pointer refers to, or null if the object no longer exists. */
112 ObjectType* operator->() const noexcept { return get(); }
113
114 /** This returns true if this reference has been pointing at an object, but that object has
115 since been deleted.
116
117 If this reference was only ever pointing at a null pointer, this will return false. Using
118 operator=() to make this refer to a different object will reset this flag to match the status
119 of the reference from which you're copying.
120 */
121 bool wasObjectDeleted() const noexcept { return holder != nullptr && holder->get() == nullptr; }
122
123 bool operator== (ObjectType* object) const noexcept { return get() == object; }
124 bool operator!= (ObjectType* object) const noexcept { return get() != object; }
125
126 //==============================================================================
127 /** This class is used internally by the WeakReference class - don't use it directly
128 in your code!
129 @see WeakReference
130 */
131 class SharedPointer : public ReferenceCountingType
132 {
133 public:
134 explicit SharedPointer (ObjectType* obj) noexcept : owner (obj) {}
135
136 inline ObjectType* get() const noexcept { return owner; }
137 void clearPointer() noexcept { owner = nullptr; }
138
139 private:
140 ObjectType* owner;
141
142 JUCE_DECLARE_NON_COPYABLE (SharedPointer)
143 };
144
146
147 //==============================================================================
148 /**
149 This class is embedded inside an object to which you want to attach WeakReference pointers.
150 See the WeakReference class notes for an example of how to use this class.
151 @see WeakReference
152 */
153 class Master
154 {
155 public:
156 Master() = default;
157
158 ~Master() noexcept
159 {
160 // You must remember to call clear() in your source object's destructor! See the notes
161 // for the WeakReference class for an example of how to do this.
162 jassert (sharedPointer == nullptr || sharedPointer->get() == nullptr);
163 }
164
165 /** The first call to this method will create an internal object that is shared by all weak
166 references to the object.
167 */
168 SharedRef getSharedPointer (ObjectType* object)
169 {
170 if (sharedPointer == nullptr)
171 {
172 sharedPointer = *new SharedPointer (object);
173 }
174 else
175 {
176 // You're trying to create a weak reference to an object that has already been deleted!!
177 jassert (sharedPointer->get() != nullptr);
178 }
179
180 return sharedPointer;
181 }
182
183 /** The object that owns this master pointer should call this before it gets destroyed,
184 to zero all the references to this object that may be out there. See the WeakReference
185 class notes for an example of how to do this.
186 */
187 void clear() noexcept
188 {
189 if (sharedPointer != nullptr)
190 sharedPointer->clearPointer();
191 }
192
193 /** Returns the number of WeakReferences that are out there pointing to this object. */
194 int getNumActiveWeakReferences() const noexcept
195 {
196 return sharedPointer == nullptr ? 0 : (sharedPointer->getReferenceCount() - 1);
197 }
198
199 private:
200 SharedRef sharedPointer;
201
202 JUCE_DECLARE_NON_COPYABLE (Master)
203 };
204
205private:
206 SharedRef holder;
207
208 static inline SharedRef getRef (ObjectType* o)
209 {
210 if (o != nullptr)
211 return o->masterReference.getSharedPointer (o);
212
213 return {};
214 }
215};
216
217
218//==============================================================================
219/**
220 Macro to easily allow a class to be made weak-referenceable.
221 This can be inserted in a class definition to add the requisite weak-ref boilerplate to that class.
222 e.g.
223
224 @code
225 class MyObject
226 {
227 public:
228 MyObject();
229 ~MyObject();
230
231 private:
232 JUCE_DECLARE_WEAK_REFERENCEABLE (MyObject)
233 };
234 @endcode
235
236 @see WeakReference, WeakReference::Master
237*/
238#define JUCE_DECLARE_WEAK_REFERENCEABLE(Class) \
239 struct WeakRefMaster : public juce::WeakReference<Class>::Master { ~WeakRefMaster() { this->clear(); } }; \
240 WeakRefMaster masterReference; \
241 friend class juce::WeakReference<Class>; \
242
243
244} // namespace juce
245
246/** @}*/
ReferencedType * get() const noexcept
Returns the object that this pointer references.
This class is embedded inside an object to which you want to attach WeakReference pointers.
int getNumActiveWeakReferences() const noexcept
Returns the number of WeakReferences that are out there pointing to this object.
void clear() noexcept
The object that owns this master pointer should call this before it gets destroyed,...
SharedRef getSharedPointer(ObjectType *object)
The first call to this method will create an internal object that is shared by all weak references to...
This class is used internally by the WeakReference class - don't use it directly in your code!
This class acts as a pointer which will automatically become null if the object to which it points is...
ObjectType * operator->() const noexcept
Returns the object that this pointer refers to, or null if the object no longer exists.
WeakReference()=default
Creates a null WeakReference.
ObjectType * get() const noexcept
Returns the object that this pointer refers to, or null if the object no longer exists.
WeakReference(WeakReference &&other) noexcept
Move constructor.
WeakReference & operator=(const WeakReference &other)
Copies another pointer to this one.
WeakReference(const WeakReference &other) noexcept
Creates a copy of another WeakReference.
bool wasObjectDeleted() const noexcept
This returns true if this reference has been pointing at an object, but that object has since been de...
WeakReference(ObjectType *object)
Creates a WeakReference that points at the given object.