runtime improvements

This commit is contained in:
David Rose 2005-05-10 22:43:44 +00:00
parent 9263c24050
commit 0bd34f9f4b
29 changed files with 257 additions and 369 deletions

View File

@ -289,7 +289,7 @@
// to help track memory leaks, and also report total memory usage on
// PStats. There is some small overhead for having this ability
// available, even if it is unused.
#defer DO_MEMORY_USAGE $[<= $[OPTIMIZE], 3]
#defer DO_MEMORY_USAGE $[<= $[OPTIMIZE], 2]
// Do you want to compile in support for pipelining? This enables
// setting and accessing multiple different copies of frame-specific

View File

@ -371,12 +371,52 @@ release_index_buffer(IndexBufferContext *) {
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_geom_munger
// Access: Public
// Description: Looks up or creates a GeomMunger object to munge
// vertices appropriate to this GSG for the indicated
// state.
////////////////////////////////////////////////////////////////////
PT(qpGeomMunger) GraphicsStateGuardian::
get_geom_munger(const RenderState *state) {
// Before we even look up the map, see if the _last_mi value points
// to this GSG. This is likely because we tend to visit the same
// state multiple times during a frame. Also, this might well be
// the only GSG in the world anyway.
if (!state->_mungers.empty()) {
RenderState::Mungers::const_iterator mi = state->_last_mi;
if ((*mi).first == this && !(*mi).first.was_deleted()) {
return (*mi).second;
}
}
// Nope, we have to loop up in the map.
RenderState::Mungers::const_iterator mi = state->_mungers.find(this);
if (mi != state->_mungers.end() && !(*mi).first.was_deleted()) {
((RenderState *)state)->_last_mi = mi;
return (*mi).second;
}
// Nothing in the map; create a new entry.
PT(qpGeomMunger) munger = make_geom_munger(state);
// Cast the RenderState to a non-const object. We can do this
// because we are only updating a cache within the RenderState, not
// really changing any of its properties.
RenderState *nc_state = (RenderState *)state;
mi = nc_state->_mungers.insert(RenderState::Mungers::value_type(this, munger)).first;
nc_state->_last_mi = mi;
return munger;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::make_geom_munger
// Access: Public, Virtual
// Description: Creates a new GeomMunger object to munge vertices
// appropriate to this GSG for the indicated state.
////////////////////////////////////////////////////////////////////
PT(qpGeomMunger) GraphicsStateGuardian::
get_geom_munger(const RenderState *state) {
make_geom_munger(const RenderState *state) {
// The default implementation returns no munger at all, but
// presumably, every kind of GSG needs some special munging action,
// so real GSG's will override this to return something more

View File

@ -122,7 +122,8 @@ public:
virtual IndexBufferContext *prepare_index_buffer(qpGeomPrimitive *data);
virtual void release_index_buffer(IndexBufferContext *ibc);
virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state);
PT(qpGeomMunger) get_geom_munger(const RenderState *state);
virtual PT(qpGeomMunger) make_geom_munger(const RenderState *state);
virtual void set_state_and_transform(const RenderState *state,
const TransformState *transform);

View File

@ -3550,13 +3550,13 @@ release_index_buffer(IndexBufferContext *ibc) {
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::get_geom_munger
// Function: DXGraphicsStateGuardian8::make_geom_munger
// Access: Public, Virtual
// Description: Creates a new GeomMunger object to munge vertices
// appropriate to this GSG for the indicated state.
////////////////////////////////////////////////////////////////////
PT(qpGeomMunger) DXGraphicsStateGuardian8::
get_geom_munger(const RenderState *state) {
make_geom_munger(const RenderState *state) {
PT(DXGeomMunger8) munger = new DXGeomMunger8(this, state);
return qpGeomMunger::register_munger(munger);
}

View File

@ -115,7 +115,7 @@ public:
void apply_index_buffer(IndexBufferContext *ibc);
virtual void release_index_buffer(IndexBufferContext *ibc);
virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state);
virtual PT(qpGeomMunger) make_geom_munger(const RenderState *state);
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb);

View File

@ -39,6 +39,16 @@ PointerTo(const PointerTo<T> &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: PointerTo::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class T>
INLINE PointerTo<T>::
~PointerTo() {
}
////////////////////////////////////////////////////////////////////
// Function: PointerTo::Dereference operator
// Access: Public
@ -138,6 +148,16 @@ ConstPointerTo(const PointerTo<T> &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: ConstPointerTo::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class T>
INLINE ConstPointerTo<T>::
~ConstPointerTo() {
}
////////////////////////////////////////////////////////////////////
// Function: ConstPointerTo::Copy Constructor
// Access: Public

View File

@ -85,6 +85,7 @@ public:
PUBLISHED:
INLINE PointerTo(To *ptr = (To *)NULL);
INLINE PointerTo(const PointerTo<T> &copy);
INLINE ~PointerTo();
public:
INLINE To &operator *() const;
@ -142,6 +143,7 @@ PUBLISHED:
INLINE ConstPointerTo(const To *ptr = (const To *)NULL);
INLINE ConstPointerTo(const PointerTo<T> &copy);
INLINE ConstPointerTo(const ConstPointerTo<T> &copy);
INLINE ~ConstPointerTo();
public:
INLINE const To &operator *() const;

View File

@ -58,7 +58,7 @@ INLINE PointerToBase<T>::
// reference count and increment the new one.
////////////////////////////////////////////////////////////////////
template<class T>
void PointerToBase<T>::
INLINE void PointerToBase<T>::
reassign(To *ptr) {
if (ptr != (To *)_void_ptr) {
// First save the old pointer; we won't delete it until we have
@ -73,16 +73,7 @@ reassign(To *ptr) {
ptr->ref();
#ifdef DO_MEMORY_USAGE
if (MemoryUsage::get_track_memory_usage()) {
// Make sure the MemoryUsage record knows what the TypeHandle
// is, if we know it ourselves.
TypeHandle type = get_type_handle(To);
if (type == TypeHandle::none()) {
do_init_type(To);
type = get_type_handle(To);
}
if (type != TypeHandle::none()) {
MemoryUsage::update_type(ptr, type);
}
update_type(ptr);
}
#endif
}
@ -105,6 +96,28 @@ reassign(const PointerToBase<To> &copy) {
reassign((To *)copy._void_ptr);
}
#ifdef DO_MEMORY_USAGE
////////////////////////////////////////////////////////////////////
// Function: PointerToBase::update_type
// Access: Protected
// Description: Ensures that the MemoryUsage record for the pointer
// has the right type of object, if we know the type
// ourselves.
////////////////////////////////////////////////////////////////////
template<class T>
void PointerToBase<T>::
update_type(To *ptr) {
TypeHandle type = get_type_handle(To);
if (type == TypeHandle::none()) {
do_init_type(To);
type = get_type_handle(To);
}
if (type != TypeHandle::none()) {
MemoryUsage::update_type(ptr, type);
}
}
#endif // DO_MEMORY_USAGE
////////////////////////////////////////////////////////////////////
// Function: PointerToBase::clear

View File

@ -42,9 +42,13 @@ protected:
INLINE PointerToBase(const PointerToBase<T> &copy);
INLINE ~PointerToBase();
void reassign(To *ptr);
INLINE void reassign(To *ptr);
INLINE void reassign(const PointerToBase<To> &copy);
#ifdef DO_MEMORY_USAGE
void update_type(To *ptr);
#endif // DO_MEMORY_USAGE
// No assignment or retrieval functions are declared in
// PointerToBase, because we will have to specialize on const
// vs. non-const later.

View File

@ -59,157 +59,6 @@ get_hash() const {
return (size_t)_void_ptr;
}
#if 0
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Equivalence operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator == (const void *other) const {
return _void_ptr == other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Nonequivalence operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator != (const void *other) const {
return _void_ptr != other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Greater-than operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator > (const void *other) const {
return _void_ptr > other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Less-than-or-equal operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator <= (const void *other) const {
return _void_ptr <= other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Greater-than-or-equal operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator >= (const void *other) const {
return _void_ptr >= other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Equivalence operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator == (void *other) const {
return _void_ptr == other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Nonequivalence operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator != (void *other) const {
return _void_ptr != other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Greater-than operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator > (void *other) const {
return _void_ptr > other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Less-than-or-equal operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator <= (void *other) const {
return _void_ptr <= other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Greater-than-or-equal operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator >= (void *other) const {
return _void_ptr >= other;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Equivalence operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator == (const PointerToVoid &other) const {
return _void_ptr == other._void_ptr;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Nonequivalence operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator != (const PointerToVoid &other) const {
return _void_ptr != other._void_ptr;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Greater-than operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator > (const PointerToVoid &other) const {
return _void_ptr > other._void_ptr;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Less-than-or-equal operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator <= (const PointerToVoid &other) const {
return _void_ptr <= other._void_ptr;
}
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Greater-than-or-equal operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PointerToVoid::
operator >= (const PointerToVoid &other) const {
return _void_ptr >= other._void_ptr;
}
#endif // WIN32_VC
////////////////////////////////////////////////////////////////////
// Function: PointerToVoid::Less-than operator
// Access: Public

View File

@ -45,24 +45,6 @@ PUBLISHED:
public:
// These comparison functions are common to all things PointerTo, so
// they're defined up here.
#if 0
INLINE bool operator == (const void *other) const;
INLINE bool operator != (const void *other) const;
INLINE bool operator > (const void *other) const;
INLINE bool operator <= (const void *other) const;
INLINE bool operator >= (const void *other) const;
INLINE bool operator == (void *other) const;
INLINE bool operator != (void *other) const;
INLINE bool operator > (void *other) const;
INLINE bool operator <= (void *other) const;
INLINE bool operator >= (void *other) const;
INLINE bool operator == (const PointerToVoid &other) const;
INLINE bool operator != (const PointerToVoid &other) const;
INLINE bool operator > (const PointerToVoid &other) const;
INLINE bool operator <= (const PointerToVoid &other) const;
INLINE bool operator >= (const PointerToVoid &other) const;
#endif // WIN32_VC
INLINE bool operator < (const void *other) const;
INLINE bool operator < (const PointerToVoid &other) const;

View File

@ -188,21 +188,7 @@ get_ref_count() const {
////////////////////////////////////////////////////////////////////
INLINE int ReferenceCount::
ref() const {
nassertr(this != NULL, 0);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertr(_ref_count != deleted_ref_count, 0);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertr(_ref_count >= 0, 0);
nassertr(test_ref_count_integrity(), 0);
return AtomicAdjust::inc(((ReferenceCount *)this)->_ref_count);
}
@ -234,26 +220,12 @@ ref() const {
////////////////////////////////////////////////////////////////////
INLINE int ReferenceCount::
unref() const {
nassertr(this != NULL, false);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertr(_ref_count != deleted_ref_count, false);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertr(_ref_count >= 0, false);
nassertr(test_ref_count_integrity(), 0);
// If this assertion fails, you tried to unref an object with a
// zero reference count. Are you using ref() and unref()
// directly? Are you sure you can't use PointerTo's?
nassertr(_ref_count > 0, false);
nassertr(_ref_count > 0, 0);
return AtomicAdjust::dec(((ReferenceCount *)this)->_ref_count);
}
@ -262,26 +234,15 @@ unref() const {
// Function: ReferenceCount::test_ref_count_integrity
// Access: Published
// Description: Does some easy checks to make sure that the reference
// count isn't completely bogus.
// count isn't completely bogus. Returns true if ok,
// false otherwise.
////////////////////////////////////////////////////////////////////
INLINE void ReferenceCount::
INLINE bool ReferenceCount::
test_ref_count_integrity() const {
#ifndef NDEBUG
nassertv(this != NULL);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertv(_ref_count != deleted_ref_count);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertv(_ref_count >= 0);
return do_test_ref_count_integrity();
#else
return true;
#endif
}

View File

@ -20,3 +20,31 @@
#include "referenceCount.h"
TypeHandle ReferenceCount::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ReferenceCount::do_test_ref_count_integrity
// Access: Protected
// Description: Does some easy checks to make sure that the reference
// count isn't completely bogus. Returns true if ok,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool ReferenceCount::
do_test_ref_count_integrity() const {
nassertr(this != NULL, false);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertr(_ref_count != deleted_ref_count, false);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertr(_ref_count >= 0, false);
return true;
}

View File

@ -51,7 +51,7 @@ PUBLISHED:
INLINE int ref() const;
INLINE int unref() const;
INLINE void test_ref_count_integrity() const;
INLINE bool test_ref_count_integrity() const;
public:
INLINE void local_object();
@ -61,6 +61,9 @@ public:
INLINE void weak_ref(WeakPointerToVoid *ptv);
INLINE void weak_unref(WeakPointerToVoid *ptv);
protected:
bool do_test_ref_count_integrity() const;
private:
enum {
// We use this value as a flag to indicate an object has been

View File

@ -3210,13 +3210,13 @@ setup_primitive(const qpGeomPrimitive *data) {
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::get_geom_munger
// Function: GLGraphicsStateGuardian::make_geom_munger
// Access: Public, Virtual
// Description: Creates a new GeomMunger object to munge vertices
// appropriate to this GSG for the indicated state.
////////////////////////////////////////////////////////////////////
PT(qpGeomMunger) CLP(GraphicsStateGuardian)::
get_geom_munger(const RenderState *state) {
make_geom_munger(const RenderState *state) {
PT(CLP(GeomMunger)) munger = new CLP(GeomMunger)(this, state);
return qpGeomMunger::register_munger(munger);
}

View File

@ -123,7 +123,7 @@ public:
virtual void release_index_buffer(IndexBufferContext *ibc);
const unsigned char *setup_primitive(const qpGeomPrimitive *data);
virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state);
virtual PT(qpGeomMunger) make_geom_munger(const RenderState *state);
virtual void framebuffer_copy_to_texture
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);

View File

@ -54,22 +54,3 @@ get_bin(int bin_index) {
}
return make_new_bin(bin_index);
}
////////////////////////////////////////////////////////////////////
// Function: CullResult::get_geom_munger
// Access: Private
// Description: Returns a suitable GeomMunger for the indicated
// state. This will ask the GSG to create a new munger
// if we haven't already created one for this state;
// otherwise, it will return the existing one.
////////////////////////////////////////////////////////////////////
INLINE PT(qpGeomMunger) CullResult::
get_geom_munger(const RenderState *state) {
Mungers::iterator mi = _mungers.find(state);
if (mi != _mungers.end()) {
return (*mi).second;
}
PT(qpGeomMunger) munger = _gsg->get_geom_munger(state);
_mungers.insert(Mungers::value_type(state, munger));
return munger;
}

View File

@ -129,7 +129,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
get_dual_transparent_state();
transparent_part->_state = state->compose(transparent_state);
transparent_part->munge_geom
(_gsg, get_geom_munger(transparent_part->_state),
(_gsg, _gsg->get_geom_munger(transparent_part->_state),
traverser);
CullBin *bin = get_bin(transparent_part->_state->get_bin_index());
nassertv(bin != (CullBin *)NULL);
@ -157,7 +157,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
// Munge vertices as needed for the GSG's requirements, and the
// object's current state.
object->munge_geom(_gsg, get_geom_munger(object->_state), traverser);
object->munge_geom(_gsg, _gsg->get_geom_munger(object->_state), traverser);
CullBin *bin = get_bin(object->_state->get_bin_index());
nassertv(bin != (CullBin *)NULL);

View File

@ -66,7 +66,6 @@ public:
private:
CullBin *make_new_bin(int bin_index);
INLINE PT(qpGeomMunger) get_geom_munger(const RenderState *state);
static CPT(RenderState) get_binary_state();
static CPT(RenderState) get_dual_transparent_state();
@ -75,9 +74,6 @@ private:
GraphicsStateGuardianBase *_gsg;
typedef pmap<CPT(RenderState), PT(qpGeomMunger) > Mungers;
Mungers _mungers;
typedef pvector< PT(CullBin) > Bins;
Bins _bins;
};

View File

@ -65,6 +65,7 @@ RenderState() {
}
_saved_entry = _states->end();
_flags = 0;
_last_mi = _mungers.end();
}
////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,8 @@
#include "renderModeAttrib.h"
#include "texGenAttrib.h"
#include "texMatrixAttrib.h"
#include "qpgeomMunger.h"
#include "weakPointerTo.h"
class GraphicsStateGuardianBase;
class FogAttrib;
@ -215,6 +217,16 @@ private:
CompositionCache _composition_cache;
CompositionCache _invert_composition_cache;
// This is here to provide a quick cache of GSG + RenderState ->
// GeomMunger for the cull phase. It is here because it is faster
// to look up the GSG in the RenderState pointer than vice-versa,
// since there are likely to be far fewer GSG's than RenderStates.
// The code to manage this map lives in
// GraphicsStateGuardian::get_geom_munger().
typedef pmap<WCPT(GraphicsStateGuardianBase), PT(qpGeomMunger) > Mungers;
Mungers _mungers;
Mungers::const_iterator _last_mi;
// This is used to mark nodes as we visit them to detect cycles.
UpdateSeq _cycle_detect;
static UpdateSeq _last_cycle_detect;
@ -305,6 +317,8 @@ public:
private:
static TypeHandle _type_handle;
friend class GraphicsStateGuardian;
};
INLINE ostream &operator << (ostream &out, const RenderState &state) {

View File

@ -157,21 +157,7 @@ get_cache_ref_count() const {
////////////////////////////////////////////////////////////////////
INLINE int CachedTypedWritableReferenceCount::
cache_ref() const {
nassertr(this != NULL, 0);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertr(_cache_ref_count != -100, 0);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertr(_cache_ref_count >= 0, 0);
nassertr(test_ref_count_integrity(), 0);
ref();
return AtomicAdjust::inc(((CachedTypedWritableReferenceCount *)this)->_cache_ref_count);
@ -204,58 +190,29 @@ cache_ref() const {
////////////////////////////////////////////////////////////////////
INLINE int CachedTypedWritableReferenceCount::
cache_unref() const {
nassertr(this != NULL, false);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertr(_cache_ref_count != -100, false);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertr(_cache_ref_count >= 0, false);
nassertr(test_ref_count_integrity(), 0);
// If this assertion fails, you tried to unref an object with a
// zero reference count. Are you using ref() and unref()
// directly? Are you sure you can't use PointerTo's?
nassertr(_cache_ref_count > 0, false);
nassertr(_cache_ref_count > 0, 0);
unref();
return AtomicAdjust::dec(((CachedTypedWritableReferenceCount *)this)->_cache_ref_count);
}
////////////////////////////////////////////////////////////////////
// Function: CachedTypedWritableReferenceCount::test_ref_count_integrity
// Access: Published
// Description: Does some easy checks to make sure that the reference
// count isn't completely bogus.
////////////////////////////////////////////////////////////////////
INLINE void CachedTypedWritableReferenceCount::
INLINE bool CachedTypedWritableReferenceCount::
test_ref_count_integrity() const {
#ifndef NDEBUG
nassertv(this != NULL);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertv(_cache_ref_count != -100);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertv(_cache_ref_count >= 0);
TypedWritableReferenceCount::test_ref_count_integrity();
return do_test_ref_count_integrity();
#else
return true;
#endif
}

View File

@ -19,3 +19,30 @@
#include "cachedTypedWritableReferenceCount.h"
TypeHandle CachedTypedWritableReferenceCount::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CachedTypedWritableReferenceCount::do_test_ref_count_integrity
// Access: Protected
// Description: Does some easy checks to make sure that the reference
// count isn't completely bogus.
////////////////////////////////////////////////////////////////////
bool CachedTypedWritableReferenceCount::
do_test_ref_count_integrity() const {
nassertr(this != NULL, false);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertr(_cache_ref_count != -100, false);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertr(_cache_ref_count >= 0, false);
return TypedWritableReferenceCount::do_test_ref_count_integrity();
}

View File

@ -52,7 +52,10 @@ PUBLISHED:
INLINE int get_cache_ref_count() const;
INLINE int cache_ref() const;
INLINE int cache_unref() const;
INLINE void test_ref_count_integrity() const;
INLINE bool test_ref_count_integrity() const;
protected:
bool do_test_ref_count_integrity() const;
private:
int _cache_ref_count;

View File

@ -157,21 +157,7 @@ get_node_ref_count() const {
////////////////////////////////////////////////////////////////////
INLINE int NodeCachedReferenceCount::
node_ref() const {
nassertr(this != NULL, 0);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertr(_node_ref_count != -100, 0);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertr(_node_ref_count >= 0, 0);
nassertr(test_ref_count_integrity(), 0);
ref();
return AtomicAdjust::inc(((NodeCachedReferenceCount *)this)->_node_ref_count);
@ -204,58 +190,29 @@ node_ref() const {
////////////////////////////////////////////////////////////////////
INLINE int NodeCachedReferenceCount::
node_unref() const {
nassertr(this != NULL, false);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertr(_node_ref_count != -100, false);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertr(_node_ref_count >= 0, false);
nassertr(test_ref_count_integrity(), 0);
// If this assertion fails, you tried to unref an object with a
// zero reference count. Are you using ref() and unref()
// directly? Are you sure you can't use PointerTo's?
nassertr(_node_ref_count > 0, false);
nassertr(_node_ref_count > 0, 0);
unref();
return AtomicAdjust::dec(((NodeCachedReferenceCount *)this)->_node_ref_count);
}
////////////////////////////////////////////////////////////////////
// Function: NodeCachedReferenceCount::test_ref_count_integrity
// Access: Published
// Description: Does some easy checks to make sure that the reference
// count isn't completely bogus.
////////////////////////////////////////////////////////////////////
INLINE void NodeCachedReferenceCount::
INLINE bool NodeCachedReferenceCount::
test_ref_count_integrity() const {
#ifndef NDEBUG
nassertv(this != NULL);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertv(_node_ref_count != -100);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertv(_node_ref_count >= 0);
CachedTypedWritableReferenceCount::test_ref_count_integrity();
return do_test_ref_count_integrity();
#else
return true;
#endif
}

View File

@ -20,3 +20,29 @@
TypeHandle NodeCachedReferenceCount::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: NodeCachedReferenceCount::do_test_ref_count_integrity
// Access: Protected
// Description: Does some easy checks to make sure that the reference
// count isn't completely bogus.
////////////////////////////////////////////////////////////////////
bool NodeCachedReferenceCount::
do_test_ref_count_integrity() const {
nassertr(this != NULL, false);
// If this assertion fails, we're trying to delete an object that
// was just deleted. Possibly you used a real pointer instead of a
// PointerTo at some point, and the object was deleted when the
// PointerTo went out of scope. Maybe you tried to create an
// automatic (local variable) instance of a class that derives from
// ReferenceCount. Or maybe your headers are out of sync, and you
// need to make clean in direct or some higher tree.
nassertr(_node_ref_count != -100, false);
// If this assertion fails, the reference counts are all screwed
// up altogether. Maybe some errant code stomped all over memory
// somewhere.
nassertr(_node_ref_count >= 0, false);
return CachedTypedWritableReferenceCount::do_test_ref_count_integrity();
}

View File

@ -59,7 +59,7 @@ PUBLISHED:
INLINE int get_node_ref_count() const;
INLINE int node_ref() const;
INLINE int node_unref() const;
INLINE void test_ref_count_integrity() const;
INLINE bool test_ref_count_integrity() const;
enum Referenced {
R_node = 0x001,
@ -67,6 +67,9 @@ PUBLISHED:
};
INLINE int get_referenced_bits() const;
protected:
bool do_test_ref_count_integrity() const;
private:
int _node_ref_count;

View File

@ -39,6 +39,16 @@ NodePointerTo(const NodePointerTo<T> &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: NodePointerTo::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class T>
INLINE NodePointerTo<T>::
~NodePointerTo() {
}
////////////////////////////////////////////////////////////////////
// Function: NodePointerTo::Dereference operator
// Access: Public
@ -150,6 +160,16 @@ NodeConstPointerTo(const NodeConstPointerTo<T> &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: NodeConstPointerTo::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class T>
INLINE NodeConstPointerTo<T>::
~NodeConstPointerTo() {
}
////////////////////////////////////////////////////////////////////
// Function: NodeConstPointerTo::Dereference operator
// Access: Public

View File

@ -24,9 +24,7 @@
////////////////////////////////////////////////////////////////////
// Class : NodePointerTo
// Description :
// This implements the special NodePointerTo template
// Description : This implements the special NodePointerTo template
// class, which works just like PointerTo except it
// manages the objects node_ref_count instead of the
// normal ref_count.
@ -37,6 +35,7 @@ public:
typedef TYPENAME NodePointerToBase<T>::To To;
INLINE NodePointerTo(To *ptr = (To *)NULL);
INLINE NodePointerTo(const NodePointerTo<T> &copy);
INLINE ~NodePointerTo();
INLINE To &operator *() const;
INLINE To *operator -> () const;
@ -61,6 +60,7 @@ public:
INLINE NodeConstPointerTo(const To *ptr = (const To *)NULL);
INLINE NodeConstPointerTo(const NodePointerTo<T> &copy);
INLINE NodeConstPointerTo(const NodeConstPointerTo<T> &copy);
INLINE ~NodeConstPointerTo();
INLINE const To &operator *() const;
INLINE const To *operator -> () const;