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 
27 namespace 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 */
80 template <class ObjectType, class ReferenceCountingType = ReferenceCountedObject>
82 {
83 public:
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 
205 private:
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...
WeakReference()=default
Creates a null WeakReference.
WeakReference(WeakReference &&other) noexcept
Move constructor.
ObjectType * get() const noexcept
Returns the object that this pointer refers to, or null if the object no longer exists.
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...
ObjectType * operator->() const noexcept
Returns the object that this pointer refers to, or null if the object no longer exists.
WeakReference(ObjectType *object)
Creates a WeakReference that points at the given object.