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 
68 protected:
69  bool do_test_ref_count_integrity() const;
70  bool do_test_ref_count_nonzero() const;
71 
72 private:
73  void create_weak_list();
74 
75 private:
76  enum {
77  // We use this value as a flag to indicate an object has been indicated as
78  // a local object, and should not be deleted except by its own destructor.
79  // Really, any nonzero value would do, but having a large specific number
80  // makes the sanity checks easier.
81  local_ref_count = 10000000,
82 
83  // This value is used as a flag to indicate that an object has just been
84  // deleted, and you're looking at deallocated memory. It's not guaranteed
85  // to stick around, of course (since the deleted memory might be
86  // repurposed for anything else, including a new object), but if you ever
87  // do encounter this value in a reference count field, you screwed up.
88  deleted_ref_count = -100,
89  };
90 
91  mutable AtomicAdjust::Integer _ref_count;
92  AtomicAdjust::Pointer _weak_list; // WeakReferenceList *
93 
94 public:
95  static TypeHandle get_class_type() {
96  return _type_handle;
97  }
98  static void init_type() {
99  register_type(_type_handle, "ReferenceCount");
100  }
101 
102 private:
103  static TypeHandle _type_handle;
104 };
105 
106 template<class RefCountType>
107 INLINE void unref_delete(RefCountType *ptr);
108 
109 /**
110  * A "proxy" to use to make a reference-countable object whenever the object
111  * cannot inherit from ReferenceCount for some reason. RefCountPr<MyClass>
112  * can be treated as an instance of MyClass directly, for the most part,
113  * except that it can be reference counted.
114  *
115  * If you want to declare a RefCountProxy to something that does not have
116  * get_class_type(), you will have to define a template specialization on
117  * _get_type_handle() and _do_init_type(), as in typedObject.h.
118  */
119 template<class Base>
121 public:
122  INLINE RefCountProxy();
123  INLINE RefCountProxy(const Base &copy);
124 
125  INLINE operator Base &();
126  INLINE operator const Base &() const;
127 
128  static TypeHandle get_class_type() {
129  return _type_handle;
130  }
131  static void init_type();
132 
133 private:
134  Base _base;
135  static TypeHandle _type_handle;
136 };
137 
138 
139 /**
140  * Another kind of proxy, similar to RefCountProxy. This one works by
141  * inheriting from the indicated base type, giving it an is-a relation instead
142  * of a has-a relation. As such, it's a little more robust, but only works
143  * when the base type is, in fact, a class.
144  */
145 template<class Base>
146 class RefCountObj : public ReferenceCount, public Base {
147 public:
148  INLINE RefCountObj();
149  INLINE RefCountObj(const Base &copy);
150  ALLOC_DELETED_CHAIN(RefCountObj<Base>);
151 
152  static TypeHandle get_class_type() {
153  return _type_handle;
154  }
155  static void init_type();
156 
157 private:
158  static TypeHandle _type_handle;
159 };
160 
161 #include "referenceCount.I"
162 
163 #endif
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 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.
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.
This class is intended to be the base class of all objects in Panda that might be allocated and delet...
Definition: memoryBase.h:69
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A base class for all things that want to be reference-counted.
Another kind of proxy, similar to RefCountProxy.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A "proxy" to use to make a reference-countable object whenever the object cannot inherit from Referen...