Panda3D
referenceCount.h
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 referenceCount.h
10  * @author drose
11  * @date 1998-10-23
12  */
13 
14 #ifndef REFERENCECOUNT_H
15 #define REFERENCECOUNT_H
16 
17 #include "pandabase.h"
18 #include "weakReferenceList.h"
19 #include "typedObject.h"
20 #include "memoryUsage.h"
21 #include "memoryBase.h"
22 #include "config_express.h"
23 #include "atomicAdjust.h"
24 #include "numeric_types.h"
25 #include "deletedChain.h"
26 
27 #include <stdlib.h>
28 
29 #ifdef HAVE_RTTI
30 #include <typeinfo>
31 #endif
32 
33 /**
34  * A base class for all things that want to be reference-counted.
35  * ReferenceCount works in conjunction with PointerTo to automatically delete
36  * objects when the last pointer to them goes away.
37  */
38 class EXPCL_PANDA_EXPRESS ReferenceCount : public MemoryBase {
39 protected:
40  INLINE ReferenceCount();
41  INLINE ReferenceCount(const ReferenceCount &);
42  INLINE void operator = (const ReferenceCount &);
43 
44 public:
45  virtual INLINE ~ReferenceCount();
46 
47 PUBLISHED:
48  INLINE int get_ref_count() const;
49  INLINE void ref() const;
50  virtual INLINE bool unref() const;
51 
52  // The current reference count.
53  MAKE_PROPERTY(ref_count, get_ref_count);
54 
55  INLINE bool test_ref_count_integrity() const;
56  INLINE bool test_ref_count_nonzero() const;
57 
58 public:
59  INLINE void local_object();
60  INLINE bool has_weak_list() const;
61  INLINE WeakReferenceList *get_weak_list() const;
62 
63  INLINE WeakReferenceList *weak_ref();
64  INLINE void weak_unref();
65 
66  INLINE bool ref_if_nonzero() const;
67  INLINE bool unref_if_one() const;
68 
69 protected:
70  bool do_test_ref_count_integrity() const;
71  bool do_test_ref_count_nonzero() const;
72 
73 private:
74  void create_weak_list();
75 
76 private:
77  enum {
78  // We use this value as a flag to indicate an object has been indicated as
79  // a local object, and should not be deleted except by its own destructor.
80  // Really, any nonzero value would do, but having a large specific number
81  // makes the sanity checks easier.
82  local_ref_count = 10000000,
83 
84  // This value is used as a flag to indicate that an object has just been
85  // deleted, and you're looking at deallocated memory. It's not guaranteed
86  // to stick around, of course (since the deleted memory might be
87  // repurposed for anything else, including a new object), but if you ever
88  // do encounter this value in a reference count field, you screwed up.
89  deleted_ref_count = -100,
90  };
91 
92  mutable AtomicAdjust::Integer _ref_count;
93  AtomicAdjust::Pointer _weak_list; // WeakReferenceList *
94 
95 public:
96  static TypeHandle get_class_type() {
97  return _type_handle;
98  }
99  static void init_type() {
100  register_type(_type_handle, "ReferenceCount");
101  }
102 
103 private:
104  static TypeHandle _type_handle;
105 };
106 
107 template<class RefCountType>
108 INLINE void unref_delete(RefCountType *ptr);
109 
110 /**
111  * A "proxy" to use to make a reference-countable object whenever the object
112  * cannot inherit from ReferenceCount for some reason. RefCountPr<MyClass>
113  * can be treated as an instance of MyClass directly, for the most part,
114  * except that it can be reference counted.
115  *
116  * If you want to declare a RefCountProxy to something that does not have
117  * get_class_type(), you will have to define a template specialization on
118  * _get_type_handle() and _do_init_type(), as in typedObject.h.
119  */
120 template<class Base>
122 public:
123  INLINE RefCountProxy();
124  INLINE RefCountProxy(const Base &copy);
125 
126  INLINE operator Base &();
127  INLINE operator const Base &() const;
128 
129  static TypeHandle get_class_type() {
130  return _type_handle;
131  }
132  static void init_type();
133 
134 private:
135  Base _base;
136  static TypeHandle _type_handle;
137 };
138 
139 
140 /**
141  * Another kind of proxy, similar to RefCountProxy. This one works by
142  * inheriting from the indicated base type, giving it an is-a relation instead
143  * of a has-a relation. As such, it's a little more robust, but only works
144  * when the base type is, in fact, a class.
145  */
146 template<class Base>
147 class RefCountObj : public ReferenceCount, public Base {
148 public:
149  INLINE RefCountObj();
150  INLINE RefCountObj(const Base &copy);
151  ALLOC_DELETED_CHAIN(RefCountObj<Base>);
152 
153  static TypeHandle get_class_type() {
154  return _type_handle;
155  }
156  static void init_type();
157 
158 private:
159  static TypeHandle _type_handle;
160 };
161 
162 #include "referenceCount.I"
163 
164 #endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class is intended to be the base class of all objects in Panda that might be allocated and delet...
Definition: memoryBase.h:65
Another kind of proxy, similar to RefCountProxy.
A "proxy" to use to make a reference-countable object whenever the object cannot inherit from Referen...
A base class for all things that want to be reference-counted.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
This is an object shared by all the weak pointers that point to the same ReferenceCount object.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.