Panda3D
 All Classes Functions Variables Enumerations
referenceCount.h
00001 // Filename: referenceCount.h
00002 // Created by:  drose (23Oct98)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef REFERENCECOUNT_H
00016 #define REFERENCECOUNT_H
00017 
00018 #include "pandabase.h"
00019 #include "weakReferenceList.h"
00020 #include "typedObject.h"
00021 #include "memoryUsage.h"
00022 #include "memoryBase.h"
00023 #include "config_express.h"
00024 #include "atomicAdjust.h"
00025 #include "numeric_types.h"
00026 #include "deletedChain.h"
00027 
00028 #include <stdlib.h>
00029 
00030 #ifdef HAVE_RTTI
00031 #include <typeinfo>
00032 #endif
00033 
00034 ////////////////////////////////////////////////////////////////////
00035 //       Class : ReferenceCount
00036 // Description : A base class for all things that want to be
00037 //               reference-counted.  ReferenceCount works in
00038 //               conjunction with PointerTo to automatically delete
00039 //               objects when the last pointer to them goes away.
00040 ////////////////////////////////////////////////////////////////////
00041 class EXPCL_PANDAEXPRESS ReferenceCount : public MemoryBase {
00042 protected:
00043   INLINE ReferenceCount();
00044   INLINE ReferenceCount(const ReferenceCount &);
00045   INLINE void operator = (const ReferenceCount &);
00046 
00047 public:
00048   virtual INLINE ~ReferenceCount();
00049 
00050 PUBLISHED:
00051   INLINE int get_ref_count() const;
00052   INLINE void ref() const;
00053   virtual INLINE bool unref() const;
00054 
00055   INLINE bool test_ref_count_integrity() const;
00056   INLINE bool test_ref_count_nonzero() const;
00057 
00058 public:
00059   INLINE void local_object();
00060   INLINE bool has_weak_list() const;
00061   INLINE WeakReferenceList *get_weak_list() const;
00062 
00063   INLINE void weak_ref(WeakPointerToVoid *ptv);
00064   INLINE void weak_unref(WeakPointerToVoid *ptv);
00065 
00066 protected:
00067   bool do_test_ref_count_integrity() const;
00068   bool do_test_ref_count_nonzero() const;
00069 
00070 private:
00071   void create_weak_list();
00072 
00073 private:
00074   enum { 
00075     // We use this value as a flag to indicate an object has been
00076     // indicated as a local object, and should not be deleted except
00077     // by its own destructor.  Really, any nonzero value would do, but
00078     // having a large specific number makes the sanity checks easier.
00079     local_ref_count = 10000000,
00080 
00081     // This value is used as a flag to indicate that an object has
00082     // just been deleted, and you're looking at deallocated memory.
00083     // It's not guaranteed to stick around, of course (since the
00084     // deleted memory might be repurposed for anything else, including
00085     // a new object), but if you ever do encounter this value in a
00086     // reference count field, you screwed up.
00087     deleted_ref_count = -100,
00088   };
00089 
00090   AtomicAdjust::Integer _ref_count;
00091   AtomicAdjust::Pointer _weak_list;  // WeakReferenceList *
00092 
00093 public:
00094   static TypeHandle get_class_type() {
00095     return _type_handle;
00096   }
00097   static void init_type() {
00098     register_type(_type_handle, "ReferenceCount");
00099   }
00100 
00101 private:
00102   static TypeHandle _type_handle;
00103 };
00104 
00105 template<class RefCountType>
00106 INLINE void unref_delete(RefCountType *ptr);
00107 
00108 ////////////////////////////////////////////////////////////////////
00109 //       Class : RefCountProxy
00110 // Description : A "proxy" to use to make a reference-countable object
00111 //               whenever the object cannot inherit from
00112 //               ReferenceCount for some reason.  RefCountPr<MyClass>
00113 //               can be treated as an instance of MyClass directly,
00114 //               for the most part, except that it can be reference
00115 //               counted.
00116 //
00117 //               If you want to declare a RefCountProxy to something
00118 //               that does not have get_class_type(), you will have to
00119 //               define a template specialization on
00120 //               _get_type_handle() and _do_init_type(), as in
00121 //               typedObject.h.
00122 ////////////////////////////////////////////////////////////////////
00123 template<class Base>
00124 class RefCountProxy : public ReferenceCount {
00125 public:
00126   INLINE RefCountProxy();
00127   INLINE RefCountProxy(const Base &copy);
00128 
00129   INLINE operator Base &();
00130   INLINE operator const Base &() const;
00131 
00132   static TypeHandle get_class_type() {
00133     return _type_handle;
00134   }
00135   static void init_type();
00136 
00137 private:
00138   Base _base;
00139   static TypeHandle _type_handle;
00140 };
00141 
00142 
00143 ////////////////////////////////////////////////////////////////////
00144 //       Class : RefCountObj
00145 // Description : Another kind of proxy, similar to RefCountProxy.
00146 //               This one works by inheriting from the indicated base
00147 //               type, giving it an is-a relation instead of a has-a
00148 //               relation.  As such, it's a little more robust, but
00149 //               only works when the base type is, in fact, a class.
00150 ////////////////////////////////////////////////////////////////////
00151 template<class Base>
00152 class RefCountObj : public ReferenceCount, public Base {
00153 public:
00154   INLINE RefCountObj();
00155   INLINE RefCountObj(const Base &copy);
00156   ALLOC_DELETED_CHAIN(RefCountObj<Base>);
00157 
00158   static TypeHandle get_class_type() {
00159     return _type_handle;
00160   }
00161   static void init_type();
00162 
00163 private:
00164   static TypeHandle _type_handle;
00165 };
00166 
00167 #include "referenceCount.I"
00168 
00169 #endif
 All Classes Functions Variables Enumerations