Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/express/memoryInfo.cxx

Go to the documentation of this file.
00001 // Filename: memoryInfo.cxx
00002 // Created by:  drose (04Jun01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #ifdef DO_MEMORY_USAGE
00020 
00021 #include "memoryInfo.h"
00022 #include "typedReferenceCount.h"
00023 #include "typeHandle.h"
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: MemoryInfo::Constructor
00027 //       Access: Public
00028 //  Description: 
00029 ////////////////////////////////////////////////////////////////////
00030 MemoryInfo::
00031 MemoryInfo() {
00032   _void_ptr = (void *)NULL;
00033   _ref_ptr = (ReferenceCount *)NULL;
00034   _typed_ptr = (TypedObject *)NULL;
00035   _size = 0;
00036   _static_type = TypeHandle::none();
00037   _dynamic_type = TypeHandle::none();
00038 
00039   _flags = 0;
00040 }
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function: MemoryInfo::get_type
00044 //       Access: Public
00045 //  Description: Returns the best known type, dynamic or static, of
00046 //               the pointer.
00047 ////////////////////////////////////////////////////////////////////
00048 TypeHandle MemoryInfo::
00049 get_type() {
00050   // If we don't want to consider the dynamic type any further, use
00051   // what we've got.
00052   if ((_flags & F_reconsider_dynamic_type) == 0) {
00053     if (_dynamic_type == TypeHandle::none()) {
00054       return _static_type;
00055     }
00056     return _dynamic_type;
00057   }
00058 
00059   // Otherwise, examine the pointer again and make sure it's still the
00060   // best information we have.  We have to do this each time because
00061   // if we happen to be examining the pointer from within the
00062   // constructor or destructor, its dynamic type will appear to be
00063   // less-specific than it actually is, so our idea of what type this
00064   // thing is could change from time to time.
00065   determine_dynamic_type();
00066 
00067   // Now return the more specific of the two.
00068   TypeHandle type = _static_type;
00069   update_type_handle(type, _dynamic_type);
00070 
00071   return type;
00072 }
00073 
00074 ////////////////////////////////////////////////////////////////////
00075 //     Function: MemoryInfo::determine_dynamic_type
00076 //       Access: Public
00077 //  Description: Tries to determine the actual type of the object to
00078 //               which this thing is pointed, if possible.
00079 ////////////////////////////////////////////////////////////////////
00080 void MemoryInfo::
00081 determine_dynamic_type() {
00082   if ((_flags & F_reconsider_dynamic_type) != 0 &&
00083       _static_type != TypeHandle::none()) {
00084     // See if we know enough now to infer the dynamic type from the
00085     // pointer.
00086 
00087     if (_typed_ptr == (TypedObject *)NULL) {
00088       // If our static type is known to inherit from
00089       // TypedReferenceCount, then we can directly downcast to get the
00090       // TypedObject pointer.
00091       if (_static_type.is_derived_from(TypedReferenceCount::get_class_type())) {
00092         _typed_ptr = (TypedReferenceCount *)_ref_ptr;
00093       }
00094     }
00095 
00096     if (_typed_ptr != (TypedObject *)NULL) {
00097       // If we have a TypedObject pointer, we can determine the type.
00098       // This might still not return the exact type, particularly if
00099       // we are being called within the destructor or constructor of
00100       // this object.
00101       TypeHandle got_type = _typed_ptr->get_type();
00102 
00103       if (got_type == TypeHandle::none()) {
00104         express_cat.warning()
00105           << "Found an unregistered type in a " << _static_type
00106           << " pointer:\n"
00107           << "Check derived types of " << _static_type
00108           << " and make sure that all are being initialized.\n";
00109         _dynamic_type = _static_type;
00110         _flags &= ~F_reconsider_dynamic_type;
00111         return;
00112       }
00113 
00114       update_type_handle(_dynamic_type, got_type);
00115     }
00116   }
00117 }
00118 
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: MemoryInfo::update_type_handle
00122 //       Access: Public
00123 //  Description: Updates the given destination TypeHandle with the
00124 //               refined TypeHandle, if it is in fact more specific
00125 //               than the original value for the destination.
00126 ////////////////////////////////////////////////////////////////////
00127 void MemoryInfo::
00128 update_type_handle(TypeHandle &destination, TypeHandle refined) {
00129   if (refined == TypeHandle::none()) {
00130     express_cat.error()
00131       << "Attempt to update type of " << (void *)_ref_ptr
00132       << "(type is " << get_type()
00133       << ") to an undefined type!\n";
00134 
00135   } else if (destination == refined) {
00136     // Updating with the same type, no problem.
00137 
00138   } else if (destination.is_derived_from(refined)) {
00139     // Updating with a less-specific type, no problem.
00140 
00141   } else if (refined.is_derived_from(destination)) {
00142     // Updating with a more-specific type, no problem.
00143     destination = refined;
00144 
00145   } else {
00146     express_cat.error()
00147       << "Pointer " << (void *)_ref_ptr << " previously indicated as type "
00148       << destination << " is now type " << refined << "!\n";
00149     destination = refined;
00150   }
00151 }
00152 
00153 #endif  // DO_MEMORY_USAGE

Generated on Fri May 2 00:38:24 2003 for Panda by doxygen1.3