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  *
41  * @since 1.10.0
42  */
44 add_callback(WeakPointerCallback *callback, void *data) {
45  nassertv(callback != nullptr);
46  _lock.lock();
47  // We need to check again whether the object is deleted after grabbing the
48  // lock, despite having already done this in weakPointerTo.I, since it may
49  // have been deleted in the meantime.
50  bool deleted = was_deleted();
51  if (!deleted) {
52  _callbacks.insert(std::make_pair(callback, data));
53  }
54  _lock.unlock();
55 
56  if (deleted) {
57  callback->wp_callback(data);
58  }
59 }
60 
61 /**
62  * Intended to be called only by WeakPointerTo (or by any class implementing a
63  * weak reference-counting pointer), this removes the indicated PointerToVoid
64  * structure from the list of such structures that are maintaining a weak
65  * pointer to this object.
66  *
67  * @since 1.10.0
68  */
71  nassertv(callback != nullptr);
72  _lock.lock();
73  _callbacks.erase(callback);
74  _lock.unlock();
75 }
76 
77 /**
78  * Called only by the ReferenceCount pointer to indicate that it has been
79  * deleted.
80  *
81  * @since 1.10.0
82  */
83 void WeakReferenceList::
84 mark_deleted() {
85  _lock.lock();
86  Callbacks::iterator ci;
87  for (ci = _callbacks.begin(); ci != _callbacks.end(); ++ci) {
88  (*ci).first->wp_callback((*ci).second);
89  }
90  _callbacks.clear();
91 
92  // Decrement the special offset added to the weak pointer count to indicate
93  // that it can be deleted when all the weak references have gone.
94  AtomicAdjust::Integer result = AtomicAdjust::add(_count, -_alive_offset);
95  _lock.unlock();
96  if (result == 0) {
97  // There are no weak references remaining either, so delete this.
98  delete this;
99  }
100  nassertv(result >= 0);
101 }
static Integer add(Integer &var, Integer delta)
Atomically computes var += delta.
Derive from this class and override the callback() method if you want to get an immediate callback fr...
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...
bool was_deleted() const
Returns true if the object represented has been deleted, ie.
~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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.