more memory tracking stuff

This commit is contained in:
David Rose 2006-11-24 22:59:44 +00:00
parent f5c32e7f28
commit 5779007507
63 changed files with 851 additions and 252 deletions

View File

@ -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

View File

@ -31,16 +31,27 @@ MutexImpl *DeletedChain<Type>::_lock;
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE Type *DeletedChain<Type>::
allocate(size_t size) {
TAU_PROFILE("Type *DeletedChain<Type>::allocate(size_t)", " ", TAU_USER);
allocate(size_t size, TypeHandle type_handle) {
TAU_PROFILE("Type *DeletedChain<Type>::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<class Type>
INLINE void DeletedChain<Type>::
deallocate(Type *ptr) {
TAU_PROFILE("void DeletedChain<Type>::deallocate(Type *)", " ", TAU_USER);
deallocate(Type *ptr, TypeHandle type_handle) {
TAU_PROFILE("void DeletedChain<Type>::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

View File

@ -24,6 +24,8 @@
#include "mutexImpl.h"
#include "atomicAdjust.h"
#include "numeric_types.h"
#include "register_type.h"
#include "typeHandle.h"
#include <assert.h>
#ifdef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
@ -80,8 +82,8 @@ enum DeletedChainFlag {
template<class Type>
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 *) { \
}

View File

@ -5,3 +5,4 @@
#include "atomicAdjustPosixImpl.cxx"
#include "atomicAdjustWin32Impl.cxx"
#include "dtoolbase.cxx"
#include "memoryBase.cxx"

View File

@ -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"

View File

@ -18,7 +18,9 @@
template<class Type>
INLINE pallocator_single<Type>::
pallocator_single() throw() {
pallocator_single(TypeHandle type_handle) throw() :
_type_handle(type_handle)
{
}
template<class Type>
@ -27,19 +29,21 @@ allocate(TYPENAME pallocator_single<Type>::size_type n, TYPENAME allocator<void>
TAU_PROFILE("pallocator_single:allocate()", " ", TAU_USER);
// This doesn't support allocating arrays.
assert(n == 1);
return DeletedChain<Type>::allocate(sizeof(Type));
return DeletedChain<Type>::allocate(sizeof(Type), _type_handle);
}
template<class Type>
INLINE void pallocator_single<Type>::
deallocate(TYPENAME pallocator_single<Type>::pointer p, TYPENAME pallocator_single<Type>::size_type) {
TAU_PROFILE("pallocator_single:deallocate()", " ", TAU_USER);
return DeletedChain<Type>::deallocate(p);
return DeletedChain<Type>::deallocate(p, _type_handle);
}
template<class Type>
INLINE pallocator_array<Type>::
pallocator_array() throw() {
pallocator_array(TypeHandle type_handle) throw() :
_type_handle(type_handle)
{
}
template<class Type>
@ -47,7 +51,13 @@ INLINE TYPENAME pallocator_array<Type>::pointer pallocator_array<Type>::
allocate(TYPENAME pallocator_array<Type>::size_type n, TYPENAME allocator<void>::const_pointer) {
TAU_PROFILE("pallocator_array:allocate()", " ", TAU_USER);
#ifdef DO_MEMORY_USAGE
return (TYPENAME pallocator_array<Type>::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<Type>::pointer)(*global_operator_new)(alloc_size);
*((size_t *)ptr) = alloc_size;
return (TYPENAME pallocator_array<Type>::pointer)(((size_t *)ptr) + 1);
#else
return (TYPENAME pallocator_array<Type>::pointer)malloc(n * sizeof(Type));
#endif // DO_MEMORY_USAGE
@ -58,7 +68,10 @@ INLINE void pallocator_array<Type>::
deallocate(TYPENAME pallocator_array<Type>::pointer p, TYPENAME pallocator_array<Type>::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

View File

@ -22,6 +22,7 @@
#include <memory>
#include "dtoolbase.h"
#include "deletedChain.h"
#include "typeHandle.h"
////////////////////////////////////////////////////////////////////
// Class : pallocator
@ -59,11 +60,12 @@ public:
typedef TYPENAME allocator<Type>::const_reference const_reference;
typedef TYPENAME allocator<Type>::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<class U>
INLINE pallocator_single(const pallocator_single<U> &) throw() { }
INLINE pallocator_single(const pallocator_single<U> &copy) throw() :
_type_handle(copy._type_handle) { }
INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
INLINE void deallocate(pointer p, size_type n);
@ -71,6 +73,8 @@ public:
template<class U> struct rebind {
typedef pallocator_single<U> other;
};
TypeHandle _type_handle;
};
template<class Type>
@ -84,11 +88,12 @@ public:
typedef TYPENAME allocator<Type>::const_reference const_reference;
typedef TYPENAME allocator<Type>::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<class U>
INLINE pallocator_array(const pallocator_array<U> &) throw() { }
INLINE pallocator_array(const pallocator_array<U> &copy) throw() :
_type_handle(copy._type_handle) { }
INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
INLINE void deallocate(pointer p, size_type n);
@ -96,6 +101,8 @@ public:
template<class U> struct rebind {
typedef pallocator_array<U> other;
};
TypeHandle _type_handle;
};
#include "pallocator.T"

View File

@ -21,6 +21,7 @@
#include "dtoolbase.h"
#include "pallocator.h"
#include "register_type.h"
#include <deque>
#ifndef USE_STL_ALLOCATOR
@ -40,11 +41,12 @@
template<class Type>
class pdeque : public deque<Type, pallocator_array<Type> > {
public:
typedef TYPENAME deque<Type, pallocator_array<Type> >::size_type size_type;
pdeque() : deque<Type, pallocator_array<Type> >() { }
typedef pallocator_array<Type> allocator;
typedef TYPENAME deque<Type, allocator>::size_type size_type;
pdeque(TypeHandle type_handle = pdeque_type_handle) : deque<Type, pallocator_array<Type> >(allocator(type_handle)) { }
pdeque(const pdeque<Type> &copy) : deque<Type, pallocator_array<Type> >(copy) { }
pdeque(size_type n) : deque<Type, pallocator_array<Type> >(n) { }
pdeque(size_type n, const Type &value) : deque<Type, pallocator_array<Type> >(n, value) { }
pdeque(size_type n, TypeHandle type_handle = pdeque_type_handle) : deque<Type, pallocator_array<Type> >(n, Type(), allocator(type_handle)) { }
pdeque(size_type n, const Type &value, TypeHandle type_handle = pdeque_type_handle) : deque<Type, pallocator_array<Type> >(n, value, allocator(type_handle)) { }
};
#endif // USE_STL_ALLOCATOR

View File

@ -21,6 +21,7 @@
#include "dtoolbase.h"
#include "pallocator.h"
#include "register_type.h"
#include <list>
#ifndef USE_STL_ALLOCATOR
@ -40,16 +41,18 @@
template<class Type>
class plist : public list<Type, pallocator_single<Type> > {
public:
typedef TYPENAME list<Type, pallocator_single<Type> >::size_type size_type;
plist() : list<Type, pallocator_single<Type> >() { }
plist(const plist<Type> &copy) : list<Type, pallocator_single<Type> >(copy) { }
plist(size_type n) : list<Type, pallocator_single<Type> >(n) { }
plist(size_type n, const Type &value) : list<Type, pallocator_single<Type> >(n, value) { }
typedef pallocator_single<Type> allocator;
typedef list<Type, allocator> 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<Type> &copy) : 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<Type, pallocator_single<Type> >::iterator iterator;
typedef TYPENAME list<Type, pallocator_single<Type> >::const_iterator const_iterator;
typedef TYPENAME list<Type, pallocator_single<Type> >::reverse_iterator reverse_iterator;
typedef TYPENAME list<Type, pallocator_single<Type> >::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

View File

@ -22,6 +22,7 @@
#include "dtoolbase.h"
#include "pallocator.h"
#include "stl_compares.h"
#include "register_type.h"
#include <map>
#ifdef HAVE_STL_HASH
@ -54,11 +55,12 @@
template<class Key, class Value, class Compare = less<Key> >
class pmap : public map<Key, Value, Compare, pallocator_single<pair<const Key, Value> > > {
public:
typedef map<Key, Value, Compare, pallocator_single<pair<const Key, Value> > > base_class;
typedef pallocator_single<pair<const Key, Value> > allocator;
typedef map<Key, Value, Compare, allocator> base_class;
pmap() : base_class() { }
pmap(TypeHandle type_handle = pmap_type_handle) : base_class(Compare(), allocator(type_handle)) { }
pmap(const pmap<Key, Value, Compare> &copy) : 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 Key, class Value, class Compare = less<Key> >
class pmultimap : public multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > > {
public:
pmultimap() : multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >() { }
pmultimap(const pmultimap<Key, Value, Compare> &copy) : multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >(copy) { }
pmultimap(const Compare &comp) : multimap<Key, Value, Compare, pallocator_single<pair<const Key, Value> > >(comp) { }
typedef pallocator_single<pair<const Key, Value> > allocator;
pmultimap(TypeHandle type_handle = pmap_type_handle) : multimap<Key, Value, Compare, allocator>(Compare(), allocator(type_handle)) { }
pmultimap(const pmultimap<Key, Value, Compare> &copy) : multimap<Key, Value, Compare, allocator>(copy) { }
pmultimap(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : multimap<Key, Value, Compare, allocator>(comp, allocator(type_handle)) { }
};
#ifdef HAVE_STL_HASH

View File

@ -22,6 +22,7 @@
#include "dtoolbase.h"
#include "pallocator.h"
#include "stl_compares.h"
#include "register_type.h"
#include <set>
#ifdef HAVE_STL_HASH
@ -54,10 +55,11 @@
template<class Key, class Compare = less<Key> >
class pset : public set<Key, Compare, pallocator_single<Key> > {
public:
typedef set<Key, Compare, pallocator_single<Key> > base_class;
pset() : base_class() { }
typedef pallocator_single<Key> allocator;
typedef set<Key, Compare, allocator> base_class;
pset(TypeHandle type_handle = pmap_type_handle) : base_class(Compare(), allocator(type_handle)) { }
pset(const pset<Key, Compare> &copy) : 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<TYPENAME base_class::iterator, bool>
@ -115,9 +117,10 @@ public:
template<class Key, class Compare = less<Key> >
class pmultiset : public multiset<Key, Compare, pallocator_single<Key> > {
public:
pmultiset() : multiset<Key, Compare, pallocator_single<Key> >() { }
pmultiset(const pmultiset<Key, Compare> &copy) : multiset<Key, Compare, pallocator_single<Key> >(copy) { }
pmultiset(const Compare &comp) : multiset<Key, Compare, pallocator_single<Key> >(comp) { }
typedef pallocator_single<Key> allocator;
pmultiset(TypeHandle type_handle = pmap_type_handle) : multiset<Key, Compare, allocator>(Compare(), allocator(type_handle)) { }
pmultiset(const pmultiset<Key, Compare> &copy) : multiset<Key, Compare, allocator>(copy) { }
pmultiset(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : multiset<Key, Compare, allocator>(comp, type_handle) { }
};
#ifdef HAVE_STL_HASH

View File

@ -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 Type>
class pvector : public vector<Type, pallocator_array<Type> > {
public:
typedef vector<Type, pallocator_array<Type> > base_class;
typedef pallocator_array<Type> allocator;
typedef vector<Type, allocator> 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<Type> &copy) : 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

View File

@ -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");
}
}

View File

@ -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;

View File

@ -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";
}

View File

@ -21,7 +21,6 @@
#include "dtoolbase.h"
#include "typeRegistry.h"
#include "pnotify.h"
#include <set>
@ -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 &copy);
@ -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.

View File

@ -21,20 +21,12 @@
#include "typeHandle.h"
#include "typedObject.h"
#include "indent.h"
#include "config_interrogatedb.h"
#include "configVariableBool.h"
#include <algorithm>
// 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<int> &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<int> &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);
}

View File

@ -21,12 +21,11 @@
#include "dtoolbase.h"
#include "mutexImpl.h"
#include "pnotify.h"
#include "pvector.h"
#include "pmap.h"
#include "memoryBase.h"
#include <set>
#include <map>
#include <vector>
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<TypeRegistryNode *> HandleRegistry;
typedef vector<TypeRegistryNode *> HandleRegistry;
HandleRegistry _handle_registry;
typedef phash_map<string, TypeRegistryNode *, string_hash> NameRegistry;
typedef map<string, TypeRegistryNode *> NameRegistry;
NameRegistry _name_registry;
typedef pvector<TypeRegistryNode *> RootClasses;
typedef vector<TypeRegistryNode *> 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<int> &set);
extern "C" EXPCL_DTOOL int get_best_parent_from_Set(int id, const std::set<int> &set);
#include "typeRegistry.I"

View File

@ -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

View File

@ -17,11 +17,10 @@
////////////////////////////////////////////////////////////////////
#include "typeRegistryNode.h"
#include "config_interrogatedb.h"
#include <algorithm>
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());

View File

@ -23,7 +23,7 @@
#include "typeHandle.h"
#include "pvector.h"
#include <vector>
////////////////////////////////////////////////////////////////////
// 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<TypeRegistryNode *> Classes;
typedef vector<TypeRegistryNode *> 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<Inherit> TopInheritance;
typedef vector<Inherit> TopInheritance;
void r_build_subtrees(TypeRegistryNode *top,
int bit_count, SubtreeMaskType bits);

View File

@ -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;
}

View File

@ -105,7 +105,7 @@
// }
//
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG TypedObject : public MemoryBase {
class EXPCL_DTOOL TypedObject : public MemoryBase {
public:
INLINE TypedObject();
INLINE TypedObject(const TypedObject &copy);

View File

@ -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 \

View File

@ -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;

View File

@ -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

View File

@ -1,4 +1,4 @@
#include "config_dtoolutil.cxx"
#include "filename.cxx"
#include "load_dso.cxx"
#include "dSearchPath.cxx"

View File

@ -51,6 +51,7 @@
#include <unistd.h>
#endif
TypeHandle Filename::_type_handle;
#ifdef WIN32
/* begin Win32-specific code */

View File

@ -20,7 +20,8 @@
#define FILENAME_H
#include "dtoolbase.h"
#include "typeHandle.h"
#include "register_type.h"
#include "vector_string.h"
#include <assert.h>
@ -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) {

View File

@ -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<Systems::iterator, bool> 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;
}

View File

@ -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) {

View File

@ -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

View File

@ -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"

View File

@ -477,7 +477,7 @@ sort_declarations() {
// need to be recomputed all that often.
_unique_declarations.clear();
pset<string> already_added;
pset<string> already_added(TypeHandle::none());
for (di = _trusted_declarations.begin();
di != _trusted_declarations.end();
++di) {

View File

@ -334,6 +334,7 @@ init_libdisplay() {
initialized = true;
DisplayRegion::init_type();
DisplayRegionPipelineReader::init_type();
GraphicsBuffer::init_type();
GraphicsDevice::init_type();
GraphicsOutput::init_type();

View File

@ -25,6 +25,7 @@
#include "pnmImage.h"
TypeHandle DisplayRegion::_type_handle;
TypeHandle DisplayRegionPipelineReader::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::Constructor

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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<CDataCache> CDCacheReader;
typedef CycleDataWriter<CDataCache> CDCacheWriter;
@ -229,6 +240,17 @@ public:
CacheKey _key;
PipelineCycler<CDataCache> _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<const CacheKey *, PT(CacheEntry), IndirectLess<CacheKey> > 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<CData> _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);

View File

@ -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");

View File

@ -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);

View File

@ -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"));

View File

@ -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);

View File

@ -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");

View File

@ -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<CDataCache> CDCacheReader;
typedef CycleDataWriter<CDataCache> CDCacheWriter;
@ -228,6 +239,17 @@ public:
CacheKey _key;
PipelineCycler<CDataCache> _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<const CacheKey *, PT(CacheEntry), IndirectLess<CacheKey> > 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<CData> _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<GeomVertexArrayDataPipelineReader *> 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<GeomVertexArrayDataPipelineWriter *> 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);

View File

@ -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();

View File

@ -21,6 +21,8 @@
#include "pandaNode.h"
#include "indent.h"
TypeHandle FindApproxLevelEntry::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FindApproxLevelEntry::output
// Access: Public

View File

@ -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 &

View File

@ -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;
////////////////////////////////////////////////////////////////////

View File

@ -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<CData> _cycler;
@ -116,6 +127,7 @@ public:
ReferenceCount::init_type();
register_type(_type_handle, "NodePathComponent",
ReferenceCount::get_class_type());
CData::init_type();
}
private:

View File

@ -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

View File

@ -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<CData> _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) {

View File

@ -22,6 +22,8 @@
#include "pandabase.h"
#include "typedObject.h"
#include "pmap.h"
#include "pvector.h"
class PNMFileType;

View File

@ -25,6 +25,9 @@
#include "typedObject.h"
#include "filename.h"
#include "pnotify.h"
#include "pmap.h"
#include "pvector.h"
class PNMFileType;
class PNMReader;

View File

@ -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<TypeHandleCollector> 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();
}

View File

@ -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 &copy) {
_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

View File

@ -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 &copy);
INLINE void operator = (const PStatCollector &copy);
INLINE bool is_valid() const;
INLINE bool is_active();
INLINE bool is_started();
INLINE void start();

View File

@ -24,6 +24,7 @@
#include "numeric_types.h"
#include "typedObject.h"
#include "indent.h"
#include "pnotify.h"
#include "checksumHashGenerator.h"