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 }
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.
static Integer add(Integer &var, Integer delta)
Atomically computes var += delta.
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...