open_toontown_panda3d/panda/src/express/memoryInfo.cxx

154 lines
5.2 KiB
C++

// Filename: memoryInfo.cxx
// Created by: drose (04Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifdef DO_MEMORY_USAGE
#include "memoryInfo.h"
#include "typedReferenceCount.h"
#include "typeHandle.h"
////////////////////////////////////////////////////////////////////
// Function: MemoryInfo::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
MemoryInfo::
MemoryInfo() {
_void_ptr = (void *)NULL;
_ref_ptr = (ReferenceCount *)NULL;
_typed_ptr = (TypedObject *)NULL;
_size = 0;
_static_type = TypeHandle::none();
_dynamic_type = TypeHandle::none();
_flags = 0;
}
////////////////////////////////////////////////////////////////////
// Function: MemoryInfo::get_type
// Access: Public
// Description: Returns the best known type, dynamic or static, of
// the pointer.
////////////////////////////////////////////////////////////////////
TypeHandle MemoryInfo::
get_type() {
// If we don't want to consider the dynamic type any further, use
// what we've got.
if ((_flags & F_reconsider_dynamic_type) == 0) {
if (_dynamic_type == TypeHandle::none()) {
return _static_type;
}
return _dynamic_type;
}
// Otherwise, examine the pointer again and make sure it's still the
// best information we have. We have to do this each time because
// if we happen to be examining the pointer from within the
// constructor or destructor, its dynamic type will appear to be
// less-specific than it actually is, so our idea of what type this
// thing is could change from time to time.
determine_dynamic_type();
// Now return the more specific of the two.
TypeHandle type = _static_type;
update_type_handle(type, _dynamic_type);
return type;
}
////////////////////////////////////////////////////////////////////
// Function: MemoryInfo::determine_dynamic_type
// Access: Public
// Description: Tries to determine the actual type of the object to
// which this thing is pointed, if possible.
////////////////////////////////////////////////////////////////////
void MemoryInfo::
determine_dynamic_type() {
if ((_flags & F_reconsider_dynamic_type) != 0 &&
_static_type != TypeHandle::none()) {
// See if we know enough now to infer the dynamic type from the
// pointer.
if (_typed_ptr == (TypedObject *)NULL) {
// If our static type is known to inherit from
// TypedReferenceCount, then we can directly downcast to get the
// TypedObject pointer.
if (_static_type.is_derived_from(TypedReferenceCount::get_class_type())) {
_typed_ptr = (TypedReferenceCount *)_ref_ptr;
}
}
if (_typed_ptr != (TypedObject *)NULL) {
// If we have a TypedObject pointer, we can determine the type.
// This might still not return the exact type, particularly if
// we are being called within the destructor or constructor of
// this object.
TypeHandle got_type = _typed_ptr->get_type();
if (got_type == TypeHandle::none()) {
express_cat.warning()
<< "Found an unregistered type in a " << _static_type
<< " pointer:\n"
<< "Check derived types of " << _static_type
<< " and make sure that all are being initialized.\n";
_dynamic_type = _static_type;
_flags &= ~F_reconsider_dynamic_type;
return;
}
update_type_handle(_dynamic_type, got_type);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: MemoryInfo::update_type_handle
// Access: Public
// Description: Updates the given destination TypeHandle with the
// refined TypeHandle, if it is in fact more specific
// than the original value for the destination.
////////////////////////////////////////////////////////////////////
void MemoryInfo::
update_type_handle(TypeHandle &destination, TypeHandle refined) {
if (refined == TypeHandle::none()) {
express_cat.error()
<< "Attempt to update type of " << (void *)_ref_ptr
<< "(type is " << get_type()
<< ") to an undefined type!\n";
} else if (destination == refined) {
// Updating with the same type, no problem.
} else if (destination.is_derived_from(refined)) {
// Updating with a less-specific type, no problem.
} else if (refined.is_derived_from(destination)) {
// Updating with a more-specific type, no problem.
destination = refined;
} else {
express_cat.error()
<< "Pointer " << (void *)_ref_ptr << " previously indicated as type "
<< destination << " is now type " << refined << "!\n";
destination = refined;
}
}
#endif // DO_MEMORY_USAGE