From 5779007507daeb54c145f1b7652da807d0b75772 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 24 Nov 2006 22:59:44 +0000 Subject: [PATCH] more memory tracking stuff --- dtool/src/dtoolbase/Sources.pp | 16 +- dtool/src/dtoolbase/deletedChain.T | 41 +++- dtool/src/dtoolbase/deletedChain.h | 10 +- dtool/src/dtoolbase/dtoolbase_composite1.cxx | 1 + dtool/src/dtoolbase/dtoolbase_composite2.cxx | 6 +- dtool/src/dtoolbase/pallocator.T | 25 ++- dtool/src/dtoolbase/pallocator.h | 15 +- dtool/src/dtoolbase/pdeque.h | 10 +- dtool/src/dtoolbase/plist.h | 21 +- dtool/src/dtoolbase/pmap.h | 15 +- dtool/src/dtoolbase/pset.h | 15 +- dtool/src/dtoolbase/pvector.h | 12 +- .../register_type.I | 0 .../register_type.cxx | 16 ++ .../register_type.h | 34 +++- .../{interrogatedb => dtoolbase}/typeHandle.I | 0 dtool/src/dtoolbase/typeHandle.cxx | 102 ++++++++++ .../{interrogatedb => dtoolbase}/typeHandle.h | 21 +- .../typeRegistry.I | 0 .../typeRegistry.cxx | 183 ++++++++---------- .../typeRegistry.h | 20 +- .../typeRegistryNode.I | 6 +- .../typeRegistryNode.cxx | 28 +-- .../typeRegistryNode.h | 12 +- .../typedObject.I | 0 .../typedObject.cxx | 4 +- .../typedObject.h | 2 +- dtool/src/dtoolutil/Sources.pp | 3 + dtool/src/dtoolutil/config_dtoolutil.cxx | 51 +++++ .../config_dtoolutil.h} | 12 +- dtool/src/dtoolutil/dtoolutil_composite1.cxx | 2 +- dtool/src/dtoolutil/filename.cxx | 1 + dtool/src/dtoolutil/filename.h | 14 +- dtool/src/dtoolutil/pandaSystem.cxx | 9 +- dtool/src/dtoolutil/pandaSystem.h | 11 ++ dtool/src/interrogatedb/Sources.pp | 16 +- .../interrogatedb_composite2.cxx | 5 - dtool/src/prc/configVariableCore.cxx | 2 +- panda/src/display/config_display.cxx | 1 + panda/src/display/displayRegion.cxx | 1 + panda/src/display/displayRegion.h | 11 ++ panda/src/gobj/config_gobj.cxx | 6 + panda/src/gobj/geom.cxx | 4 + panda/src/gobj/geom.h | 47 +++++ panda/src/gobj/geomPrimitive.cxx | 2 + panda/src/gobj/geomPrimitive.h | 23 +++ panda/src/gobj/geomVertexArrayData.cxx | 3 + panda/src/gobj/geomVertexArrayData.h | 34 ++++ panda/src/gobj/geomVertexData.cxx | 5 + panda/src/gobj/geomVertexData.h | 58 ++++++ panda/src/pgraph/config_pgraph.cxx | 4 +- panda/src/pgraph/findApproxLevelEntry.cxx | 2 + panda/src/pgraph/findApproxLevelEntry.h | 11 ++ panda/src/pgraph/nodePathComponent.cxx | 1 + panda/src/pgraph/nodePathComponent.h | 12 ++ panda/src/pgraph/pandaNode.cxx | 2 + panda/src/pgraph/pandaNode.h | 23 +++ panda/src/pnmimage/pnmFileTypeRegistry.h | 2 + panda/src/pnmimage/pnmImageHeader.h | 3 + panda/src/pstatclient/pStatClient.cxx | 56 +++++- panda/src/pstatclient/pStatCollector.I | 44 +++-- panda/src/pstatclient/pStatCollector.h | 6 +- panda/src/putil/bitMask.h | 1 + 63 files changed, 851 insertions(+), 252 deletions(-) rename dtool/src/{interrogatedb => dtoolbase}/register_type.I (100%) rename dtool/src/{interrogatedb => dtoolbase}/register_type.cxx (77%) rename dtool/src/{interrogatedb => dtoolbase}/register_type.h (88%) rename dtool/src/{interrogatedb => dtoolbase}/typeHandle.I (100%) create mode 100644 dtool/src/dtoolbase/typeHandle.cxx rename dtool/src/{interrogatedb => dtoolbase}/typeHandle.h (90%) rename dtool/src/{interrogatedb => dtoolbase}/typeRegistry.I (100%) rename dtool/src/{interrogatedb => dtoolbase}/typeRegistry.cxx (86%) rename dtool/src/{interrogatedb => dtoolbase}/typeRegistry.h (89%) rename dtool/src/{interrogatedb => dtoolbase}/typeRegistryNode.I (96%) rename dtool/src/{interrogatedb => dtoolbase}/typeRegistryNode.cxx (95%) rename dtool/src/{interrogatedb => dtoolbase}/typeRegistryNode.h (93%) rename dtool/src/{interrogatedb => dtoolbase}/typedObject.I (100%) rename dtool/src/{interrogatedb => dtoolbase}/typedObject.cxx (96%) rename dtool/src/{interrogatedb => dtoolbase}/typedObject.h (99%) create mode 100644 dtool/src/dtoolutil/config_dtoolutil.cxx rename dtool/src/{interrogatedb/typeHandle.cxx => dtoolutil/config_dtoolutil.h} (78%) diff --git a/dtool/src/dtoolbase/Sources.pp b/dtool/src/dtoolbase/Sources.pp index db41d6667e..fb06ab4023 100644 --- a/dtool/src/dtoolbase/Sources.pp +++ b/dtool/src/dtoolbase/Sources.pp @@ -29,8 +29,13 @@ mutexSpinlockImpl.h mutexSpinlockImpl.I \ nearly_zero.h \ numeric_types.h \ + register_type.I register_type.h \ selectThreadImpl.h \ stl_compares.I stl_compares.h \ + typeHandle.I typeHandle.h \ + typeRegistry.I typeRegistry.h \ + typeRegistryNode.I typeRegistryNode.h \ + typedObject.I typedObject.h \ pallocator.T pallocator.h \ pdeque.h plist.h pmap.h pset.h pvector.h \ dlmalloc.c lookup3.h lookup3.c @@ -49,7 +54,11 @@ mutexLinuxImpl.cxx \ mutexPosixImpl.cxx \ mutexWin32Impl.cxx \ - mutexSpinlockImpl.cxx + mutexSpinlockImpl.cxx \ + register_type.cxx \ + typeHandle.cxx \ + typeRegistry.cxx typeRegistryNode.cxx \ + typedObject.cxx #define INSTALL_HEADERS \ addHash.I addHash.h \ @@ -74,8 +83,13 @@ mutexSpinlockImpl.h mutexSpinlockImpl.I \ nearly_zero.h \ numeric_types.h \ + register_type.I register_type.h \ selectThreadImpl.h \ stl_compares.I stl_compares.h \ + typeHandle.I typeHandle.h \ + typeRegistry.I typeRegistry.h \ + typeRegistryNode.I typeRegistryNode.h \ + typedObject.I typedObject.h \ pallocator.T pallocator.h \ pdeque.h plist.h pmap.h pset.h pvector.h \ lookup3.h diff --git a/dtool/src/dtoolbase/deletedChain.T b/dtool/src/dtoolbase/deletedChain.T index 230fd0e821..a6b541e70b 100644 --- a/dtool/src/dtoolbase/deletedChain.T +++ b/dtool/src/dtoolbase/deletedChain.T @@ -31,16 +31,27 @@ MutexImpl *DeletedChain::_lock; //////////////////////////////////////////////////////////////////// template INLINE Type *DeletedChain:: -allocate(size_t size) { - TAU_PROFILE("Type *DeletedChain::allocate(size_t)", " ", TAU_USER); +allocate(size_t size, TypeHandle type_handle) { + TAU_PROFILE("Type *DeletedChain::allocate(size_t, TypeHandle)", " ", TAU_USER); assert(size <= sizeof(Type)); + size_t alloc_size = sizeof(Type); +#ifdef USE_DELETEDCHAINFLAG + // In development mode, we also need to reserve space for _flag. + alloc_size += sizeof(PN_int32); +#endif // NDEBUG + TVOLATILE ObjectNode *obj; #ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE init_lock(); _lock->lock(); if (_deleted_chain != (ObjectNode *)NULL) { +#ifdef DO_MEMORY_USAGE + type_handle.dec_memory_usage(TypeHandle::MC_deleted_chain_inactive, alloc_size); + type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size); +#endif // DO_MEMORY_USAGE + obj = _deleted_chain; _deleted_chain = _deleted_chain->_next; _lock->release(); @@ -59,6 +70,10 @@ allocate(size_t size) { TVOLATILE ObjectNode *result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_deleted_chain, (void *)obj, (void *)next); if (result == obj) { // We got it. +#ifdef DO_MEMORY_USAGE + type_handle.dec_memory_usage(TypeHandle::MC_deleted_chain_inactive, alloc_size); + type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size); +#endif // DO_MEMORY_USAGE #ifdef USE_DELETEDCHAINFLAG PN_int32 orig_flag = AtomicAdjust::compare_and_exchange(obj->_flag, DCF_deleted, DCF_alive); assert(orig_flag == (PN_int32)DCF_deleted); @@ -74,11 +89,9 @@ allocate(size_t size) { // If we get here, the deleted_chain is empty; we have to allocate a // new object from the system pool. - size_t alloc_size = sizeof(Type); -#ifdef USE_DELETEDCHAINFLAG - // In development mode, we also need to reserve space for _flag. - alloc_size += sizeof(PN_int32); -#endif // NDEBUG +#ifdef DO_MEMORY_USAGE + type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size); +#endif // DO_MEMORY_USAGE size = max(alloc_size, sizeof(ObjectNode)); #ifdef DO_MEMORY_USAGE @@ -100,10 +113,20 @@ allocate(size_t size) { //////////////////////////////////////////////////////////////////// template INLINE void DeletedChain:: -deallocate(Type *ptr) { - TAU_PROFILE("void DeletedChain::deallocate(Type *)", " ", TAU_USER); +deallocate(Type *ptr, TypeHandle type_handle) { + TAU_PROFILE("void DeletedChain::deallocate(Type *, TypeHandle)", " ", TAU_USER); assert(ptr != (Type *)NULL); +#ifdef DO_MEMORY_USAGE + size_t alloc_size = sizeof(Type); +#ifdef USE_DELETEDCHAINFLAG + // In development mode, we also need to reserve space for _flag. + alloc_size += sizeof(PN_int32); +#endif // NDEBUG + type_handle.dec_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size); + type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_inactive, alloc_size); +#endif // DO_MEMORY_USAGE + TVOLATILE ObjectNode *obj = type_to_node(ptr); #ifdef USE_DELETEDCHAINFLAG diff --git a/dtool/src/dtoolbase/deletedChain.h b/dtool/src/dtoolbase/deletedChain.h index 7b9f3de15b..731ab1b06a 100644 --- a/dtool/src/dtoolbase/deletedChain.h +++ b/dtool/src/dtoolbase/deletedChain.h @@ -24,6 +24,8 @@ #include "mutexImpl.h" #include "atomicAdjust.h" #include "numeric_types.h" +#include "register_type.h" +#include "typeHandle.h" #include #ifdef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR @@ -80,8 +82,8 @@ enum DeletedChainFlag { template class DeletedChain { public: - INLINE static Type *allocate(size_t size); - INLINE static void deallocate(Type *ptr); + INLINE static Type *allocate(size_t size, TypeHandle type_handle); + INLINE static void deallocate(Type *ptr, TypeHandle type_handle); private: class ObjectNode { @@ -124,13 +126,13 @@ private: // DeletedChain. #define ALLOC_DELETED_CHAIN(Type) \ inline void *operator new(size_t size) { \ - return (void *)DeletedChain< Type >::allocate(size); \ + return (void *)DeletedChain< Type >::allocate(size, get_type_handle(Type)); \ } \ inline void *operator new(size_t size, void *ptr) { \ return ptr; \ } \ inline void operator delete(void *ptr) { \ - DeletedChain< Type >::deallocate((Type *)ptr); \ + DeletedChain< Type >::deallocate((Type *)ptr, get_type_handle(Type)); \ } \ inline void operator delete(void *, void *) { \ } diff --git a/dtool/src/dtoolbase/dtoolbase_composite1.cxx b/dtool/src/dtoolbase/dtoolbase_composite1.cxx index c49607c22f..225d6f5163 100644 --- a/dtool/src/dtoolbase/dtoolbase_composite1.cxx +++ b/dtool/src/dtoolbase/dtoolbase_composite1.cxx @@ -5,3 +5,4 @@ #include "atomicAdjustPosixImpl.cxx" #include "atomicAdjustWin32Impl.cxx" #include "dtoolbase.cxx" +#include "memoryBase.cxx" diff --git a/dtool/src/dtoolbase/dtoolbase_composite2.cxx b/dtool/src/dtoolbase/dtoolbase_composite2.cxx index aa04bbfe7a..b22b54018c 100644 --- a/dtool/src/dtoolbase/dtoolbase_composite2.cxx +++ b/dtool/src/dtoolbase/dtoolbase_composite2.cxx @@ -1,7 +1,11 @@ -#include "memoryBase.cxx" #include "mutexDummyImpl.cxx" #include "mutexNsprImpl.cxx" #include "mutexLinuxImpl.cxx" #include "mutexPosixImpl.cxx" #include "mutexWin32Impl.cxx" #include "mutexSpinlockImpl.cxx" +#include "register_type.cxx" +#include "typeHandle.cxx" +#include "typeRegistry.cxx" +#include "typeRegistryNode.cxx" +#include "typedObject.cxx" diff --git a/dtool/src/dtoolbase/pallocator.T b/dtool/src/dtoolbase/pallocator.T index 891b53b93f..c32c1b0d2b 100644 --- a/dtool/src/dtoolbase/pallocator.T +++ b/dtool/src/dtoolbase/pallocator.T @@ -18,7 +18,9 @@ template INLINE pallocator_single:: -pallocator_single() throw() { +pallocator_single(TypeHandle type_handle) throw() : + _type_handle(type_handle) +{ } template @@ -27,19 +29,21 @@ allocate(TYPENAME pallocator_single::size_type n, TYPENAME allocator TAU_PROFILE("pallocator_single:allocate()", " ", TAU_USER); // This doesn't support allocating arrays. assert(n == 1); - return DeletedChain::allocate(sizeof(Type)); + return DeletedChain::allocate(sizeof(Type), _type_handle); } template INLINE void pallocator_single:: deallocate(TYPENAME pallocator_single::pointer p, TYPENAME pallocator_single::size_type) { TAU_PROFILE("pallocator_single:deallocate()", " ", TAU_USER); - return DeletedChain::deallocate(p); + return DeletedChain::deallocate(p, _type_handle); } template INLINE pallocator_array:: -pallocator_array() throw() { +pallocator_array(TypeHandle type_handle) throw() : + _type_handle(type_handle) +{ } template @@ -47,7 +51,13 @@ INLINE TYPENAME pallocator_array::pointer pallocator_array:: allocate(TYPENAME pallocator_array::size_type n, TYPENAME allocator::const_pointer) { TAU_PROFILE("pallocator_array:allocate()", " ", TAU_USER); #ifdef DO_MEMORY_USAGE - return (TYPENAME pallocator_array::pointer)(*global_operator_new)(n * sizeof(Type)); + size_t alloc_size = n * sizeof(Type); + // We also need to store the total number of bytes we allocated. + alloc_size += sizeof(size_t); + _type_handle.inc_memory_usage(TypeHandle::MC_array, alloc_size); + void *ptr = (TYPENAME pallocator_array::pointer)(*global_operator_new)(alloc_size); + *((size_t *)ptr) = alloc_size; + return (TYPENAME pallocator_array::pointer)(((size_t *)ptr) + 1); #else return (TYPENAME pallocator_array::pointer)malloc(n * sizeof(Type)); #endif // DO_MEMORY_USAGE @@ -58,7 +68,10 @@ INLINE void pallocator_array:: deallocate(TYPENAME pallocator_array::pointer p, TYPENAME pallocator_array::size_type) { TAU_PROFILE("pallocator_array:deallocate()", " ", TAU_USER); #ifdef DO_MEMORY_USAGE - (*global_operator_delete)(p); + // Now we need to recover the total number of bytes. + size_t alloc_size = *(((size_t *)p) - 1); + _type_handle.dec_memory_usage(TypeHandle::MC_array, alloc_size); + (*global_operator_delete)(((size_t *)p) - 1); #else free(p); #endif // DO_MEMORY_USAGE diff --git a/dtool/src/dtoolbase/pallocator.h b/dtool/src/dtoolbase/pallocator.h index aa3d4972f5..b354f9e73b 100644 --- a/dtool/src/dtoolbase/pallocator.h +++ b/dtool/src/dtoolbase/pallocator.h @@ -22,6 +22,7 @@ #include #include "dtoolbase.h" #include "deletedChain.h" +#include "typeHandle.h" //////////////////////////////////////////////////////////////////// // Class : pallocator @@ -59,11 +60,12 @@ public: typedef TYPENAME allocator::const_reference const_reference; typedef TYPENAME allocator::size_type size_type; - INLINE pallocator_single() throw(); + INLINE pallocator_single(TypeHandle type_handle) throw(); // template member functions in VC++ can only be defined in-class. template - INLINE pallocator_single(const pallocator_single &) throw() { } + INLINE pallocator_single(const pallocator_single ©) throw() : + _type_handle(copy._type_handle) { } INLINE pointer allocate(size_type n, allocator::const_pointer hint = 0); INLINE void deallocate(pointer p, size_type n); @@ -71,6 +73,8 @@ public: template struct rebind { typedef pallocator_single other; }; + + TypeHandle _type_handle; }; template @@ -84,11 +88,12 @@ public: typedef TYPENAME allocator::const_reference const_reference; typedef TYPENAME allocator::size_type size_type; - INLINE pallocator_array() throw(); + INLINE pallocator_array(TypeHandle type_handle) throw(); // template member functions in VC++ can only be defined in-class. template - INLINE pallocator_array(const pallocator_array &) throw() { } + INLINE pallocator_array(const pallocator_array ©) throw() : + _type_handle(copy._type_handle) { } INLINE pointer allocate(size_type n, allocator::const_pointer hint = 0); INLINE void deallocate(pointer p, size_type n); @@ -96,6 +101,8 @@ public: template struct rebind { typedef pallocator_array other; }; + + TypeHandle _type_handle; }; #include "pallocator.T" diff --git a/dtool/src/dtoolbase/pdeque.h b/dtool/src/dtoolbase/pdeque.h index 60de0e9230..9d7ea45c3e 100644 --- a/dtool/src/dtoolbase/pdeque.h +++ b/dtool/src/dtoolbase/pdeque.h @@ -21,6 +21,7 @@ #include "dtoolbase.h" #include "pallocator.h" +#include "register_type.h" #include #ifndef USE_STL_ALLOCATOR @@ -40,11 +41,12 @@ template class pdeque : public deque > { public: - typedef TYPENAME deque >::size_type size_type; - pdeque() : deque >() { } + typedef pallocator_array allocator; + typedef TYPENAME deque::size_type size_type; + pdeque(TypeHandle type_handle = pdeque_type_handle) : deque >(allocator(type_handle)) { } pdeque(const pdeque ©) : deque >(copy) { } - pdeque(size_type n) : deque >(n) { } - pdeque(size_type n, const Type &value) : deque >(n, value) { } + pdeque(size_type n, TypeHandle type_handle = pdeque_type_handle) : deque >(n, Type(), allocator(type_handle)) { } + pdeque(size_type n, const Type &value, TypeHandle type_handle = pdeque_type_handle) : deque >(n, value, allocator(type_handle)) { } }; #endif // USE_STL_ALLOCATOR diff --git a/dtool/src/dtoolbase/plist.h b/dtool/src/dtoolbase/plist.h index 7fe4811290..b0001453ef 100644 --- a/dtool/src/dtoolbase/plist.h +++ b/dtool/src/dtoolbase/plist.h @@ -21,6 +21,7 @@ #include "dtoolbase.h" #include "pallocator.h" +#include "register_type.h" #include #ifndef USE_STL_ALLOCATOR @@ -40,16 +41,18 @@ template class plist : public list > { public: - typedef TYPENAME list >::size_type size_type; - plist() : list >() { } - plist(const plist ©) : list >(copy) { } - plist(size_type n) : list >(n) { } - plist(size_type n, const Type &value) : list >(n, value) { } + typedef pallocator_single allocator; + typedef list base_class; + typedef TYPENAME base_class::size_type size_type; + plist(TypeHandle type_handle = plist_type_handle) : base_class(allocator(type_handle)) { } + plist(const plist ©) : base_class(copy) { } + plist(size_type n, TypeHandle type_handle = plist_type_handle) : base_class(n, Type(), allocator(type_handle)) { } + plist(size_type n, const Type &value, TypeHandle type_handle = plist_type_handle) : base_class(n, value, allocator(type_handle)) { } - typedef TYPENAME list >::iterator iterator; - typedef TYPENAME list >::const_iterator const_iterator; - typedef TYPENAME list >::reverse_iterator reverse_iterator; - typedef TYPENAME list >::const_reverse_iterator const_reverse_iterator; + typedef TYPENAME base_class::iterator iterator; + typedef TYPENAME base_class::const_iterator const_iterator; + typedef TYPENAME base_class::reverse_iterator reverse_iterator; + typedef TYPENAME base_class::const_reverse_iterator const_reverse_iterator; }; #endif // USE_STL_ALLOCATOR diff --git a/dtool/src/dtoolbase/pmap.h b/dtool/src/dtoolbase/pmap.h index 071ca2c111..eba39894bc 100644 --- a/dtool/src/dtoolbase/pmap.h +++ b/dtool/src/dtoolbase/pmap.h @@ -22,6 +22,7 @@ #include "dtoolbase.h" #include "pallocator.h" #include "stl_compares.h" +#include "register_type.h" #include #ifdef HAVE_STL_HASH @@ -54,11 +55,12 @@ template > class pmap : public map > > { public: - typedef map > > base_class; + typedef pallocator_single > allocator; + typedef map base_class; - pmap() : base_class() { } + pmap(TypeHandle type_handle = pmap_type_handle) : base_class(Compare(), allocator(type_handle)) { } pmap(const pmap ©) : base_class(copy) { } - pmap(const Compare &comp) : base_class(comp) { } + pmap(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : base_class(comp, allocator(type_handle)) { } #ifdef USE_TAU TYPENAME base_class::mapped_type & @@ -123,9 +125,10 @@ public: template > class pmultimap : public multimap > > { public: - pmultimap() : multimap > >() { } - pmultimap(const pmultimap ©) : multimap > >(copy) { } - pmultimap(const Compare &comp) : multimap > >(comp) { } + typedef pallocator_single > allocator; + pmultimap(TypeHandle type_handle = pmap_type_handle) : multimap(Compare(), allocator(type_handle)) { } + pmultimap(const pmultimap ©) : multimap(copy) { } + pmultimap(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : multimap(comp, allocator(type_handle)) { } }; #ifdef HAVE_STL_HASH diff --git a/dtool/src/dtoolbase/pset.h b/dtool/src/dtoolbase/pset.h index e01a98a6ee..22f09b6c6f 100644 --- a/dtool/src/dtoolbase/pset.h +++ b/dtool/src/dtoolbase/pset.h @@ -22,6 +22,7 @@ #include "dtoolbase.h" #include "pallocator.h" #include "stl_compares.h" +#include "register_type.h" #include #ifdef HAVE_STL_HASH @@ -54,10 +55,11 @@ template > class pset : public set > { public: - typedef set > base_class; - pset() : base_class() { } + typedef pallocator_single allocator; + typedef set base_class; + pset(TypeHandle type_handle = pmap_type_handle) : base_class(Compare(), allocator(type_handle)) { } pset(const pset ©) : base_class(copy) { } - pset(const Compare &comp) : base_class(comp) { } + pset(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : base_class(comp, type_handle) { } #ifdef USE_TAU std::pair @@ -115,9 +117,10 @@ public: template > class pmultiset : public multiset > { public: - pmultiset() : multiset >() { } - pmultiset(const pmultiset ©) : multiset >(copy) { } - pmultiset(const Compare &comp) : multiset >(comp) { } + typedef pallocator_single allocator; + pmultiset(TypeHandle type_handle = pmap_type_handle) : multiset(Compare(), allocator(type_handle)) { } + pmultiset(const pmultiset ©) : multiset(copy) { } + pmultiset(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : multiset(comp, type_handle) { } }; #ifdef HAVE_STL_HASH diff --git a/dtool/src/dtoolbase/pvector.h b/dtool/src/dtoolbase/pvector.h index 2e8dd20d07..a2cb39834a 100644 --- a/dtool/src/dtoolbase/pvector.h +++ b/dtool/src/dtoolbase/pvector.h @@ -23,6 +23,7 @@ #include "dtoolbase.h" #include "pallocator.h" +#include "register_type.h" #ifndef USE_STL_ALLOCATOR // If we're not using custom allocators, just use the standard class @@ -41,14 +42,15 @@ template class pvector : public vector > { public: - typedef vector > base_class; + typedef pallocator_array allocator; + typedef vector base_class; typedef TYPENAME base_class::size_type size_type; - pvector() : base_class() { } + pvector(TypeHandle type_handle = pvector_type_handle) : base_class(allocator(type_handle)) { } pvector(const pvector ©) : base_class(copy) { } - pvector(size_type n) : base_class(n) { } - pvector(size_type n, const Type &value) : base_class(n, value) { } - pvector(const Type *begin, const Type *end) : base_class(begin, end) { } + pvector(size_type n, TypeHandle type_handle = pvector_type_handle) : base_class(n, Type(), allocator(type_handle)) { } + pvector(size_type n, const Type &value, TypeHandle type_handle = pvector_type_handle) : base_class(n, value, allocator(type_handle)) { } + pvector(const Type *begin, const Type *end, TypeHandle type_handle = pvector_type_handle) : base_class(begin, end, allocator(type_handle)) { } }; #endif // USE_STL_ALLOCATOR diff --git a/dtool/src/interrogatedb/register_type.I b/dtool/src/dtoolbase/register_type.I similarity index 100% rename from dtool/src/interrogatedb/register_type.I rename to dtool/src/dtoolbase/register_type.I diff --git a/dtool/src/interrogatedb/register_type.cxx b/dtool/src/dtoolbase/register_type.cxx similarity index 77% rename from dtool/src/interrogatedb/register_type.cxx rename to dtool/src/dtoolbase/register_type.cxx index df043b4e6d..0ac1e032c0 100644 --- a/dtool/src/interrogatedb/register_type.cxx +++ b/dtool/src/dtoolbase/register_type.cxx @@ -23,9 +23,11 @@ TypeHandle long_type_handle; TypeHandle int_type_handle; TypeHandle short_type_handle; TypeHandle char_type_handle; +TypeHandle uchar_type_handle; TypeHandle bool_type_handle; TypeHandle double_type_handle; TypeHandle float_type_handle; +TypeHandle string_type_handle; TypeHandle long_p_type_handle; TypeHandle int_p_type_handle; @@ -36,6 +38,12 @@ TypeHandle double_p_type_handle; TypeHandle float_p_type_handle; TypeHandle void_p_type_handle; +TypeHandle pvector_type_handle; +TypeHandle pdeque_type_handle; +TypeHandle plist_type_handle; +TypeHandle pmap_type_handle; +TypeHandle pset_type_handle; + void init_system_type_handles() { static bool done = false; if (!done) { @@ -44,9 +52,11 @@ void init_system_type_handles() { register_type(int_type_handle, "int"); register_type(short_type_handle, "short"); register_type(char_type_handle, "char"); + register_type(uchar_type_handle, "uchar"); register_type(bool_type_handle, "bool"); register_type(double_type_handle, "double"); register_type(float_type_handle, "float"); + register_type(string_type_handle, "string"); register_type(int_p_type_handle, "int*"); register_type(short_p_type_handle, "short*"); @@ -55,6 +65,12 @@ void init_system_type_handles() { register_type(double_p_type_handle, "double*"); register_type(float_p_type_handle, "float*"); register_type(void_p_type_handle, "void*"); + + register_type(pvector_type_handle, "pvector"); + register_type(pdeque_type_handle, "pdeque"); + register_type(plist_type_handle, "plist"); + register_type(pmap_type_handle, "pmap"); + register_type(pset_type_handle, "pset"); } } diff --git a/dtool/src/interrogatedb/register_type.h b/dtool/src/dtoolbase/register_type.h similarity index 88% rename from dtool/src/interrogatedb/register_type.h rename to dtool/src/dtoolbase/register_type.h index 798ed9d877..5336f7b516 100644 --- a/dtool/src/interrogatedb/register_type.h +++ b/dtool/src/dtoolbase/register_type.h @@ -85,13 +85,15 @@ register_dynamic_type(const string &name, // A few system-wide TypeHandles are defined for some basic types. -extern TypeHandle EXPCL_DTOOLCONFIG long_type_handle; -extern TypeHandle EXPCL_DTOOLCONFIG int_type_handle; -extern TypeHandle EXPCL_DTOOLCONFIG short_type_handle; -extern TypeHandle EXPCL_DTOOLCONFIG char_type_handle; -extern TypeHandle EXPCL_DTOOLCONFIG bool_type_handle; -extern TypeHandle EXPCL_DTOOLCONFIG double_type_handle; -extern TypeHandle EXPCL_DTOOLCONFIG float_type_handle; +extern TypeHandle EXPCL_DTOOL long_type_handle; +extern TypeHandle EXPCL_DTOOL int_type_handle; +extern TypeHandle EXPCL_DTOOL short_type_handle; +extern TypeHandle EXPCL_DTOOL char_type_handle; +extern TypeHandle EXPCL_DTOOL uchar_type_handle; +extern TypeHandle EXPCL_DTOOL bool_type_handle; +extern TypeHandle EXPCL_DTOOL double_type_handle; +extern TypeHandle EXPCL_DTOOL float_type_handle; +extern TypeHandle EXPCL_DTOOL string_type_handle; extern TypeHandle long_p_type_handle; extern TypeHandle int_p_type_handle; @@ -102,7 +104,13 @@ extern TypeHandle double_p_type_handle; extern TypeHandle float_p_type_handle; extern TypeHandle void_p_type_handle; -void EXPCL_DTOOLCONFIG init_system_type_handles(); +extern TypeHandle EXPCL_DTOOL pvector_type_handle; +extern TypeHandle EXPCL_DTOOL pdeque_type_handle; +extern TypeHandle EXPCL_DTOOL plist_type_handle; +extern TypeHandle EXPCL_DTOOL pmap_type_handle; +extern TypeHandle EXPCL_DTOOL pset_type_handle; + +void EXPCL_DTOOL init_system_type_handles(); // The following template function and its specializations will return // a TypeHandle for any type in the world, from a pointer to that @@ -133,6 +141,11 @@ INLINE TypeHandle _get_type_handle(const char *) { return char_type_handle; } +template<> +INLINE TypeHandle _get_type_handle(const unsigned char *) { + return uchar_type_handle; +} + template<> INLINE TypeHandle _get_type_handle(const bool *) { return bool_type_handle; @@ -148,6 +161,11 @@ INLINE TypeHandle _get_type_handle(const float *) { return float_type_handle; } +template<> +INLINE TypeHandle _get_type_handle(const string *) { + return string_type_handle; +} + template<> INLINE TypeHandle _get_type_handle(const long * const *) { return long_p_type_handle; diff --git a/dtool/src/interrogatedb/typeHandle.I b/dtool/src/dtoolbase/typeHandle.I similarity index 100% rename from dtool/src/interrogatedb/typeHandle.I rename to dtool/src/dtoolbase/typeHandle.I diff --git a/dtool/src/dtoolbase/typeHandle.cxx b/dtool/src/dtoolbase/typeHandle.cxx new file mode 100644 index 0000000000..4763cc99d9 --- /dev/null +++ b/dtool/src/dtoolbase/typeHandle.cxx @@ -0,0 +1,102 @@ +// Filename: typeHandle.cxx +// Created by: drose (23Oct98) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "typeHandle.h" +#include "typeRegistryNode.h" + +// This is initialized to zero by static initialization. +TypeHandle TypeHandle::_none; + +#ifdef DO_MEMORY_USAGE +//////////////////////////////////////////////////////////////////// +// Function: TypeHandle::get_memory_usage +// Access: Published +// Description: Returns the total allocated memory used by objects of +// this type, for the indicated memory class. This is +// only updated if track-memory-usage is set true in +// your Config.prc file. +//////////////////////////////////////////////////////////////////// +size_t TypeHandle:: +get_memory_usage(MemoryClass memory_class) const { + assert((int)memory_class >= 0 && (int)memory_class < (int)MC_limit); + if ((*this) == TypeHandle::none()) { + return 0; + } else { + TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, NULL); + assert(rnode != (TypeRegistryNode *)NULL); + return rnode->_memory_usage[memory_class]; + } +} +#endif // DO_MEMORY_USAGE + +#ifdef DO_MEMORY_USAGE +//////////////////////////////////////////////////////////////////// +// Function: TypeHandle::inc_memory_usage +// Access: Published +// Description: Adds the indicated amount to the record for the total +// allocated memory for objects of this type. +//////////////////////////////////////////////////////////////////// +void TypeHandle:: +inc_memory_usage(MemoryClass memory_class, size_t size) { + assert((int)memory_class >= 0 && (int)memory_class < (int)MC_limit); + if ((*this) != TypeHandle::none()) { + TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, NULL); + assert(rnode != (TypeRegistryNode *)NULL); + rnode->_memory_usage[memory_class] += size; + } +} +#endif // DO_MEMORY_USAGE + +#ifdef DO_MEMORY_USAGE +//////////////////////////////////////////////////////////////////// +// Function: TypeHandle::dec_memory_usage +// Access: Published +// Description: Subtracts the indicated amount from the record for +// the total allocated memory for objects of this type. +//////////////////////////////////////////////////////////////////// +void TypeHandle:: +dec_memory_usage(MemoryClass memory_class, size_t size) { + assert((int)memory_class >= 0 && (int)memory_class < (int)MC_limit); + if ((*this) != TypeHandle::none()) { + TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, NULL); + assert(rnode != (TypeRegistryNode *)NULL); + rnode->_memory_usage[memory_class] -= size; + } +} +#endif // DO_MEMORY_USAGE + +ostream & +operator << (ostream &out, TypeHandle::MemoryClass mem_class) { + switch (mem_class) { + case TypeHandle::MC_singleton: + return out << "singleton"; + + case TypeHandle::MC_array: + return out << "array"; + + case TypeHandle::MC_deleted_chain_active: + return out << "deleted_chain_active"; + + case TypeHandle::MC_deleted_chain_inactive: + return out << "deleted_chain_inactive"; + } + + return out + << "**invalid TypeHandle::MemoryClass (" << (int)mem_class + << ")**\n"; +} diff --git a/dtool/src/interrogatedb/typeHandle.h b/dtool/src/dtoolbase/typeHandle.h similarity index 90% rename from dtool/src/interrogatedb/typeHandle.h rename to dtool/src/dtoolbase/typeHandle.h index 3477f6cc98..12a2776a40 100644 --- a/dtool/src/interrogatedb/typeHandle.h +++ b/dtool/src/dtoolbase/typeHandle.h @@ -21,7 +21,6 @@ #include "dtoolbase.h" #include "typeRegistry.h" -#include "pnotify.h" #include @@ -88,8 +87,18 @@ class TypedObject; // ancestry of a particular type may be queried, and the // type name may be retrieved for run-time display. //////////////////////////////////////////////////////////////////// -class EXPCL_DTOOLCONFIG TypeHandle { +class EXPCL_DTOOL TypeHandle { PUBLISHED: + enum MemoryClass { + MC_singleton, + MC_array, + MC_deleted_chain_active, + MC_deleted_chain_inactive, + + MC_limit // Not a real value, just a placeholder for the maximum + // enum value. + }; + INLINE TypeHandle(); INLINE TypeHandle(const TypeHandle ©); @@ -117,6 +126,12 @@ PUBLISHED: INLINE int get_best_parent_from_Set(const std::set< int > &legal_vals) const; +#ifdef DO_MEMORY_USAGE + size_t get_memory_usage(MemoryClass memory_class) const; + void inc_memory_usage(MemoryClass memory_class, size_t size); + void dec_memory_usage(MemoryClass memory_class, size_t size); +#endif + INLINE int get_index() const; INLINE void output(ostream &out) const; INLINE static TypeHandle none(); @@ -136,6 +151,8 @@ INLINE ostream &operator << (ostream &out, TypeHandle type) { return out; } +ostream &operator << (ostream &out, TypeHandle::MemoryClass mem_class); + // We must include typeRegistry at this point so we can call it from // our inline functions. This is a circular include that is // strategically placed to do no harm. diff --git a/dtool/src/interrogatedb/typeRegistry.I b/dtool/src/dtoolbase/typeRegistry.I similarity index 100% rename from dtool/src/interrogatedb/typeRegistry.I rename to dtool/src/dtoolbase/typeRegistry.I diff --git a/dtool/src/interrogatedb/typeRegistry.cxx b/dtool/src/dtoolbase/typeRegistry.cxx similarity index 86% rename from dtool/src/interrogatedb/typeRegistry.cxx rename to dtool/src/dtoolbase/typeRegistry.cxx index d15879a94a..c944887d1c 100644 --- a/dtool/src/interrogatedb/typeRegistry.cxx +++ b/dtool/src/dtoolbase/typeRegistry.cxx @@ -21,20 +21,12 @@ #include "typeHandle.h" #include "typedObject.h" #include "indent.h" -#include "config_interrogatedb.h" -#include "configVariableBool.h" #include -// In general, we use the interrogatedb_cat->info() syntax in this file -// (instead of interrogatedb_cat.info()), because much of this work is done at -// static init time, and we must use the arrow syntax to force -// initialization of the interrogatedb_cat category. - MutexImpl *TypeRegistry::_lock = NULL; TypeRegistry *TypeRegistry::_global_pointer = NULL; - //////////////////////////////////////////////////////////////////// // Function: TypeRegistry::register_type // Access: Public @@ -57,7 +49,7 @@ register_type(TypeHandle &type_handle, const string &name) { if (&type_handle == &rnode->_ref) { // No problem. _lock->release(); - nassertr(rnode->_name == name, false); + assert(rnode->_name == name); return false; } } @@ -69,14 +61,6 @@ register_type(TypeHandle &type_handle, const string &name) { // The name was not already used; this is the first time this // class has been defined. -#ifdef NOTIFY_DEBUG - // This code runs at static init time, so cannot use the - // interrogatedb_cat.is_spam() syntax. - if (interrogatedb_cat->is_spam()) { - interrogatedb_cat->spam() << "Registering type " << name << "\n"; - } -#endif - TypeHandle new_handle; new_handle._index = _handle_registry.size(); @@ -90,11 +74,11 @@ register_type(TypeHandle &type_handle, const string &name) { return true; } TypeRegistryNode *rnode = (*ri).second; - nassertr(rnode->_name == (*ri).first, false); - nassertr(rnode->_handle._index >= 0 && - rnode->_handle._index < (int)_handle_registry.size(), false); - nassertr(_handle_registry[rnode->_handle._index] == rnode, false); - nassertr(rnode->_handle._index != 0, false); + assert(rnode->_name == (*ri).first); + assert(rnode->_handle._index >= 0 && + rnode->_handle._index < (int)_handle_registry.size()); + assert(_handle_registry[rnode->_handle._index] == rnode); + assert(rnode->_handle._index != 0); // The name was previously used; make sure the type_handle matches. if (&type_handle == &rnode->_ref) { @@ -110,8 +94,7 @@ register_type(TypeHandle &type_handle, const string &name) { // at the first call to register_type(), and we got the same // reference passed in this time, but now it's different! Bad // juju. - interrogatedb_cat->error() - << "Reregistering " << name << "\n"; + cerr << "Reregistering " << name << "\n"; type_handle == rnode->_handle; _lock->release(); return false; @@ -119,7 +102,7 @@ register_type(TypeHandle &type_handle, const string &name) { if (type_handle != rnode->_handle) { // Hmm, we seem to have a contradictory type registration! - interrogatedb_cat->warning() + cerr << "Attempt to register type " << name << " more than once!\n"; // This is invalid, but we'll allow it anyway. It seems to happen @@ -153,14 +136,6 @@ register_dynamic_type(const string &name) { // The name was not already used; this is the first time this // class has been defined. -#ifdef NOTIFY_DEBUG - // This code runs at static init time, so cannot use the - // interrogatedb_cat.is_spam() syntax. - if (interrogatedb_cat->is_spam()) { - interrogatedb_cat->spam() << "Registering type " << name << "\n"; - } -#endif - // We must dynamically allocate a new handle so the TypeRegistryNode // has something unique to point to. This doesn't really mean // anything, though. @@ -196,9 +171,9 @@ record_derivation(TypeHandle child, TypeHandle parent) { _lock->lock(); TypeRegistryNode *cnode = look_up(child, NULL); - nassertv(cnode != (TypeRegistryNode *)NULL); + assert(cnode != (TypeRegistryNode *)NULL); TypeRegistryNode *pnode = look_up(parent, NULL); - nassertv(pnode != (TypeRegistryNode *)NULL); + assert(pnode != (TypeRegistryNode *)NULL); // First, we'll just run through the list to make sure we hadn't // already made this connection. @@ -233,7 +208,7 @@ record_alternate_name(TypeHandle type, const string &name) { NameRegistry::iterator ri = _name_registry.insert(NameRegistry::value_type(name, rnode)).first; if ((*ri).second != rnode) { - interrogatedb_cat.warning() + cerr << "Name " << name << " already assigned to TypeHandle " << rnode->_name << "; cannot reassign to " << type << "\n"; } @@ -279,7 +254,7 @@ string TypeRegistry:: get_name(TypeHandle type, TypedObject *object) const { _lock->lock(); TypeRegistryNode *rnode = look_up(type, object); - nassertr(rnode != (TypeRegistryNode *)NULL, ""); + assert(rnode != (TypeRegistryNode *)NULL); string name = rnode->_name; _lock->release(); @@ -311,8 +286,8 @@ is_derived_from(TypeHandle child, TypeHandle base, const TypeRegistryNode *child_node = look_up(child, child_object); const TypeRegistryNode *base_node = look_up(base, (TypedObject *)NULL); - nassertr(child_node != (TypeRegistryNode *)NULL && - base_node != (TypeRegistryNode *)NULL, false); + assert(child_node != (TypeRegistryNode *)NULL && + base_node != (TypeRegistryNode *)NULL); freshen_derivations(); bool result = TypeRegistryNode::is_derived_from(child_node, base_node); @@ -320,6 +295,42 @@ is_derived_from(TypeHandle child, TypeHandle base, return result; } +//////////////////////////////////////////////////////////////////// +// Function: TypeRegistry::get_num_type_handles +// Access: Public +// Description: Returns the total number of unique TypeHandles in the +// system. +//////////////////////////////////////////////////////////////////// +int TypeRegistry:: +get_num_typehandles() { + _lock->lock(); + int num_types = (int)_handle_registry.size(); + _lock->release(); + return num_types; +} + +//////////////////////////////////////////////////////////////////// +// Function: TypeRegistry::get_typehandle +// Access: Public +// Description: Returns the nth TypeHandle in the system. See +// get_num_typehandles(). +//////////////////////////////////////////////////////////////////// +TypeHandle TypeRegistry:: +get_typehandle(int n) { + _lock->lock(); + TypeRegistryNode *rnode = NULL; + if (n >= 0 && n < (int)_handle_registry.size()) { + rnode = _handle_registry[n]; + } + _lock->release(); + + if (rnode != (TypeRegistryNode *)NULL) { + return rnode->_handle; + } + + return TypeHandle::none(); +} + //////////////////////////////////////////////////////////////////// // Function: TypeRegistry::get_num_root_classes // Access: Public @@ -347,7 +358,7 @@ get_root_class(int n) { _lock->lock(); freshen_derivations(); TypeHandle handle; - if (n >= 0 && n < get_num_root_classes()) { + if (n >= 0 && n < (int)_root_classes.size()) { handle = _root_classes[n]->_handle; } _lock->release(); @@ -375,7 +386,7 @@ int TypeRegistry:: get_num_parent_classes(TypeHandle child, TypedObject *child_object) const { _lock->lock(); TypeRegistryNode *rnode = look_up(child, child_object); - nassertr(rnode != (TypeRegistryNode *)NULL, 0); + assert(rnode != (TypeRegistryNode *)NULL); int num_parents = rnode->_parent_classes.size(); _lock->release(); return num_parents; @@ -393,7 +404,7 @@ get_parent_class(TypeHandle child, int index) const { _lock->lock(); TypeHandle handle; TypeRegistryNode *rnode = look_up(child, (TypedObject *)NULL); - nassertr(rnode != (TypeRegistryNode *)NULL, TypeHandle::none()); + assert(rnode != (TypeRegistryNode *)NULL); if (index >= 0 && index < (int)rnode->_parent_classes.size()) { handle = rnode->_parent_classes[index]->_handle; } @@ -417,7 +428,7 @@ int TypeRegistry:: get_num_child_classes(TypeHandle child, TypedObject *child_object) const { _lock->lock(); TypeRegistryNode *rnode = look_up(child, child_object); - nassertr(rnode != (TypeRegistryNode *)NULL, 0); + assert(rnode != (TypeRegistryNode *)NULL); int num_children = rnode->_child_classes.size(); _lock->release(); return num_children; @@ -435,7 +446,7 @@ get_child_class(TypeHandle child, int index) const { _lock->lock(); TypeHandle handle; TypeRegistryNode *rnode = look_up(child, (TypedObject *)NULL); - nassertr(rnode != (TypeRegistryNode *)NULL, TypeHandle::none()); + assert(rnode != (TypeRegistryNode *)NULL); if (index >= 0 && index < (int)rnode->_child_classes.size()) { handle = rnode->_child_classes[index]->_handle; } @@ -464,8 +475,8 @@ get_parent_towards(TypeHandle child, TypeHandle base, TypeHandle handle; const TypeRegistryNode *child_node = look_up(child, child_object); const TypeRegistryNode *base_node = look_up(base, NULL); - nassertr(child_node != (TypeRegistryNode *)NULL && - base_node != (TypeRegistryNode *)NULL, TypeHandle::none()); + assert(child_node != (TypeRegistryNode *)NULL && + base_node != (TypeRegistryNode *)NULL); freshen_derivations(); handle = TypeRegistryNode::get_parent_towards(child_node, base_node); _lock->release(); @@ -495,8 +506,7 @@ reregister_types() { ++ri) { TypeRegistryNode *rnode = (*ri); if (rnode != NULL && rnode->_handle != rnode->_ref) { - interrogatedb_cat->warning() - << "Reregistering " << rnode->_name << "\n"; + cerr << "Reregistering " << rnode->_name << "\n"; } } _lock->release(); @@ -538,12 +548,6 @@ ptr() { init_lock(); _lock->lock(); if (_global_pointer == NULL) { -#ifdef NOTIFY_DEBUG - if (interrogatedb_cat->is_spam()) { - interrogatedb_cat->spam() - << "Creating global TypeRegistry\n"; - } -#endif init_global_pointer(); } _lock->release(); @@ -574,16 +578,6 @@ TypeRegistry() { void TypeRegistry:: init_global_pointer() { _global_pointer = new TypeRegistry; - - // Now that we've created the TypeRegistry, we can assign this - // Config variable. - - ConfigVariableBool paranoid_inheritance - ("paranoid-inheritance", true, - PRC_DESC("Set this to true to double-check the test for inheritance of " - "TypeHandles, e.g. via is_of_type(). This has no effect if NDEBUG " - "is defined.")); - TypeRegistryNode::_paranoid_inheritance = paranoid_inheritance; } //////////////////////////////////////////////////////////////////// @@ -595,13 +589,6 @@ init_global_pointer() { //////////////////////////////////////////////////////////////////// void TypeRegistry:: rebuild_derivations() { -#ifdef NOTIFY_DEBUG - if (interrogatedb_cat->is_debug()) { - interrogatedb_cat->debug() - << "Rebuilding derivation tree.\n"; - } -#endif - // First, remove all of the old data from the last type // rebuild_derivations() was called. _root_classes.clear(); @@ -678,42 +665,42 @@ look_up(TypeHandle handle, TypedObject *object) const { handle = object->force_init_type(); if (handle._index == 0) { // Strange. - interrogatedb_cat->error() + cerr << "Unable to force_init_type() on unregistered TypeHandle.\n"; - nassertr(false, NULL); + return NULL; } if (handle == object->get_type()) { // Problem solved! - interrogatedb_cat->warning() + cerr << "Type " << handle << " was unregistered!\n"; } else { // No good; it looks like the TypeHandle belongs to a class // that defined get_type(), but didn't define // force_init_type(). - interrogatedb_cat->error() + cerr << "Attempt to reference unregistered TypeHandle. Type is of some\n" << "class derived from " << handle << " that doesn't define a good\n" << "force_init_type() method.\n"; - nassertr(false, NULL); + return NULL; } } else { // We don't have a TypedObject pointer, so there's nothing we // can do about it. - interrogatedb_cat->error() + cerr << "Attempt to reference unregistered TypeHandle!\n" << "Registered TypeHandles are:\n"; - write(interrogatedb_cat->error(false)); - nassertr(false, NULL); + write(cerr); + return NULL; } } if (handle._index < 0 || handle._index >= (int)_handle_registry.size()) { - interrogatedb_cat->fatal() + cerr << "Invalid TypeHandle index " << handle._index << "! Is memory corrupt?\n"; - nassertr(false, NULL); + return NULL; } #endif // NDEBUG @@ -724,34 +711,34 @@ look_up(TypeHandle handle, TypedObject *object) const { // Function: find_type_by_id // Access: Private /////////////////////////////////////////////////////////////////// -TypeHandle TypeRegistry::find_type_by_id(int id) const -{ - if (id < 0 ||id >= (int)_handle_registry.size()) - { - interrogatedb_cat->fatal() +TypeHandle TypeRegistry:: +find_type_by_id(int id) const { + if (id < 0 ||id >= (int)_handle_registry.size()) { + cerr << "Invalid TypeHandle index " << id << "! Is memory corrupt?\n"; - //nassertr(false, NULL); return TypeHandle::none(); } - return _handle_registry[id]->_handle; -}; + return _handle_registry[id]->_handle; +} //////////////////////////////////////////////////////////////////// // Function: get_best_parent_from_Set // Access: Private /////////////////////////////////////////////////////////////////// -extern "C" int get_best_parent_from_Set(int id, const std::set &set) -{ - // most common case.. - if(set.find(id) != set.end()) - return id; +extern "C" int +get_best_parent_from_Set(int id, const std::set &set) { + // most common case.. + if (set.find(id) != set.end()) { + return id; + } - TypeHandle th = TypeRegistry::ptr()->find_type_by_id(id); - if(th == TypeHandle::none()) - return -1; + TypeHandle th = TypeRegistry::ptr()->find_type_by_id(id); + if (th == TypeHandle::none()) { + return -1; + } - return th.get_best_parent_from_Set(set); + return th.get_best_parent_from_Set(set); } diff --git a/dtool/src/interrogatedb/typeRegistry.h b/dtool/src/dtoolbase/typeRegistry.h similarity index 89% rename from dtool/src/interrogatedb/typeRegistry.h rename to dtool/src/dtoolbase/typeRegistry.h index 1b9dec2dc3..768cf0e7a0 100644 --- a/dtool/src/interrogatedb/typeRegistry.h +++ b/dtool/src/dtoolbase/typeRegistry.h @@ -21,12 +21,11 @@ #include "dtoolbase.h" #include "mutexImpl.h" -#include "pnotify.h" -#include "pvector.h" -#include "pmap.h" #include "memoryBase.h" #include +#include +#include class TypeHandle; class TypeRegistryNode; @@ -41,7 +40,7 @@ class TypedObject; // initially, and it should be migrated to shared memory // as soon as shared memory becomes available. //////////////////////////////////////////////////////////////////// -class EXPCL_DTOOLCONFIG TypeRegistry : public MemoryBase { +class EXPCL_DTOOL TypeRegistry : public MemoryBase { public: // User code shouldn't generally need to call // TypeRegistry::register_type() or record_derivation() directly; @@ -62,6 +61,9 @@ PUBLISHED: bool is_derived_from(TypeHandle child, TypeHandle base, TypedObject *child_object); + int get_num_typehandles(); + TypeHandle get_typehandle(int n); + int get_num_root_classes(); TypeHandle get_root_class(int n); @@ -98,24 +100,26 @@ private: static INLINE void init_lock(); - typedef pvector HandleRegistry; + typedef vector HandleRegistry; HandleRegistry _handle_registry; - typedef phash_map NameRegistry; + typedef map NameRegistry; NameRegistry _name_registry; - typedef pvector RootClasses; + typedef vector RootClasses; RootClasses _root_classes; bool _derivations_fresh; static MutexImpl *_lock; static TypeRegistry *_global_pointer; + + friend class TypeHandle; }; /////////////////////////////////////////// // Helper function to allow for "C" interaction into the type system -extern "C" EXPCL_DTOOLCONFIG int get_best_parent_from_Set(int id, const std::set &set); +extern "C" EXPCL_DTOOL int get_best_parent_from_Set(int id, const std::set &set); #include "typeRegistry.I" diff --git a/dtool/src/interrogatedb/typeRegistryNode.I b/dtool/src/dtoolbase/typeRegistryNode.I similarity index 96% rename from dtool/src/interrogatedb/typeRegistryNode.I rename to dtool/src/dtoolbase/typeRegistryNode.I index 55b462cbed..ba79514457 100644 --- a/dtool/src/interrogatedb/typeRegistryNode.I +++ b/dtool/src/dtoolbase/typeRegistryNode.I @@ -37,14 +37,14 @@ Inherit() { INLINE TypeRegistryNode::Inherit:: Inherit(TypeRegistryNode *top, int bit_count, TypeRegistryNode::SubtreeMaskType bits) { - nassertv(bit_count < (int)(sizeof(SubtreeMaskType) * 8)); + assert(bit_count < (int)(sizeof(SubtreeMaskType) * 8)); _top = top; // Build a bitmask consisting of bit_count low-order bits. _mask = ((SubtreeMaskType)1 << bit_count) - 1; // There shouldn't be anything but zeroes after bit_count bits. - nassertv((bits & ~_mask) == 0); + assert((bits & ~_mask) == 0); _bits = bits; } @@ -94,7 +94,7 @@ operator < (const Inherit &other) const { INLINE bool TypeRegistryNode::Inherit:: is_derived_from(const TypeRegistryNode::Inherit &child, const TypeRegistryNode::Inherit &base) { - nassertr(child._top == base._top, false); + assert(child._top == base._top); // Child derives from base if and only if its subtree mask contains // more bits (or the same number of bits), and the n low-order diff --git a/dtool/src/interrogatedb/typeRegistryNode.cxx b/dtool/src/dtoolbase/typeRegistryNode.cxx similarity index 95% rename from dtool/src/interrogatedb/typeRegistryNode.cxx rename to dtool/src/dtoolbase/typeRegistryNode.cxx index 22123f929e..88360b024a 100644 --- a/dtool/src/interrogatedb/typeRegistryNode.cxx +++ b/dtool/src/dtoolbase/typeRegistryNode.cxx @@ -17,11 +17,10 @@ //////////////////////////////////////////////////////////////////// #include "typeRegistryNode.h" -#include "config_interrogatedb.h" #include -bool TypeRegistryNode::_paranoid_inheritance; +bool TypeRegistryNode::_paranoid_inheritance = false; //////////////////////////////////////////////////////////////////// // Function: TypeRegistryNode::Constructor @@ -33,6 +32,9 @@ TypeRegistryNode(TypeHandle handle, const string &name, TypeHandle &ref) : _handle(handle), _name(name), _ref(ref) { clear_subtree(); +#ifdef DO_MEMORY_USAGE + memset(_memory_usage, 0, sizeof(_memory_usage)); +#endif } //////////////////////////////////////////////////////////////////// @@ -60,7 +62,7 @@ is_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base) { // relationship with no additional work. (See r_build_subtrees()). if (child->_inherit._top == base->_inherit._top) { - nassertr(child->_inherit._top != (TypeRegistryNode *)NULL, false); + assert(child->_inherit._top != (TypeRegistryNode *)NULL); bool derives = Inherit::is_derived_from(child->_inherit, base->_inherit); @@ -69,7 +71,7 @@ is_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base) { if (_paranoid_inheritance) { bool paranoid_derives = check_derived_from(child, base); if (derives != paranoid_derives) { - interrogatedb_cat.error() + cerr << "Inheritance test for " << child->_name << " from " << base->_name << " failed!\n" << "Result: " << derives << " should have been: " @@ -80,7 +82,7 @@ is_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base) { << child->_name << " has mask " << child->_inherit._mask << " and bits " << child->_inherit._bits << "\n" << base->_name << " has mask " << base->_inherit._mask - << " and bits " << base->_inherit._bits << "\n" + << " and bits " << base->_inherit._bits << "\n" << dec; return paranoid_derives; } @@ -134,7 +136,7 @@ is_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base) { if (_paranoid_inheritance) { bool paranoid_derives = check_derived_from(child, base); if (derives != paranoid_derives) { - interrogatedb_cat.error() + cerr << "Inheritance test for " << child->_name << " from " << base->_name << " failed!\n" << "Result: " << derives << " should have been: " @@ -142,7 +144,7 @@ is_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base) { << child->_name << " is a descendent of " << child_top->_name << "\n" << base->_name << " is a descendent of " - << base_top->_name << "\n"; + << base_top->_name << "\n"; return paranoid_derives; } } @@ -270,7 +272,7 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count, // node itself. if (top != this && _parent_classes.size() != 1) { - nassertv(!_parent_classes.empty()); + assert(!_parent_classes.empty()); // This class multiply inherits; it therefore begins a new subtree. @@ -284,7 +286,7 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count, if (_visit_count == (int)_parent_classes.size()) { // This is the last time we'll visit this node, so continue the // recursion now. - nassertv(_inherit._top == (TypeRegistryNode *)NULL); + assert(_inherit._top == (TypeRegistryNode *)NULL); sort(_top_inheritance.begin(), _top_inheritance.end()); define_subtree(); } @@ -292,9 +294,9 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count, } else { // This class singly inherits, so this had better be the only time // this function is called on it since clear_subtree(). - nassertv(_inherit._top == (TypeRegistryNode *)NULL); + assert(_inherit._top == (TypeRegistryNode *)NULL); - nassertv(bit_count < (int)(sizeof(SubtreeMaskType) * 8)); + assert(bit_count < (int)(sizeof(SubtreeMaskType) * 8)); _inherit = Inherit(top, bit_count, bits); @@ -312,13 +314,13 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count, // we can differentiate parent from child. more_bits = max(more_bits, 1); - nassertv(more_bits < (int)(sizeof(SubtreeMaskType) * 8)); + assert(more_bits < (int)(sizeof(SubtreeMaskType) * 8)); if (bit_count + more_bits > (int)(sizeof(SubtreeMaskType) * 8)) { // Too many bits; we need to start a new subtree right here. // This node becomes a subtree top node, even though it's not a // multiple-inheritance node. - nassertv(top != this); + assert(top != this); _top_inheritance = top->_top_inheritance; _top_inheritance.push_back(_inherit); sort(_top_inheritance.begin(), _top_inheritance.end()); diff --git a/dtool/src/interrogatedb/typeRegistryNode.h b/dtool/src/dtoolbase/typeRegistryNode.h similarity index 93% rename from dtool/src/interrogatedb/typeRegistryNode.h rename to dtool/src/dtoolbase/typeRegistryNode.h index d118a51d57..d6e7ef6c52 100644 --- a/dtool/src/interrogatedb/typeRegistryNode.h +++ b/dtool/src/dtoolbase/typeRegistryNode.h @@ -23,7 +23,7 @@ #include "typeHandle.h" -#include "pvector.h" +#include //////////////////////////////////////////////////////////////////// // Class : TypeRegistryNode @@ -32,7 +32,7 @@ // class; this class is hidden within the TypeRegistry // accessors. //////////////////////////////////////////////////////////////////// -class EXPCL_DTOOLCONFIG TypeRegistryNode { +class EXPCL_DTOOL TypeRegistryNode { public: TypeRegistryNode(TypeHandle handle, const string &name, TypeHandle &ref); @@ -48,10 +48,14 @@ public: TypeHandle _handle; string _name; TypeHandle &_ref; - typedef pvector Classes; + typedef vector Classes; Classes _parent_classes; Classes _child_classes; +#ifdef DO_MEMORY_USAGE + size_t _memory_usage[TypeHandle::MC_limit]; +#endif + static bool _paranoid_inheritance; private: @@ -75,7 +79,7 @@ private: SubtreeMaskType _mask; SubtreeMaskType _bits; }; - typedef pvector TopInheritance; + typedef vector TopInheritance; void r_build_subtrees(TypeRegistryNode *top, int bit_count, SubtreeMaskType bits); diff --git a/dtool/src/interrogatedb/typedObject.I b/dtool/src/dtoolbase/typedObject.I similarity index 100% rename from dtool/src/interrogatedb/typedObject.I rename to dtool/src/dtoolbase/typedObject.I diff --git a/dtool/src/interrogatedb/typedObject.cxx b/dtool/src/dtoolbase/typedObject.cxx similarity index 96% rename from dtool/src/interrogatedb/typedObject.cxx rename to dtool/src/dtoolbase/typedObject.cxx index 275fc4f64a..c535764e1e 100644 --- a/dtool/src/interrogatedb/typedObject.cxx +++ b/dtool/src/dtoolbase/typedObject.cxx @@ -17,8 +17,6 @@ //////////////////////////////////////////////////////////////////// #include "typedObject.h" -#include "config_interrogatedb.h" - TypeHandle TypedObject::_type_handle; @@ -42,7 +40,7 @@ get_type() const { // Normally, this function should never be called, because it is a // pure virtual function. If it is called, you probably called // get_type() on a recently-destructed object. - interrogatedb_cat.warning() + cerr << "TypedObject::get_type() called!\n"; return _type_handle; } diff --git a/dtool/src/interrogatedb/typedObject.h b/dtool/src/dtoolbase/typedObject.h similarity index 99% rename from dtool/src/interrogatedb/typedObject.h rename to dtool/src/dtoolbase/typedObject.h index 3f138f1faa..5f2c20583b 100644 --- a/dtool/src/interrogatedb/typedObject.h +++ b/dtool/src/dtoolbase/typedObject.h @@ -105,7 +105,7 @@ // } // //////////////////////////////////////////////////////////////////// -class EXPCL_DTOOLCONFIG TypedObject : public MemoryBase { +class EXPCL_DTOOL TypedObject : public MemoryBase { public: INLINE TypedObject(); INLINE TypedObject(const TypedObject ©); diff --git a/dtool/src/dtoolutil/Sources.pp b/dtool/src/dtoolutil/Sources.pp index 59ab38b5c5..928befea15 100644 --- a/dtool/src/dtoolutil/Sources.pp +++ b/dtool/src/dtoolutil/Sources.pp @@ -9,6 +9,7 @@ #define SOURCES \ checkPandaVersion.h \ + config_dtoolutil.h \ executionEnvironment.I executionEnvironment.h filename.I \ filename.h load_dso.h dSearchPath.I dSearchPath.h \ pandaSystem.h pandaVersion.h \ @@ -18,6 +19,7 @@ #define INCLUDED_SOURCES \ checkPandaVersion.cxx \ + config_dtoolutil.cxx \ executionEnvironment.cxx filename.cxx load_dso.cxx \ dSearchPath.cxx \ pandaSystem.cxx \ @@ -26,6 +28,7 @@ #define INSTALL_HEADERS \ checkPandaVersion.h \ + config_dtoolutil.h \ executionEnvironment.I executionEnvironment.h filename.I \ filename.h load_dso.h dSearchPath.I dSearchPath.h \ pandaSystem.h pandaVersion.h \ diff --git a/dtool/src/dtoolutil/config_dtoolutil.cxx b/dtool/src/dtoolutil/config_dtoolutil.cxx new file mode 100644 index 0000000000..f90e105b48 --- /dev/null +++ b/dtool/src/dtoolutil/config_dtoolutil.cxx @@ -0,0 +1,51 @@ +// Filename: config_dtoolutil.cxx +// Created by: drose (17Nov06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "config_dtoolutil.h" + +#include "filename.h" +#include "pandaSystem.h" + +//////////////////////////////////////////////////////////////////// +// Function: init_libdtoolutil +// Description: Initializes the library. This must be called at +// least once before any of the functions or classes in +// this library can be used. Normally it will be +// called by the static initializers and need not be +// called explicitly, but special cases exist. +//////////////////////////////////////////////////////////////////// +void +init_libdtoolutil() { + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; + + Filename::init_type(); + PandaSystem::init_type(); +} + +class InitDtoolutil { +public: + InitDtoolutil() { + init_libdtoolutil(); + } +}; + +static InitDtoolutil _init; diff --git a/dtool/src/interrogatedb/typeHandle.cxx b/dtool/src/dtoolutil/config_dtoolutil.h similarity index 78% rename from dtool/src/interrogatedb/typeHandle.cxx rename to dtool/src/dtoolutil/config_dtoolutil.h index 33105f7c02..a1eddd7aa6 100644 --- a/dtool/src/interrogatedb/typeHandle.cxx +++ b/dtool/src/dtoolutil/config_dtoolutil.h @@ -1,5 +1,5 @@ -// Filename: typeHandle.cxx -// Created by: drose (23Oct98) +// Filename: config_dtoolutil.h +// Created by: drose (17Nov06) // //////////////////////////////////////////////////////////////////// // @@ -16,7 +16,9 @@ // //////////////////////////////////////////////////////////////////// -#include "typeHandle.h" +#ifndef CONFIG_DTOOLUTIL_H +#define CONFIG_DTOOLUTIL_H -// This is initialized to zero by static initialization. -TypeHandle TypeHandle::_none; +#include "dtoolbase.h" + +#endif diff --git a/dtool/src/dtoolutil/dtoolutil_composite1.cxx b/dtool/src/dtoolutil/dtoolutil_composite1.cxx index c51a5c47ea..86eb708076 100644 --- a/dtool/src/dtoolutil/dtoolutil_composite1.cxx +++ b/dtool/src/dtoolutil/dtoolutil_composite1.cxx @@ -1,4 +1,4 @@ - +#include "config_dtoolutil.cxx" #include "filename.cxx" #include "load_dso.cxx" #include "dSearchPath.cxx" diff --git a/dtool/src/dtoolutil/filename.cxx b/dtool/src/dtoolutil/filename.cxx index d5c682808a..af32b98986 100644 --- a/dtool/src/dtoolutil/filename.cxx +++ b/dtool/src/dtoolutil/filename.cxx @@ -51,6 +51,7 @@ #include #endif +TypeHandle Filename::_type_handle; #ifdef WIN32 /* begin Win32-specific code */ diff --git a/dtool/src/dtoolutil/filename.h b/dtool/src/dtoolutil/filename.h index 21240b34db..7852b5ee72 100644 --- a/dtool/src/dtoolutil/filename.h +++ b/dtool/src/dtoolutil/filename.h @@ -20,7 +20,8 @@ #define FILENAME_H #include "dtoolbase.h" - +#include "typeHandle.h" +#include "register_type.h" #include "vector_string.h" #include @@ -216,6 +217,17 @@ protected: size_t _hash_end; int _flags; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "Filename"); + } + +private: + static TypeHandle _type_handle; }; INLINE ostream &operator << (ostream &out, const Filename &n) { diff --git a/dtool/src/dtoolutil/pandaSystem.cxx b/dtool/src/dtoolutil/pandaSystem.cxx index 83a4cfe20c..00aebceb2e 100644 --- a/dtool/src/dtoolutil/pandaSystem.cxx +++ b/dtool/src/dtoolutil/pandaSystem.cxx @@ -20,6 +20,7 @@ #include "pandaVersion.h" PandaSystem *PandaSystem::_global_ptr = NULL; +TypeHandle PandaSystem::_type_handle; //////////////////////////////////////////////////////////////////// // Function: PandaSystem::Constructor @@ -30,7 +31,9 @@ PandaSystem *PandaSystem::_global_ptr = NULL; // PandaSystem. //////////////////////////////////////////////////////////////////// PandaSystem:: -PandaSystem() { +PandaSystem() : + _systems(get_class_type()) +{ _system_names_dirty = false; } @@ -269,7 +272,7 @@ get_system_tag(const string &system, const string &tag) const { //////////////////////////////////////////////////////////////////// void PandaSystem:: add_system(const string &system) { - bool inserted = _systems.insert(Systems::value_type(system, SystemTags())).second; + bool inserted = _systems.insert(Systems::value_type(system, SystemTags(get_class_type()))).second; if (inserted) { _system_names_dirty = true; } @@ -285,7 +288,7 @@ void PandaSystem:: set_system_tag(const string &system, const string &tag, const string &value) { pair result; - result = _systems.insert(Systems::value_type(system, SystemTags())); + result = _systems.insert(Systems::value_type(system, SystemTags(get_class_type()))); if (result.second) { _system_names_dirty = true; } diff --git a/dtool/src/dtoolutil/pandaSystem.h b/dtool/src/dtoolutil/pandaSystem.h index 78a4e84c91..a2cf0c634a 100644 --- a/dtool/src/dtoolutil/pandaSystem.h +++ b/dtool/src/dtoolutil/pandaSystem.h @@ -74,6 +74,17 @@ private: bool _system_names_dirty; static PandaSystem *_global_ptr; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "PandaSystem"); + } + +private: + static TypeHandle _type_handle; }; inline ostream &operator << (ostream &out, const PandaSystem &ps) { diff --git a/dtool/src/interrogatedb/Sources.pp b/dtool/src/interrogatedb/Sources.pp index a235a9092c..bf1dedba05 100644 --- a/dtool/src/interrogatedb/Sources.pp +++ b/dtool/src/interrogatedb/Sources.pp @@ -16,11 +16,6 @@ interrogate_datafile.I interrogate_datafile.h \ interrogate_interface.h interrogate_request.h \ py_panda.h \ - register_type.I register_type.h \ - typedObject.I typedObject.h \ - typeHandle.I typeHandle.h \ - typeRegistry.I typeRegistry.h \ - typeRegistryNode.I typeRegistryNode.h \ vector_int.h #define INCLUDED_SOURCES \ @@ -33,21 +28,12 @@ interrogateType.cxx interrogate_datafile.cxx \ interrogate_interface.cxx interrogate_request.cxx \ py_panda.cxx \ - register_type.cxx \ - typedObject.cxx \ - typeHandle.cxx \ - typeRegistry.cxx typeRegistryNode.cxx \ vector_int.cxx #define INSTALL_HEADERS \ interrogate_interface.h interrogate_request.h vector_int.h \ config_interrogatedb.h \ py_panda.h \ - register_type.I register_type.h \ - typedObject.I typedObject.h \ - typeHandle.I typeHandle.h \ - typeRegistry.I typeRegistry.h \ - typeRegistryNode.I typeRegistryNode.h \ - + vector_int.h #end lib_target diff --git a/dtool/src/interrogatedb/interrogatedb_composite2.cxx b/dtool/src/interrogatedb/interrogatedb_composite2.cxx index 1521861194..d7ac84faae 100644 --- a/dtool/src/interrogatedb/interrogatedb_composite2.cxx +++ b/dtool/src/interrogatedb/interrogatedb_composite2.cxx @@ -1,11 +1,6 @@ #include "interrogateType.cxx" #include "interrogate_request.cxx" #include "py_panda.cxx" -#include "register_type.cxx" -#include "typedObject.cxx" -#include "typeHandle.cxx" -#include "typeRegistry.cxx" -#include "typeRegistryNode.cxx" diff --git a/dtool/src/prc/configVariableCore.cxx b/dtool/src/prc/configVariableCore.cxx index dc1d14157a..b122d53f13 100644 --- a/dtool/src/prc/configVariableCore.cxx +++ b/dtool/src/prc/configVariableCore.cxx @@ -477,7 +477,7 @@ sort_declarations() { // need to be recomputed all that often. _unique_declarations.clear(); - pset already_added; + pset already_added(TypeHandle::none()); for (di = _trusted_declarations.begin(); di != _trusted_declarations.end(); ++di) { diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index cd53b02246..7f01e853c9 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -334,6 +334,7 @@ init_libdisplay() { initialized = true; DisplayRegion::init_type(); + DisplayRegionPipelineReader::init_type(); GraphicsBuffer::init_type(); GraphicsDevice::init_type(); GraphicsOutput::init_type(); diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index ecb6c28c45..2c6864eb45 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -25,6 +25,7 @@ #include "pnmImage.h" TypeHandle DisplayRegion::_type_handle; +TypeHandle DisplayRegionPipelineReader::_type_handle; //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::Constructor diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 018aa5a372..5f8e69a4e4 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -273,6 +273,17 @@ private: DisplayRegion *_object; Thread *_current_thread; const DisplayRegion::CData *_cdata; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "DisplayRegionPipelineReader"); + } + +private: + static TypeHandle _type_handle; }; INLINE ostream &operator << (ostream &out, const DisplayRegion &dr); diff --git a/panda/src/gobj/config_gobj.cxx b/panda/src/gobj/config_gobj.cxx index 16e187d9e6..dbbc1f20ec 100644 --- a/panda/src/gobj/config_gobj.cxx +++ b/panda/src/gobj/config_gobj.cxx @@ -249,18 +249,24 @@ ConfigVariableDouble default_keystone ConfigureFn(config_gobj) { BufferContext::init_type(); Geom::init_type(); + GeomPipelineReader::init_type(); GeomContext::init_type(); GeomLines::init_type(); GeomLinestrips::init_type(); GeomMunger::init_type(); GeomPoints::init_type(); GeomPrimitive::init_type(); + GeomPrimitivePipelineReader::init_type(); GeomTriangles::init_type(); GeomTrifans::init_type(); GeomTristrips::init_type(); GeomVertexArrayData::init_type(); + GeomVertexArrayDataPipelineReader::init_type(); + GeomVertexArrayDataPipelineWriter::init_type(); GeomVertexArrayFormat::init_type(); GeomVertexData::init_type(); + GeomVertexDataPipelineReader::init_type(); + GeomVertexDataPipelineWriter::init_type(); GeomVertexFormat::init_type(); IndexBufferContext::init_type(); InternalName::init_type(); diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index 8c23aa6f80..587742fde6 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -32,6 +32,10 @@ UpdateSeq Geom::_next_modified; PStatCollector Geom::_draw_primitive_setup_pcollector("Draw:Primitive:Setup"); TypeHandle Geom::_type_handle; +TypeHandle Geom::CDataCache::_type_handle; +TypeHandle Geom::CacheEntry::_type_handle; +TypeHandle Geom::CData::_type_handle; +TypeHandle GeomPipelineReader::_type_handle; //////////////////////////////////////////////////////////////////// // Function: Geom::Constructor diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index e84014ff40..46dfbebb5e 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -195,6 +195,17 @@ private: Geom *_source; // A back pointer to the containing Geom const Geom *_geom_result; // ref-counted if not NULL and not same as _source CPT(GeomVertexData) _data_result; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "Geom::CDataCache"); + } + + private: + static TypeHandle _type_handle; }; typedef CycleDataReader CDCacheReader; typedef CycleDataWriter CDCacheWriter; @@ -229,6 +240,17 @@ public: CacheKey _key; PipelineCycler _cycler; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "Geom::CacheEntry"); + } + + private: + static TypeHandle _type_handle; }; typedef pmap > Cache; @@ -259,6 +281,17 @@ private: CPT(BoundingVolume) _internal_bounds; bool _internal_bounds_stale; CPT(BoundingVolume) _user_bounds; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "Geom::CData"); + } + + private: + static TypeHandle _type_handle; }; PipelineCycler _cycler; @@ -297,6 +330,9 @@ public: TypedWritableReferenceCount::init_type(); register_type(_type_handle, "Geom", TypedWritableReferenceCount::get_class_type()); + CDataCache::init_type(); + CacheEntry::init_type(); + CData::init_type(); } virtual TypeHandle get_type() const { return get_class_type(); @@ -353,6 +389,17 @@ private: const Geom *_object; Thread *_current_thread; const Geom::CData *_cdata; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomPipelineReader"); + } + +private: + static TypeHandle _type_handle; }; INLINE ostream &operator << (ostream &out, const Geom &obj); diff --git a/panda/src/gobj/geomPrimitive.cxx b/panda/src/gobj/geomPrimitive.cxx index 41d49f2799..4d9ddc3606 100644 --- a/panda/src/gobj/geomPrimitive.cxx +++ b/panda/src/gobj/geomPrimitive.cxx @@ -33,6 +33,8 @@ #include "pStatTimer.h" TypeHandle GeomPrimitive::_type_handle; +TypeHandle GeomPrimitive::CData::_type_handle; +TypeHandle GeomPrimitivePipelineReader::_type_handle; PStatCollector GeomPrimitive::_decompose_pcollector("*:Munge:Decompose"); PStatCollector GeomPrimitive::_rotate_pcollector("*:Munge:Rotate"); diff --git a/panda/src/gobj/geomPrimitive.h b/panda/src/gobj/geomPrimitive.h index eb9632d026..1fcc5715df 100644 --- a/panda/src/gobj/geomPrimitive.h +++ b/panda/src/gobj/geomPrimitive.h @@ -251,6 +251,17 @@ private: unsigned int _min_vertex; unsigned int _max_vertex; + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomPrimitive::CData"); + } + + private: + static TypeHandle _type_handle; + friend class GeomPrimitive; }; @@ -280,6 +291,7 @@ public: TypedWritableReferenceCount::init_type(); register_type(_type_handle, "GeomPrimitive", TypedWritableReferenceCount::get_class_type()); + CData::init_type(); } virtual TypeHandle get_type() const { return get_class_type(); @@ -341,6 +353,17 @@ private: const GeomPrimitive::CData *_cdata; GeomVertexArrayDataPipelineReader *_vertices_reader; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomPrimitivePipelineReader"); + } + +private: + static TypeHandle _type_handle; }; INLINE ostream &operator << (ostream &out, const GeomPrimitive &obj); diff --git a/panda/src/gobj/geomVertexArrayData.cxx b/panda/src/gobj/geomVertexArrayData.cxx index eec8a60122..78a5698331 100644 --- a/panda/src/gobj/geomVertexArrayData.cxx +++ b/panda/src/gobj/geomVertexArrayData.cxx @@ -25,6 +25,9 @@ #include "pset.h" TypeHandle GeomVertexArrayData::_type_handle; +TypeHandle GeomVertexArrayData::CData::_type_handle; +TypeHandle GeomVertexArrayDataPipelineReader::_type_handle; +TypeHandle GeomVertexArrayDataPipelineWriter::_type_handle; PT(PStatCollectorForward) GeomVertexArrayData::_vdata_mem_pcollector = new PStatCollectorForward(PStatCollector("Main memory:C++:Vertex Data")); diff --git a/panda/src/gobj/geomVertexArrayData.h b/panda/src/gobj/geomVertexArrayData.h index e4c1f3493c..4b3518982a 100644 --- a/panda/src/gobj/geomVertexArrayData.h +++ b/panda/src/gobj/geomVertexArrayData.h @@ -136,6 +136,17 @@ private: UsageHint _usage_hint; PTA_uchar _data; UpdateSeq _modified; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomVertexArrayData::CData"); + } + + private: + static TypeHandle _type_handle; friend class GeomVertexArrayData; }; @@ -170,6 +181,7 @@ public: TypedWritableReferenceCount::init_type(); register_type(_type_handle, "GeomVertexArrayData", TypedWritableReferenceCount::get_class_type()); + CData::init_type(); } virtual TypeHandle get_type() const { return get_class_type(); @@ -234,6 +246,17 @@ public: ALLOC_DELETED_CHAIN(GeomVertexArrayDataPipelineReader); INLINE const GeomVertexArrayData *get_object() const; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomVertexArrayDataPipelineReader"); + } + +private: + static TypeHandle _type_handle; }; //////////////////////////////////////////////////////////////////// @@ -257,6 +280,17 @@ public: INLINE GeomVertexArrayData *get_object() const; PTA_uchar modify_data(); void set_data(CPTA_uchar data); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomVertexArrayDataPipelineWriter"); + } + +private: + static TypeHandle _type_handle; }; INLINE ostream &operator << (ostream &out, const GeomVertexArrayData &obj); diff --git a/panda/src/gobj/geomVertexData.cxx b/panda/src/gobj/geomVertexData.cxx index 1c810812e2..bf6f94d022 100644 --- a/panda/src/gobj/geomVertexData.cxx +++ b/panda/src/gobj/geomVertexData.cxx @@ -28,6 +28,11 @@ #include "indent.h" TypeHandle GeomVertexData::_type_handle; +TypeHandle GeomVertexData::CDataCache::_type_handle; +TypeHandle GeomVertexData::CacheEntry::_type_handle; +TypeHandle GeomVertexData::CData::_type_handle; +TypeHandle GeomVertexDataPipelineReader::_type_handle; +TypeHandle GeomVertexDataPipelineWriter::_type_handle; PStatCollector GeomVertexData::_convert_pcollector("*:Munge:Convert"); PStatCollector GeomVertexData::_scale_color_pcollector("*:Munge:Scale color"); diff --git a/panda/src/gobj/geomVertexData.h b/panda/src/gobj/geomVertexData.h index c75bb8e114..522967c745 100644 --- a/panda/src/gobj/geomVertexData.h +++ b/panda/src/gobj/geomVertexData.h @@ -197,6 +197,17 @@ private: } CPT(GeomVertexData) _result; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomVertexData::CDataCache"); + } + + private: + static TypeHandle _type_handle; }; typedef CycleDataReader CDCacheReader; typedef CycleDataWriter CDCacheWriter; @@ -228,6 +239,17 @@ public: CacheKey _key; PipelineCycler _cycler; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomVertexData::CacheEntry"); + } + + private: + static TypeHandle _type_handle; }; typedef pmap > Cache; @@ -255,6 +277,17 @@ private: PT(GeomVertexData) _animated_vertices; UpdateSeq _animated_vertices_modified; UpdateSeq _modified; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomVertexData::CData"); + } + + private: + static TypeHandle _type_handle; }; PipelineCycler _cycler; @@ -298,6 +331,9 @@ public: TypedWritableReferenceCount::init_type(); register_type(_type_handle, "GeomVertexData", TypedWritableReferenceCount::get_class_type()); + CDataCache::init_type(); + CacheEntry::init_type(); + CData::init_type(); } virtual TypeHandle get_type() const { return get_class_type(); @@ -399,6 +435,17 @@ private: bool _got_array_readers; typedef pvector ArrayReaders; ArrayReaders _array_readers; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomVertexDataPipelineReader"); + } + +private: + static TypeHandle _type_handle; }; //////////////////////////////////////////////////////////////////// @@ -437,6 +484,17 @@ private: bool _got_array_writers; typedef pvector ArrayWriters; ArrayWriters _array_writers; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "GeomVertexDataPipelineWriter"); + } + +private: + static TypeHandle _type_handle; }; INLINE ostream &operator << (ostream &out, const GeomVertexData &obj); diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index 670719244b..d89a140fc0 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -44,6 +44,7 @@ #include "eventStorePandaNode.h" #include "fadeLodNode.h" #include "fadeLodNodeData.h" +#include "findApproxLevelEntry.h" #include "fog.h" #include "fogAttrib.h" #include "geomNode.h" @@ -317,6 +318,7 @@ init_libpgraph() { EventStorePandaNode::init_type(); FadeLODNode::init_type(); FadeLODNodeData::init_type(); + FindApproxLevelEntry::init_type(); Fog::init_type(); FogAttrib::init_type(); GeomNode::init_type(); @@ -332,11 +334,11 @@ init_libpgraph() { MaterialAttrib::init_type(); ModelLoadRequest::init_type(); ModelNode::init_type(); - ModelRoot::init_type(); NodePath::init_type(); NodePathComponent::init_type(); PandaNode::init_type(); + PandaNodePipelineReader::init_type(); PlaneNode::init_type(); PointLight::init_type(); PolylightNode::init_type(); diff --git a/panda/src/pgraph/findApproxLevelEntry.cxx b/panda/src/pgraph/findApproxLevelEntry.cxx index 3f9b465d8b..bb42668875 100644 --- a/panda/src/pgraph/findApproxLevelEntry.cxx +++ b/panda/src/pgraph/findApproxLevelEntry.cxx @@ -21,6 +21,8 @@ #include "pandaNode.h" #include "indent.h" +TypeHandle FindApproxLevelEntry::_type_handle; + //////////////////////////////////////////////////////////////////// // Function: FindApproxLevelEntry::output // Access: Public diff --git a/panda/src/pgraph/findApproxLevelEntry.h b/panda/src/pgraph/findApproxLevelEntry.h index a23a8d46a1..61e499931b 100644 --- a/panda/src/pgraph/findApproxLevelEntry.h +++ b/panda/src/pgraph/findApproxLevelEntry.h @@ -68,6 +68,17 @@ public: int _i; FindApproxPath &_approx_path; FindApproxLevelEntry *_next; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "FindApproxLevelEntry"); + } + +private: + static TypeHandle _type_handle; }; INLINE ostream & diff --git a/panda/src/pgraph/nodePathComponent.cxx b/panda/src/pgraph/nodePathComponent.cxx index bf56ef9f5a..b56586213b 100644 --- a/panda/src/pgraph/nodePathComponent.cxx +++ b/panda/src/pgraph/nodePathComponent.cxx @@ -24,6 +24,7 @@ int NodePathComponent::_next_key = 1; Mutex NodePathComponent::_key_lock("NodePathComponent::_key_lock"); TypeHandle NodePathComponent::_type_handle; +TypeHandle NodePathComponent::CData::_type_handle; //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/nodePathComponent.h b/panda/src/pgraph/nodePathComponent.h index 3d58de66ec..68a1ee8ef6 100644 --- a/panda/src/pgraph/nodePathComponent.h +++ b/panda/src/pgraph/nodePathComponent.h @@ -96,6 +96,17 @@ private: PT(NodePathComponent) _next; int _length; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "NodePathComponent::CData"); + } + + private: + static TypeHandle _type_handle; }; PipelineCycler _cycler; @@ -116,6 +127,7 @@ public: ReferenceCount::init_type(); register_type(_type_handle, "NodePathComponent", ReferenceCount::get_class_type()); + CData::init_type(); } private: diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index 3ce90ea4fd..11929ec624 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -39,6 +39,8 @@ DrawMask PandaNode::_overall_bit = DrawMask::bit(31); PStatCollector PandaNode::_reset_prev_pcollector("App:Collisions:Reset"); TypeHandle PandaNode::_type_handle; +TypeHandle PandaNode::CData::_type_handle; +TypeHandle PandaNodePipelineReader::_type_handle; // // There are two different interfaces here for making and breaking diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h index 967fa7780d..697673fc67 100644 --- a/panda/src/pgraph/pandaNode.h +++ b/panda/src/pgraph/pandaNode.h @@ -525,6 +525,17 @@ private: PT(Down) _down; PT(Down) _stashed; PT(Up) _up; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "PandaNode::CData"); + } + + private: + static TypeHandle _type_handle; }; PipelineCycler _cycler; @@ -618,6 +629,7 @@ public: register_type(_type_handle, "PandaNode", TypedWritable::get_class_type(), ReferenceCount::get_class_type()); + CData::init_type(); } virtual TypeHandle get_type() const { return get_class_type(); @@ -700,6 +712,17 @@ private: Thread *_current_thread; const PandaNode::CData *_cdata; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "PandaNodePipelineReader"); + } + +private: + static TypeHandle _type_handle; }; INLINE ostream &operator << (ostream &out, const PandaNode &node) { diff --git a/panda/src/pnmimage/pnmFileTypeRegistry.h b/panda/src/pnmimage/pnmFileTypeRegistry.h index 44cc5b90b5..caf1291524 100644 --- a/panda/src/pnmimage/pnmFileTypeRegistry.h +++ b/panda/src/pnmimage/pnmFileTypeRegistry.h @@ -22,6 +22,8 @@ #include "pandabase.h" #include "typedObject.h" +#include "pmap.h" +#include "pvector.h" class PNMFileType; diff --git a/panda/src/pnmimage/pnmImageHeader.h b/panda/src/pnmimage/pnmImageHeader.h index addb65c472..f31ab096a5 100644 --- a/panda/src/pnmimage/pnmImageHeader.h +++ b/panda/src/pnmimage/pnmImageHeader.h @@ -25,6 +25,9 @@ #include "typedObject.h" #include "filename.h" +#include "pnotify.h" +#include "pmap.h" +#include "pvector.h" class PNMFileType; class PNMReader; diff --git a/panda/src/pstatclient/pStatClient.cxx b/panda/src/pstatclient/pStatClient.cxx index 443c44a7f2..77f4d8804e 100644 --- a/panda/src/pstatclient/pStatClient.cxx +++ b/panda/src/pstatclient/pStatClient.cxx @@ -42,6 +42,16 @@ PStatCollector PStatClient::_clock_busy_wait_pcollector("Wait:Clock Wait:Spin"); PStatClient *PStatClient::_global_pstats = NULL; +// This class is used to report memory usage per TypeHandle. We +// create one of these for each TypeHandle in the system. +class TypeHandleCollector { +public: + PStatCollector _mem_class[TypeHandle::MC_limit]; +}; +typedef pvector TypeHandleCols; +static TypeHandleCols type_handle_cols; + + //////////////////////////////////////////////////////////////////// // Function: PStatClient::PerThreadData::Constructor // Access: Public @@ -200,16 +210,44 @@ main_tick() { // know about PStatClient. #ifdef DO_MEMORY_USAGE - if (MemoryUsage::has_total_size()) { - _total_size_pcollector.set_level(MemoryUsage::get_total_size()); + if (is_connected()) { + if (MemoryUsage::has_total_size()) { + _total_size_pcollector.set_level(MemoryUsage::get_total_size()); + } + if (MemoryUsage::has_cpp_size()) { + _cpp_size_pcollector.set_level(MemoryUsage::get_cpp_size()); + } + if (MemoryUsage::has_interpreter_size()) { + _interpreter_size_pcollector.set_level(MemoryUsage::get_interpreter_size()); + } + + TypeRegistry *type_reg = TypeRegistry::ptr(); + int num_typehandles = type_reg->get_num_typehandles(); + + while ((int)type_handle_cols.size() < num_typehandles) { + type_handle_cols.push_back(TypeHandleCollector()); + } + + for (int i = 0; i < num_typehandles; ++i) { + TypeHandle type = type_reg->get_typehandle(i); + for (int mi = 0; mi < (int)TypeHandle::MC_limit; ++mi) { + TypeHandle::MemoryClass mc = (TypeHandle::MemoryClass)mi; + PStatCollector &col = type_handle_cols[i]._mem_class[mi]; + size_t usage = type.get_memory_usage(mc); + if (usage != 0 || col.is_valid()) { + // We have some memory usage on this TypeHandle. See if we + // have a collector for it. + if (!col.is_valid()) { + ostringstream strm; + strm << "Main memory:C++:" << type << ":" << mc; + col = PStatCollector(strm.str()); + } + col.set_level(usage); + } + } + } } - if (MemoryUsage::has_cpp_size()) { - _cpp_size_pcollector.set_level(MemoryUsage::get_cpp_size()); - } - if (MemoryUsage::has_interpreter_size()) { - _interpreter_size_pcollector.set_level(MemoryUsage::get_interpreter_size()); - } -#endif +#endif // DO_MEMORY_USAGE get_global_pstats()->client_main_tick(); } diff --git a/panda/src/pstatclient/pStatCollector.I b/panda/src/pstatclient/pStatCollector.I index f9e08ac1b8..300b1e2c43 100644 --- a/panda/src/pstatclient/pStatCollector.I +++ b/panda/src/pstatclient/pStatCollector.I @@ -19,21 +19,6 @@ #ifdef DO_PSTATS -//////////////////////////////////////////////////////////////////// -// Function: PStatCollector::Default Constructor -// Access: Private -// Description: Normally, this constructor is called only from -// PStatClient. Use one of the constructors below to -// create your own Collector. -//////////////////////////////////////////////////////////////////// -INLINE PStatCollector:: -PStatCollector() : - _client(NULL), - _index(0), - _level(0.0f) -{ -} - //////////////////////////////////////////////////////////////////// // Function: PStatCollector::Constructor // Access: Private @@ -49,6 +34,22 @@ PStatCollector(PStatClient *client, int index) : { } +//////////////////////////////////////////////////////////////////// +// Function: PStatCollector::Default Constructor +// Access: Public +// Description: Creates an invalid PStatCollector. Any attempt to +// use this collector will crash messily. +// +// You can reassign it to a different, valid one later. +//////////////////////////////////////////////////////////////////// +INLINE PStatCollector:: +PStatCollector() : + _client(NULL), + _index(0), + _level(0.0f) +{ +} + //////////////////////////////////////////////////////////////////// // Function: PStatCollector::Constructor // Access: Published @@ -135,6 +136,19 @@ operator = (const PStatCollector ©) { _index = copy._index; } +//////////////////////////////////////////////////////////////////// +// Function: PStatCollector::is_valid +// Access: Published +// Description: Returns true if collector is valid and may be used, +// or false if it was constructed with the default +// constructor (in which case any attempt to use it will +// crash). +//////////////////////////////////////////////////////////////////// +INLINE bool PStatCollector:: +is_valid() const { + return (_client != (PStatClient *)NULL); +} + //////////////////////////////////////////////////////////////////// // Function: PStatCollector::is_active // Access: Published diff --git a/panda/src/pstatclient/pStatCollector.h b/panda/src/pstatclient/pStatCollector.h index 782f996b26..5ecde7a410 100644 --- a/panda/src/pstatclient/pStatCollector.h +++ b/panda/src/pstatclient/pStatCollector.h @@ -54,9 +54,11 @@ class EXPCL_PANDA PStatCollector { #ifdef DO_PSTATS private: - INLINE PStatCollector(); INLINE PStatCollector(PStatClient *client, int index); +public: + INLINE PStatCollector(); + PUBLISHED: INLINE PStatCollector(const string &name, PStatClient *client = NULL); @@ -66,6 +68,8 @@ PUBLISHED: INLINE PStatCollector(const PStatCollector ©); INLINE void operator = (const PStatCollector ©); + INLINE bool is_valid() const; + INLINE bool is_active(); INLINE bool is_started(); INLINE void start(); diff --git a/panda/src/putil/bitMask.h b/panda/src/putil/bitMask.h index 411115edce..7e9223032f 100644 --- a/panda/src/putil/bitMask.h +++ b/panda/src/putil/bitMask.h @@ -24,6 +24,7 @@ #include "numeric_types.h" #include "typedObject.h" #include "indent.h" +#include "pnotify.h" #include "checksumHashGenerator.h"