OpenShot Library | libopenshot-audio  0.1.9
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->() noexcept { return get(); }
113 
114  /** Returns the object that this pointer refers to, or null if the object no longer exists. */
115  const ObjectType* operator->() const noexcept { return get(); }
116 
117  /** This returns true if this reference has been pointing at an object, but that object has
118  since been deleted.
119 
120  If this reference was only ever pointing at a null pointer, this will return false. Using
121  operator=() to make this refer to a different object will reset this flag to match the status
122  of the reference from which you're copying.
123  */
124  bool wasObjectDeleted() const noexcept { return holder != nullptr && holder->get() == nullptr; }
125 
126  bool operator== (ObjectType* object) const noexcept { return get() == object; }
127  bool operator!= (ObjectType* object) const noexcept { return get() != object; }
128 
129  //==============================================================================
130  /** This class is used internally by the WeakReference class - don't use it directly
131  in your code!
132  @see WeakReference
133  */
134  class SharedPointer : public ReferenceCountingType
135  {
136  public:
137  explicit SharedPointer (ObjectType* obj) noexcept : owner (obj) {}
138 
139  inline ObjectType* get() const noexcept { return owner; }
140  void clearPointer() noexcept { owner = nullptr; }
141 
142  private:
143  ObjectType* owner;
144 
145  JUCE_DECLARE_NON_COPYABLE (SharedPointer)
146  };
147 
149 
150  //==============================================================================
151  /**
152  This class is embedded inside an object to which you want to attach WeakReference pointers.
153  See the WeakReference class notes for an example of how to use this class.
154  @see WeakReference
155  */
156  class Master
157  {
158  public:
159  Master() = default;
160 
161  ~Master() noexcept
162  {
163  // You must remember to call clear() in your source object's destructor! See the notes
164  // for the WeakReference class for an example of how to do this.
165  jassert (sharedPointer == nullptr || sharedPointer->get() == nullptr);
166  }
167 
168  /** The first call to this method will create an internal object that is shared by all weak
169  references to the object.
170  */
171  SharedRef getSharedPointer (ObjectType* object)
172  {
173  if (sharedPointer == nullptr)
174  {
175  sharedPointer = *new SharedPointer (object);
176  }
177  else
178  {
179  // You're trying to create a weak reference to an object that has already been deleted!!
180  jassert (sharedPointer->get() != nullptr);
181  }
182 
183  return sharedPointer;
184  }
185 
186  /** The object that owns this master pointer should call this before it gets destroyed,
187  to zero all the references to this object that may be out there. See the WeakReference
188  class notes for an example of how to do this.
189  */
190  void clear() noexcept
191  {
192  if (sharedPointer != nullptr)
193  sharedPointer->clearPointer();
194  }
195 
196  /** Returns the number of WeakReferences that are out there pointing to this object. */
197  int getNumActiveWeakReferences() const noexcept
198  {
199  return sharedPointer == nullptr ? 0 : (sharedPointer->getReferenceCount() - 1);
200  }
201 
202  private:
203  SharedRef sharedPointer;
204 
205  JUCE_DECLARE_NON_COPYABLE (Master)
206  };
207 
208 private:
209  SharedRef holder;
210 
211  static inline SharedRef getRef (ObjectType* o)
212  {
213  if (o != nullptr)
214  return o->masterReference.getSharedPointer (o);
215 
216  return {};
217  }
218 };
219 
220 
221 //==============================================================================
222 /**
223  Macro to easily allow a class to be made weak-referenceable.
224  This can be inserted in a class definition to add the requisite weak-ref boilerplate to that class.
225  e.g.
226 
227  @code
228  class MyObject
229  {
230  public:
231  MyObject();
232  ~MyObject();
233 
234  private:
235  JUCE_DECLARE_WEAK_REFERENCEABLE (MyObject)
236  };
237  @endcode
238 
239  @see WeakReference, WeakReference::Master
240 */
241 #define JUCE_DECLARE_WEAK_REFERENCEABLE(Class) \
242  struct WeakRefMaster : public juce::WeakReference<Class>::Master { ~WeakRefMaster() { this->clear(); } }; \
243  WeakRefMaster masterReference; \
244  friend class juce::WeakReference<Class>; \
245 
246 
247 } // namespace juce
248 
249 /** @}*/
bool wasObjectDeleted() const noexcept
This returns true if this reference has been pointing at an object, but that object has since been de...
void clear() noexcept
The object that owns this master pointer should call this before it gets destroyed, to zero all the references to this object that may be out there.
SharedRef getSharedPointer(ObjectType *object)
The first call to this method will create an internal object that is shared by all weak references to...
int getNumActiveWeakReferences() const noexcept
Returns the number of WeakReferences that are out there pointing to this object.
ReferencedType * get() const noexcept
Returns the object that this pointer references.
This class acts as a pointer which will automatically become null if the object to which it points is...
ObjectType * operator->() 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.
const 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.
WeakReference(WeakReference &&other) noexcept
Move constructor.
WeakReference(const WeakReference &other) noexcept
Creates a copy of another WeakReference.
This class is embedded inside an object to which you want to attach WeakReference pointers...
This class is used internally by the WeakReference class - don&#39;t use it directly in your code! ...
WeakReference & operator=(const WeakReference &other)
Copies another pointer to this one.