Panda3D
weakReferenceList.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file weakReferenceList.cxx
10  * @author drose
11  * @date 2004-09-27
12  */
13 
14 #include "weakReferenceList.h"
15 #include "weakPointerToVoid.h"
16 #include "pnotify.h"
17 
18 /**
19  *
20  */
21 WeakReferenceList::
22 WeakReferenceList() : _count(_alive_offset) {
23 }
24 
25 /**
26  * The destructor tells all of the owned references that we're gone.
27  */
30  nassertv(_count == 0);
31 }
32 
33 /**
34  * Adds the callback to the list of callbacks that will be called when the
35  * underlying pointer is deleted. If it has already been deleted, it will
36  * be called immediately.
37  *
38  * The data pointer can be an arbitrary pointer and is passed as only argument
39  * to the callback.
40  */
42 add_callback(WeakPointerCallback *callback, void *data) {
43  nassertv(callback != nullptr);
44  _lock.lock();
45  // We need to check again whether the object is deleted after grabbing the
46  // lock, despite having already done this in weakPointerTo.I, since it may
47  // have been deleted in the meantime.
48  bool deleted = was_deleted();
49  if (!deleted) {
50  _callbacks.insert(std::make_pair(callback, data));
51  }
52  _lock.unlock();
53 
54  if (deleted) {
55  callback->wp_callback(data);
56  }
57 }
58 
59 /**
60  * Intended to be called only by WeakPointerTo (or by any class implementing a
61  * weak reference-counting pointer), this removes the indicated PointerToVoid
62  * structure from the list of such structures that are maintaining a weak
63  * pointer to this object.
64  */
67  nassertv(callback != nullptr);
68  _lock.lock();
69  _callbacks.erase(callback);
70  _lock.unlock();
71 }
72 
73 /**
74  * Called only by the ReferenceCount pointer to indicate that it has been
75  * deleted.
76  */
77 void WeakReferenceList::
78 mark_deleted() {
79  _lock.lock();
80  Callbacks::iterator ci;
81  for (ci = _callbacks.begin(); ci != _callbacks.end(); ++ci) {
82  (*ci).first->wp_callback((*ci).second);
83  }
84  _callbacks.clear();
85 
86  // Decrement the special offset added to the weak pointer count to indicate
87  // that it can be deleted when all the weak references have gone.
88  AtomicAdjust::Integer result = AtomicAdjust::add(_count, -_alive_offset);
89  _lock.unlock();
90  if (result == 0) {
91  // There are no weak references remaining either, so delete this.
92  delete this;
93  }
94  nassertv(result >= 0);
95 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_callback(WeakPointerCallback *callback, void *data)
Adds the callback to the list of callbacks that will be called when the underlying pointer is deleted...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool was_deleted() const
Returns true if the object represented has been deleted, ie.
Derive from this class and override the callback() method if you want to get an immediate callback fr...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
~WeakReferenceList()
The destructor tells all of the owned references that we're gone.
void remove_callback(WeakPointerCallback *callback)
Intended to be called only by WeakPointerTo (or by any class implementing a weak reference-counting p...
static ALWAYS_INLINE Integer add(Integer &var, Integer delta)
Atomically computes var += delta.