Browse Source

more better pstats mem tracking

David Rose 19 years ago
parent
commit
d87cae471d
42 changed files with 425 additions and 288 deletions
  1. 6 0
      dtool/src/dtoolbase/register_type.cxx
  2. 13 0
      dtool/src/dtoolbase/register_type.h
  3. 1 1
      panda/src/chan/animChannelMatrixXfmTable.I
  4. 19 12
      panda/src/chan/animChannelMatrixXfmTable.cxx
  5. 10 12
      panda/src/chan/animChannelScalarTable.cxx
  6. 12 3
      panda/src/chan/animGroup.cxx
  7. 4 2
      panda/src/chan/partGroup.I
  8. 4 1
      panda/src/chan/partGroup.cxx
  9. 1 0
      panda/src/collide/collisionLevelStateBase.I
  10. 2 0
      panda/src/collide/collisionLevelStateBase.cxx
  11. 12 0
      panda/src/collide/collisionLevelStateBase.h
  12. 2 0
      panda/src/collide/collisionTraverser.cxx
  13. 12 0
      panda/src/collide/collisionTraverser.h
  14. 4 0
      panda/src/collide/config_collide.cxx
  15. 2 1
      panda/src/cull/cullBinStateSorted.I
  16. 4 2
      panda/src/egg2pg/animBundleMaker.cxx
  17. 44 6
      panda/src/express/ordered_vector.I
  18. 9 3
      panda/src/express/ordered_vector.h
  19. 15 0
      panda/src/express/pointerTo.h
  20. 44 110
      panda/src/express/pointerToArray.I
  21. 18 10
      panda/src/express/pointerToArray.h
  22. 4 65
      panda/src/express/pointerToArrayBase.I
  23. 2 12
      panda/src/express/pointerToArrayBase.h
  24. 3 2
      panda/src/gobj/geomVertexArrayData.I
  25. 5 12
      panda/src/gobj/geomVertexArrayData.cxx
  26. 0 4
      panda/src/gobj/geomVertexArrayData.h
  27. 8 18
      panda/src/gobj/texture.cxx
  28. 0 3
      panda/src/gobj/texture.h
  29. 3 3
      panda/src/pgraph/pandaNode.cxx
  30. 2 2
      panda/src/pgraph/pandaNode.h
  31. 2 0
      panda/src/pnmtext/Sources.pp
  32. 1 1
      panda/src/pnmtext/freetypeFont.h
  33. 1 1
      panda/src/pnmtext/pnmTextMaker.h
  34. 6 0
      panda/src/pstatclient/config_pstats.cxx
  35. 2 0
      panda/src/pstatclient/config_pstats.h
  36. 24 2
      panda/src/pstatclient/pStatClient.cxx
  37. 1 0
      panda/src/pstatclient/pStatClient.h
  38. 1 0
      panda/src/putil/buttonHandle.cxx
  39. 13 0
      panda/src/putil/buttonHandle.h
  40. 3 0
      panda/src/putil/config_util.cxx
  41. 73 0
      panda/src/putil/copyOnWriteObject.I
  42. 33 0
      panda/src/putil/copyOnWriteObject.h

+ 6 - 0
dtool/src/dtoolbase/register_type.cxx

@@ -21,7 +21,9 @@
 
 TypeHandle long_type_handle;
 TypeHandle int_type_handle;
+TypeHandle uint_type_handle;
 TypeHandle short_type_handle;
+TypeHandle ushort_type_handle;
 TypeHandle char_type_handle;
 TypeHandle uchar_type_handle;
 TypeHandle bool_type_handle;
@@ -39,6 +41,7 @@ TypeHandle float_p_type_handle;
 TypeHandle void_p_type_handle;
 
 TypeHandle pvector_type_handle;
+TypeHandle ov_set_type_handle;
 TypeHandle pdeque_type_handle;
 TypeHandle plist_type_handle;
 TypeHandle pmap_type_handle;
@@ -50,7 +53,9 @@ void init_system_type_handles() {
     done = true;
     register_type(long_type_handle, "long");
     register_type(int_type_handle, "int");
+    register_type(uint_type_handle, "uint");
     register_type(short_type_handle, "short");
+    register_type(ushort_type_handle, "ushort");
     register_type(char_type_handle, "char");
     register_type(uchar_type_handle, "uchar");
     register_type(bool_type_handle, "bool");
@@ -67,6 +72,7 @@ void init_system_type_handles() {
     register_type(void_p_type_handle, "void*");
 
     register_type(pvector_type_handle, "pvector");
+    register_type(ov_set_type_handle, "ov_set");
     register_type(pdeque_type_handle, "pdeque");
     register_type(plist_type_handle, "plist");
     register_type(pmap_type_handle, "pmap");

+ 13 - 0
dtool/src/dtoolbase/register_type.h

@@ -87,7 +87,9 @@ register_dynamic_type(const string &name,
 // A few system-wide TypeHandles are defined for some basic types.
 extern TypeHandle EXPCL_DTOOL long_type_handle;
 extern TypeHandle EXPCL_DTOOL int_type_handle;
+extern TypeHandle EXPCL_DTOOL uint_type_handle;
 extern TypeHandle EXPCL_DTOOL short_type_handle;
+extern TypeHandle EXPCL_DTOOL ushort_type_handle;
 extern TypeHandle EXPCL_DTOOL char_type_handle;
 extern TypeHandle EXPCL_DTOOL uchar_type_handle;
 extern TypeHandle EXPCL_DTOOL bool_type_handle;
@@ -105,6 +107,7 @@ extern TypeHandle float_p_type_handle;
 extern TypeHandle void_p_type_handle;
 
 extern TypeHandle EXPCL_DTOOL pvector_type_handle;
+extern TypeHandle EXPCL_DTOOL ov_set_type_handle;
 extern TypeHandle EXPCL_DTOOL pdeque_type_handle;
 extern TypeHandle EXPCL_DTOOL plist_type_handle;
 extern TypeHandle EXPCL_DTOOL pmap_type_handle;
@@ -131,11 +134,21 @@ INLINE TypeHandle _get_type_handle(const int *) {
   return int_type_handle;
 }
 
+template<>
+INLINE TypeHandle _get_type_handle(const unsigned int *) {
+  return uint_type_handle;
+}
+
 template<>
 INLINE TypeHandle _get_type_handle(const short *) {
   return short_type_handle;
 }
 
+template<>
+INLINE TypeHandle _get_type_handle(const unsigned short *) {
+  return ushort_type_handle;
+}
+
 template<>
 INLINE TypeHandle _get_type_handle(const char *) {
   return char_type_handle;

+ 1 - 1
panda/src/chan/animChannelMatrixXfmTable.I

@@ -38,7 +38,7 @@ INLINE CPTA_float AnimChannelMatrixXfmTable::
 get_table(char table_id) const {
   int table_index = get_table_index(table_id);
   if (table_index < 0) {
-    return CPTA_float();
+    return CPTA_float(get_class_type());
   }
   return _tables[table_index];
 }

+ 19 - 12
panda/src/chan/animChannelMatrixXfmTable.cxx

@@ -39,6 +39,9 @@ TypeHandle AnimChannelMatrixXfmTable::_type_handle;
 /////////////////////////////////////////////////////////////
 AnimChannelMatrixXfmTable::
 AnimChannelMatrixXfmTable() {
+  for (int i = 0; i < num_matrix_components; i++) {
+    _tables[i] = CPTA_float(get_class_type());
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -65,7 +68,11 @@ AnimChannelMatrixXfmTable(AnimGroup *parent, const AnimChannelMatrixXfmTable &co
 ////////////////////////////////////////////////////////////////////
 AnimChannelMatrixXfmTable::
 AnimChannelMatrixXfmTable(AnimGroup *parent, const string &name)
-  : AnimChannelMatrix(parent, name) {
+  : AnimChannelMatrix(parent, name) 
+{
+  for (int i = 0; i < num_matrix_components; i++) {
+    _tables[i] = CPTA_float(get_class_type());
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -279,7 +286,7 @@ set_table(char table_id, const CPTA_float &table) {
 void AnimChannelMatrixXfmTable::
 clear_all_tables() {
   for (int i = 0; i < num_matrix_components; i++) {
-    _tables[i] = NULL;
+    _tables[i] = CPTA_float(get_class_type());
   }
 }
 
@@ -431,7 +438,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
 
     for (int i = 0; i < num_matrix_components; i++) {
       int size = scan.get_uint16();
-      PTA_float ind_table;
+      PTA_float ind_table(get_class_type());
       for (int j = 0; j < size; j++) {
         ind_table.push_back(scan.get_float32());
       }
@@ -454,9 +461,9 @@ fillin(DatagramIterator &scan, BamReader *manager) {
         default_hpr[2] = _tables[8][0];
       }
 
-      PTA_float h_table = PTA_float::empty_array(num_hprs);
-      PTA_float p_table = PTA_float::empty_array(num_hprs);
-      PTA_float r_table = PTA_float::empty_array(num_hprs);
+      PTA_float h_table = PTA_float::empty_array(num_hprs, get_class_type());
+      PTA_float p_table = PTA_float::empty_array(num_hprs, get_class_type());
+      PTA_float r_table = PTA_float::empty_array(num_hprs, get_class_type());
 
       for (size_t hi = 0; hi < num_hprs; hi++) {
         float h = (hi < _tables[6].size() ? _tables[6][hi] : default_hpr[0]);
@@ -493,12 +500,12 @@ fillin(DatagramIterator &scan, BamReader *manager) {
     int i;
     // First, read in the scales and shears.
     for (i = 0; i < 3; i++) {
-      PTA_float ind_table = PTA_float::empty_array(0);
+      PTA_float ind_table = PTA_float::empty_array(0, get_class_type());
       compressor.read_reals(scan, ind_table.v());
       _tables[i] = ind_table;
     }
     for (i = 3; i < 6; i++) {
-      PTA_float ind_table = PTA_float::empty_array(0);
+      PTA_float ind_table = PTA_float::empty_array(0, get_class_type());
       compressor.read_reals(scan, ind_table.v());
       _tables[i] = ind_table;
     }
@@ -506,9 +513,9 @@ fillin(DatagramIterator &scan, BamReader *manager) {
     // Read in the HPR array and store it back in the joint angles.
     vector_LVecBase3f hprs;
     compressor.read_hprs(scan, hprs, new_hpr);
-    PTA_float h_table = PTA_float::empty_array(hprs.size());
-    PTA_float p_table = PTA_float::empty_array(hprs.size());
-    PTA_float r_table = PTA_float::empty_array(hprs.size());
+    PTA_float h_table = PTA_float::empty_array(hprs.size(), get_class_type());
+    PTA_float p_table = PTA_float::empty_array(hprs.size(), get_class_type());
+    PTA_float r_table = PTA_float::empty_array(hprs.size(), get_class_type());
 
     for (i = 0; i < (int)hprs.size(); i++) {
       if (!new_hpr && temp_hpr_fix) {
@@ -538,7 +545,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
 
     // Now read in the translations.
     for (i = 9; i < num_matrix_components; i++) {
-      PTA_float ind_table = PTA_float::empty_array(0);
+      PTA_float ind_table = PTA_float::empty_array(0, get_class_type());
       compressor.read_reals(scan, ind_table.v());
       _tables[i] = ind_table;
     }

+ 10 - 12
panda/src/chan/animChannelScalarTable.cxx

@@ -36,7 +36,7 @@ TypeHandle AnimChannelScalarTable::_type_handle;
 //  Description:
 ////////////////////////////////////////////////////////////////////
 AnimChannelScalarTable::
-AnimChannelScalarTable(){
+AnimChannelScalarTable() : _table(get_class_type()) {
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -60,8 +60,10 @@ AnimChannelScalarTable(AnimGroup *parent, const AnimChannelScalarTable &copy) :
 //  Description:
 ////////////////////////////////////////////////////////////////////
 AnimChannelScalarTable::
-AnimChannelScalarTable(AnimGroup *parent, const string &name)
-  : AnimChannelScalar(parent, name) {
+AnimChannelScalarTable(AnimGroup *parent, const string &name) :
+  AnimChannelScalar(parent, name),
+  _table(get_class_type())
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -159,8 +161,7 @@ make_copy(AnimGroup *parent) const {
 //               the particular object to a Datagram
 ////////////////////////////////////////////////////////////////////
 void AnimChannelScalarTable::
-write_datagram(BamWriter *manager, Datagram &me)
-{
+write_datagram(BamWriter *manager, Datagram &me) {
   AnimChannelScalar::write_datagram(manager, me);
 
   if (compress_channels && !FFTCompressor::is_compression_available()) {
@@ -272,13 +273,12 @@ write_datagram(BamWriter *manager, Datagram &me)
 //               place
 ////////////////////////////////////////////////////////////////////
 void AnimChannelScalarTable::
-fillin(DatagramIterator& scan, BamReader* manager)
-{
+fillin(DatagramIterator& scan, BamReader* manager) {
   AnimChannelScalar::fillin(scan, manager);
 
   bool wrote_compressed = scan.get_bool();
 
-  PTA_float temp_table=PTA_float::empty_array(0);
+  PTA_float temp_table = PTA_float::empty_array(0, get_class_type());
 
   if (!wrote_compressed) {
     // Regular floats.
@@ -343,8 +343,7 @@ fillin(DatagramIterator& scan, BamReader* manager)
 //  Description: Factory method to generate a AnimChannelScalarTable object
 ////////////////////////////////////////////////////////////////////
 TypedWritable* AnimChannelScalarTable::
-make_AnimChannelScalarTable(const FactoryParams &params)
-{
+make_AnimChannelScalarTable(const FactoryParams &params) {
   AnimChannelScalarTable *me = new AnimChannelScalarTable;
   DatagramIterator scan;
   BamReader *manager;
@@ -360,8 +359,7 @@ make_AnimChannelScalarTable(const FactoryParams &params)
 //  Description: Factory method to generate a AnimChannelScalarTable object
 ////////////////////////////////////////////////////////////////////
 void AnimChannelScalarTable::
-register_with_read_factory()
-{
+register_with_read_factory() {
   BamReader::get_factory()->register_factory(get_class_type(), make_AnimChannelScalarTable);
 }
 

+ 12 - 3
panda/src/chan/animGroup.cxx

@@ -45,7 +45,10 @@ TypeHandle AnimGroup::_type_handle;
 //               children.
 ////////////////////////////////////////////////////////////////////
 AnimGroup::
-AnimGroup(const string &name) : Namable(name) {
+AnimGroup(const string &name) : 
+  Namable(name),
+  _children(get_class_type())
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -57,7 +60,10 @@ AnimGroup(const string &name) : Namable(name) {
 //               make_copy() only.
 ////////////////////////////////////////////////////////////////////
 AnimGroup::
-AnimGroup(AnimGroup *parent, const AnimGroup &copy) : Namable(copy) {
+AnimGroup(AnimGroup *parent, const AnimGroup &copy) : 
+  Namable(copy),
+  _children(get_class_type())
+{
   if (parent != (AnimGroup *)NULL) {
     parent->_children.push_back(this);
     _root = parent->_root;
@@ -74,7 +80,10 @@ AnimGroup(AnimGroup *parent, const AnimGroup &copy) : Namable(copy) {
 //               delete the entire hierarchy.
 ////////////////////////////////////////////////////////////////////
 AnimGroup::
-AnimGroup(AnimGroup *parent, const string &name) : Namable(name) {
+AnimGroup(AnimGroup *parent, const string &name) : 
+  Namable(name),
+  _children(get_class_type())
+ {
   nassertv(parent != NULL);
 
   parent->_children.push_back(this);

+ 4 - 2
panda/src/chan/partGroup.I

@@ -26,7 +26,8 @@
 ////////////////////////////////////////////////////////////////////
 INLINE PartGroup::
 PartGroup(const string &name) :
-  Namable(name)
+  Namable(name),
+  _children(get_class_type())
 {
 }
 
@@ -39,7 +40,8 @@ PartGroup(const string &name) :
 ////////////////////////////////////////////////////////////////////
 INLINE PartGroup::
 PartGroup(const PartGroup &copy) :
-  Namable(copy)
+  Namable(copy),
+  _children(get_class_type())
 {
   // We don't copy children in the copy constructor.  However,
   // copy_subgraph() will do this.

+ 4 - 1
panda/src/chan/partGroup.cxx

@@ -39,7 +39,10 @@ TypeHandle PartGroup::_type_handle;
 //               delete the entire hierarchy.
 ////////////////////////////////////////////////////////////////////
 PartGroup::
-PartGroup(PartGroup *parent, const string &name) : Namable(name) {
+PartGroup(PartGroup *parent, const string &name) : 
+  Namable(name),
+  _children(get_class_type())
+{
   nassertv(parent != NULL);
 
   parent->_children.push_back(this);

+ 1 - 0
panda/src/collide/collisionLevelStateBase.I

@@ -25,6 +25,7 @@
 INLINE CollisionLevelStateBase::
 CollisionLevelStateBase(const NodePath &node_path) :
   _node_path(node_path),
+  _colliders(get_class_type()),
   _include_mask(CollideMask::all_on())
 {
 }

+ 2 - 0
panda/src/collide/collisionLevelStateBase.cxx

@@ -23,6 +23,8 @@
 
 PStatCollector CollisionLevelStateBase::_node_volume_pcollector("Collision Volumes:PandaNode");
 
+TypeHandle CollisionLevelStateBase::_type_handle;
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionLevelStateBase::clear
 //       Access: Public

+ 12 - 0
panda/src/collide/collisionLevelStateBase.h

@@ -30,6 +30,7 @@
 #include "plist.h"
 #include "pStatCollector.h"
 #include "bitMask.h"
+#include "register_type.h"
 
 class CollisionSolid;
 class CollisionNode;
@@ -90,6 +91,17 @@ protected:
 
   static PStatCollector _node_volume_pcollector;
 
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    register_type(_type_handle, "CollisionLevelStateBase");
+  }
+
+private:
+  static TypeHandle _type_handle;
+
   friend class CollisionTraverser;
 };
 

+ 2 - 0
panda/src/collide/collisionTraverser.cxx

@@ -48,6 +48,8 @@ PStatCollector CollisionTraverser::_cnode_volume_pcollector("Collision Volumes:C
 PStatCollector CollisionTraverser::_gnode_volume_pcollector("Collision Volumes:GeomNode");
 PStatCollector CollisionTraverser::_geom_volume_pcollector("Collision Volumes:Geom");
 
+TypeHandle CollisionTraverser::_type_handle;
+
 // This function object class is used in prepare_colliders(), below.
 class SortByColliderSort {
 public:

+ 12 - 0
panda/src/collide/collisionTraverser.h

@@ -28,6 +28,7 @@
 #include "pStatCollector.h"
 
 #include "pset.h"
+#include "register_type.h"
 
 class CollisionNode;
 class CollisionRecorder;
@@ -150,6 +151,17 @@ private:
   typedef pvector<PStatCollector> SolidCollideCollectors;
   SolidCollideCollectors _solid_collide_collectors;
 
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    register_type(_type_handle, "CollisionTraverser");
+  }
+
+private:
+  static TypeHandle _type_handle;
+
   friend class SortByColliderSort;
 };
 

+ 4 - 0
panda/src/collide/config_collide.cxx

@@ -28,6 +28,7 @@
 #include "collisionDSSolid.h"
 #include "collisionInvSphere.h"
 #include "collisionLine.h"
+#include "collisionLevelStateBase.h"
 #include "collisionNode.h"
 #include "collisionPlane.h"
 #include "collisionPolygon.h"
@@ -36,6 +37,7 @@
 #include "collisionSegment.h"
 #include "collisionSolid.h"
 #include "collisionSphere.h"
+#include "collisionTraverser.h"
 #include "collisionTube.h"
 #include "collisionVisualizer.h"
 #include "dconfig.h"
@@ -99,6 +101,7 @@ init_libcollide() {
   CollisionDSSolid::init_type();
   CollisionInvSphere::init_type();
   CollisionLine::init_type();
+  CollisionLevelStateBase::init_type();
   CollisionNode::init_type();
   CollisionPlane::init_type();
   CollisionPolygon::init_type();
@@ -106,6 +109,7 @@ init_libcollide() {
   CollisionSegment::init_type();
   CollisionSolid::init_type();
   CollisionSphere::init_type();
+  CollisionTraverser::init_type();
   CollisionTube::init_type();
 
 #ifdef DO_COLLISION_RECORDING

+ 2 - 1
panda/src/cull/cullBinStateSorted.I

@@ -25,7 +25,8 @@
 INLINE CullBinStateSorted::
 CullBinStateSorted(const string &name, GraphicsStateGuardianBase *gsg,
                    const PStatCollector &draw_region_pcollector) :
-  CullBin(name, BT_state_sorted, gsg, draw_region_pcollector)
+  CullBin(name, BT_state_sorted, gsg, draw_region_pcollector),
+  _objects(get_class_type())
 {
 }
 

+ 4 - 2
panda/src/egg2pg/animBundleMaker.cxx

@@ -240,7 +240,8 @@ create_s_channel(EggSAnimData *egg_anim, const string &name,
 
   // First we have to copy the table data from PTA_double to
   // PTA_float.
-  PTA_float new_data=PTA_float::empty_array(egg_anim->get_num_rows());
+  PTA_float new_data = PTA_float::empty_array(egg_anim->get_num_rows(),
+                                              table->get_class_type());
   for (int i = 0; i < egg_anim->get_num_rows(); i++) {
     new_data[i] = (float)egg_anim->get_value(i);
   }
@@ -325,7 +326,8 @@ create_xfm_channel(EggXfmSAnim *egg_anim, const string &name,
 
           // Now we have to copy the table data from PTA_double to
           // PTA_float.
-          PTA_float new_data=PTA_float::empty_array(child->get_num_rows());
+          PTA_float new_data=PTA_float::empty_array(child->get_num_rows(),
+                                                    table->get_class_type());
           for (int i = 0; i < child->get_num_rows(); i++) {
             new_data[i] = (float)child->get_value(i);
           }

+ 44 - 6
panda/src/express/ordered_vector.I

@@ -24,8 +24,22 @@
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Compare>
 INLINE ordered_vector<Key, Compare>::
-ordered_vector(const Compare &compare) :
-  _compare(compare)
+ordered_vector(TypeHandle type_handle) :
+  _compare(Compare()),
+  _vector(type_handle)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ordered_vector::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Key, class Compare>
+INLINE ordered_vector<Key, Compare>::
+ordered_vector(const Compare &compare, TypeHandle type_handle) :
+  _compare(compare),
+  _vector(type_handle)
 {
 }
 
@@ -721,8 +735,20 @@ find_insert_position(TYPENAME ordered_vector<Key, Compare>::ITERATOR first,
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Compare>
 INLINE ov_set<Key, Compare>::
-ov_set(const Compare &compare) :
-  ordered_vector<Key, Compare>(compare)
+ov_set(TypeHandle type_handle) :
+  ordered_vector<Key, Compare>(type_handle)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ov_set::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Key, class Compare>
+INLINE ov_set<Key, Compare>::
+ov_set(const Compare &compare, TypeHandle type_handle) :
+  ordered_vector<Key, Compare>(compare, type_handle)
 {
 }
 
@@ -802,8 +828,20 @@ verify_list() const {
 ////////////////////////////////////////////////////////////////////
 template<class Key, class Compare>
 INLINE ov_multiset<Key, Compare>::
-ov_multiset(const Compare &compare) :
-  ordered_vector<Key, Compare>(compare)
+ov_multiset(TypeHandle type_handle) :
+  ordered_vector<Key, Compare>(type_handle)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ov_multiset::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+template<class Key, class Compare>
+INLINE ov_multiset<Key, Compare>::
+ov_multiset(const Compare &compare, TypeHandle type_handle) :
+  ordered_vector<Key, Compare>(compare, type_handle)
 {
 }
 

+ 9 - 3
panda/src/express/ordered_vector.h

@@ -153,7 +153,9 @@ public:
 public:
   // Constructors.  We don't implement the whole slew of STL
   // constructors here yet.
-  INLINE ordered_vector(const Compare &compare = Compare());
+  INLINE ordered_vector(TypeHandle type_handle = ov_set_type_handle);
+  INLINE ordered_vector(const Compare &compare,
+                        TypeHandle type_handle = ov_set_type_handle);
   INLINE ordered_vector(const ordered_vector<Key, Compare> &copy);
   INLINE ordered_vector<Key, Compare> &operator = (const ordered_vector<Key, Compare> &copy);
   INLINE ~ordered_vector();
@@ -281,7 +283,9 @@ public:
   typedef TYPENAME ordered_vector<Key, Compare>::ITERATOR ITERATOR;
   typedef TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE VALUE_TYPE;
 
-  INLINE ov_set(const Compare &compare = Compare());
+  INLINE ov_set(TypeHandle type_handle = ov_set_type_handle);
+  INLINE ov_set(const Compare &compare,
+                TypeHandle type_handle = ov_set_type_handle);
   INLINE ov_set(const ov_set<Key, Compare> &copy);
   INLINE ov_set<Key, Compare> &operator = (const ov_set<Key, Compare> &copy);
 
@@ -304,7 +308,9 @@ public:
   typedef TYPENAME ordered_vector<Key, Compare>::ITERATOR ITERATOR;
   typedef TYPENAME ordered_vector<Key, Compare>::VALUE_TYPE VALUE_TYPE;
 
-  INLINE ov_multiset(const Compare &compare = Compare());
+  INLINE ov_multiset(TypeHandle type_handle = ov_set_type_handle);
+  INLINE ov_multiset(const Compare &compare,
+                     TypeHandle type_handle = ov_set_type_handle);
   INLINE ov_multiset(const ov_multiset<Key, Compare> &copy);
   INLINE ov_multiset<Key, Compare> &operator = (const ov_multiset<Key, Compare> &copy);
 

+ 15 - 0
panda/src/express/pointerTo.h

@@ -71,6 +71,7 @@
 
 #include "pandabase.h"
 #include "pointerToBase.h"
+#include "register_type.h"
 
 ////////////////////////////////////////////////////////////////////
 //       Class : PointerTo
@@ -172,6 +173,20 @@ PUBLISHED:
 #define PT(type) PointerTo< type >
 #define CPT(type) ConstPointerTo< type >
 
+// Now that we have defined PointerTo, we can define what it means to
+// take the TypeHandle of a PointerTo object.
+
+template<class T>
+INLINE TypeHandle _get_type_handle(const PointerTo<T> *) {
+  return T::get_class_type();
+}
+
+template<class T>
+INLINE TypeHandle _get_type_handle(const ConstPointerTo<T> *) {
+  return T::get_class_type();
+}
+
+
 #include "pointerTo.I"
 
 #endif

+ 44 - 110
panda/src/express/pointerToArray.I

@@ -31,8 +31,9 @@ pvector<Element> ConstPointerToArray<Element>::_empty_array;
 ////////////////////////////////////////////////////////////////////
 template<class Element>
 INLINE PointerToArray<Element>::
-PointerToArray() :
-  PointerToArrayBase<Element>((ReferenceCountedVector<Element> *)NULL)
+PointerToArray(TypeHandle type_handle) :
+  PointerToArrayBase<Element>((ReferenceCountedVector<Element> *)NULL),
+  _type_handle(type_handle)
 {
 }
 
@@ -43,11 +44,11 @@ PointerToArray() :
 ////////////////////////////////////////////////////////////////////
 template<class Element>
 INLINE PointerToArray<Element> 
-PointerToArray<Element>::empty_array(size_type n) {
-  PointerToArray<Element> temp;
-  temp.reassign(new ReferenceCountedVector<Element>);
+PointerToArray<Element>::empty_array(size_type n, TypeHandle type_handle) {
+  PointerToArray<Element> temp(type_handle);
+  temp.reassign(new ReferenceCountedVector<Element>(type_handle));
 
-  To new_array(n);
+  To new_array(n, type_handle);
   ((To *)(temp._void_ptr))->swap(new_array);
   return temp;
 }
@@ -59,8 +60,10 @@ PointerToArray<Element>::empty_array(size_type n) {
 ////////////////////////////////////////////////////////////////////
 template<class Element>
 INLINE PointerToArray<Element>::
-PointerToArray(size_type n, const Element &value) :
-  PointerToArrayBase<Element>(new ReferenceCountedVector<Element>) {
+PointerToArray(size_type n, const Element &value, TypeHandle type_handle) :
+  PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(type_handle)),
+  _type_handle(type_handle)
+{
   ((To *)(this->_void_ptr))->reserve(n);
   insert(begin(), n, value);
 }
@@ -73,44 +76,11 @@ PointerToArray(size_type n, const Element &value) :
 template<class Element>
 INLINE PointerToArray<Element>::
 PointerToArray(const PointerToArray<Element> &copy) :
-  PointerToArrayBase<Element>(copy)
+  PointerToArrayBase<Element>(copy),
+  _type_handle(copy._type_handle)
 {
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PointerToArray::get_col
-//       Access: Published
-//  Description: Returns the pointer to the PStatCollector object that
-//               tracks the total allocated size of this buffer.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE PStatCollectorForwardBase *PointerToArray<Element>::
-get_col() const {
-#ifdef DO_PSTATS
-  if ((this->_void_ptr) != NULL) {
-    return ((To *)(this->_void_ptr))->get_col();
-  }
-#endif  // DO_PSTATS
-  return NULL;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PointerToArray::set_col
-//       Access: Published
-//  Description: Changes the pointer to the PStatCollector object that
-//               tracks the total allocated size of this buffer.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE void PointerToArray<Element>::
-set_col(PStatCollectorForwardBase *col) {
-#ifdef DO_PSTATS
-  if ((this->_void_ptr) == NULL) {
-    reassign(new ReferenceCountedVector<Element>);
-  }
-  ((To *)(this->_void_ptr))->set_col(col);
-#endif  // DO_PSTATS
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PointerToArray::begin
 //       Access: Public
@@ -187,7 +157,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::size_type PointerToArray<Element>::
 max_size() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   return ((To *)(this->_void_ptr))->max_size();
 }
@@ -212,7 +182,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 reserve(TYPENAME PointerToArray<Element>::size_type n) {
   if ((this->_void_ptr) == NULL) {
-    reassign(new ReferenceCountedVector<Element>);
+    reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   ((To *)(this->_void_ptr))->reserve(n);
 }
@@ -226,7 +196,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 resize(TYPENAME PointerToArray<Element>::size_type n) {
   if ((this->_void_ptr) == NULL) {
-    reassign(new ReferenceCountedVector<Element>);
+    reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   ((To *)(this->_void_ptr))->resize(n);
 }
@@ -252,7 +222,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::reference PointerToArray<Element>::
 front() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -269,7 +239,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::reference PointerToArray<Element>::
 back() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -286,7 +256,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::iterator PointerToArray<Element>::
 insert(iterator position, const Element &x) {
   if ((this->_void_ptr) == NULL) {
-    reassign(new ReferenceCountedVector<Element>);
+    reassign(new ReferenceCountedVector<Element>(_type_handle));
     position = end();
   }
   nassertr(position >= ((To *)(this->_void_ptr))->begin() &&
@@ -303,7 +273,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 insert(iterator position, size_type n, const Element &x) {
   if ((this->_void_ptr) == NULL) {
-    reassign(new ReferenceCountedVector<Element>);
+    reassign(new ReferenceCountedVector<Element>(_type_handle));
     position = end();
   }
   nassertv(position >= ((To *)(this->_void_ptr))->begin() &&
@@ -349,7 +319,7 @@ template<class Element>
 INLINE TYPENAME PointerToArray<Element>::reference PointerToArray<Element>::
 operator [](size_type n) const {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -410,7 +380,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 push_back(const Element &x) {
   if ((this->_void_ptr) == NULL) {
-    reassign(new ReferenceCountedVector<Element>);
+    reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   ((To *)(this->_void_ptr))->push_back(x);
 }
@@ -424,7 +394,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 pop_back() {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   nassertv(!((To *)(this->_void_ptr))->empty());
   ((To *)(this->_void_ptr))->pop_back();
@@ -441,7 +411,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 make_empty() {
   nassertd((this->_void_ptr) != NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   nassertv(!((To *)(this->_void_ptr))->empty());
   ((To *)(this->_void_ptr))->clear();
@@ -487,7 +457,7 @@ template<class Element>
 INLINE pvector<Element> &PointerToArray<Element>::
 v() const {
   if ((this->_void_ptr) == NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   return *((To *)(this->_void_ptr));
 }
@@ -546,7 +516,7 @@ template<class Element>
 INLINE void PointerToArray<Element>::
 node_ref() const {
   if ((this->_void_ptr) == NULL) {
-    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((PointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   ((To *)(this->_void_ptr))->node_ref();
 }
@@ -583,6 +553,7 @@ operator = (ReferenceCountedVector<Element> *ptr) {
 template<class Element>
 INLINE PointerToArray<Element> &PointerToArray<Element>::
 operator = (const PointerToArray<Element> &copy) {
+  _type_handle = copy._type_handle;
   reassign(copy);
   return *this;
 }
@@ -597,18 +568,6 @@ operator = (const PointerToArray<Element> &copy) {
 template<class Element>
 INLINE void PointerToArray<Element>::
 clear() {
-#ifdef DO_PSTATS
-  if ((this->_void_ptr) != NULL) {
-    PT(PStatCollectorForwardBase) col = ((To *)(this->_void_ptr))->get_col();
-    if (col != (PStatCollectorForwardBase *)NULL) {
-      // If we have a PStat counter, preserve it.
-      reassign(new ReferenceCountedVector<Element>);
-      ((To *)(this->_void_ptr))->set_col(col);
-      return;
-    }
-  }
-#endif // DO_PSTATS
-
   reassign((ReferenceCountedVector<Element> *)NULL);
 }
 
@@ -621,8 +580,9 @@ clear() {
 ////////////////////////////////////////////////////////////////////
 template<class Element>
 INLINE ConstPointerToArray<Element>::
-ConstPointerToArray() :
-  PointerToArrayBase<Element>((ReferenceCountedVector<Element> *)NULL)
+ConstPointerToArray(TypeHandle type_handle) :
+  PointerToArrayBase<Element>((ReferenceCountedVector<Element> *)NULL),
+  _type_handle(type_handle)
 {
 }
 
@@ -634,7 +594,8 @@ ConstPointerToArray() :
 template<class Element>
 INLINE ConstPointerToArray<Element>::
 ConstPointerToArray(const PointerToArray<Element> &copy) :
-  PointerToArrayBase<Element>(copy)
+  PointerToArrayBase<Element>(copy),
+  _type_handle(copy._type_handle)
 {
 }
 
@@ -646,27 +607,11 @@ ConstPointerToArray(const PointerToArray<Element> &copy) :
 template<class Element>
 INLINE ConstPointerToArray<Element>::
 ConstPointerToArray(const ConstPointerToArray<Element> &copy) :
-  PointerToArrayBase<Element>(copy)
+  PointerToArrayBase<Element>(copy),
+  _type_handle(copy._type_handle)
 {
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ConstPointerToArray::get_col
-//       Access: Published
-//  Description: Returns the pointer to the PStatCollector object that
-//               tracks the total allocated size of this buffer.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE PStatCollectorForwardBase *ConstPointerToArray<Element>::
-get_col() const {
-#ifdef DO_PSTATS
-  if ((this->_void_ptr) != NULL) {
-    return ((To *)(this->_void_ptr))->get_col();
-  }
-#endif  // DO_PSTATS
-  return NULL;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ConstPointerToArray::begin
 //       Access: Public
@@ -743,7 +688,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
 max_size() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   return ((To *)(this->_void_ptr))->max_size();
 }
@@ -768,7 +713,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::size_type ConstPointerToArray<Element>::
 capacity() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   return ((To *)(this->_void_ptr))->capacity();
 }
@@ -782,7 +727,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
 front() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -799,7 +744,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
 back() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -817,7 +762,7 @@ template<class Element>
 INLINE TYPENAME ConstPointerToArray<Element>::reference ConstPointerToArray<Element>::
 operator [](size_type n) const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   nassertd(!((To *)(this->_void_ptr))->empty()) {
     ((To *)(this->_void_ptr))->push_back(Element());
@@ -893,7 +838,7 @@ template<class Element>
 INLINE const pvector<Element> &ConstPointerToArray<Element>::
 v() const {
   nassertd((this->_void_ptr) != NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   return *(To *)(this->_void_ptr);
 }
@@ -929,7 +874,7 @@ template<class Element>
 INLINE void ConstPointerToArray<Element>::
 node_ref() const {
   if ((this->_void_ptr) == NULL) {
-    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>);
+    ((ConstPointerToArray<Element> *)this)->reassign(new ReferenceCountedVector<Element>(_type_handle));
   }
   ((To *)(this->_void_ptr))->node_ref();
 }
@@ -966,6 +911,7 @@ operator = (ReferenceCountedVector<Element> *ptr) {
 template<class Element>
 INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
 operator = (const PointerToArray<Element> &copy) {
+  _type_handle = copy._type_handle;
   reassign(copy);
   return *this;
 }
@@ -978,6 +924,7 @@ operator = (const PointerToArray<Element> &copy) {
 template<class Element>
 INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
 operator = (const ConstPointerToArray<Element> &copy) {
+  _type_handle = copy._type_handle;
   reassign(copy);
   return *this;
 }
@@ -992,20 +939,7 @@ operator = (const ConstPointerToArray<Element> &copy) {
 template<class Element>
 INLINE void ConstPointerToArray<Element>::
 clear() {
-#ifdef DO_PSTATS
-  if ((this->_void_ptr) != NULL) {
-    PT(PStatCollectorForwardBase) col = ((To *)(this->_void_ptr))->get_col();
-    if (col != (PStatCollectorForwardBase *)NULL) {
-      // If we have a PStat counter, preserve it.
-      reassign(new ReferenceCountedVector<Element>);
-      ((To *)(this->_void_ptr))->set_col(col);
-      return;
-    }
-  }
-
-#else  // DO_PSTATS
   reassign((ReferenceCountedVector<Element> *)NULL);
-#endif // DO_PSTATS
 }
 
-#endif  // CPPPARSEr
+#endif  // CPPPARSER

+ 18 - 10
panda/src/express/pointerToArray.h

@@ -78,6 +78,9 @@
 #pragma warning (disable : 4506)
 #endif
 
+template <class Element>
+class ConstPointerToArray;
+
 ////////////////////////////////////////////////////////////////////
 //       Class : PointerToArray
 // Description : A special kind of PointerTo that stores an array of
@@ -114,14 +117,11 @@ public:
   typedef TYPENAME pvector<Element>::size_type size_type;
 
 public:
-  INLINE PointerToArray();
-  INLINE static PointerToArray<Element> empty_array(size_type n);
-  INLINE PointerToArray(size_type n, const Element &value);
+  INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element));
+  INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
+  INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element));
   INLINE PointerToArray(const PointerToArray<Element> &copy);
 
-  INLINE PStatCollectorForwardBase *get_col() const;
-  INLINE void set_col(PStatCollectorForwardBase *col);
-
 public:
   // Duplicating the interface of vector.  The following member
   // functions are all const, because they do not reassign the
@@ -195,14 +195,19 @@ public:
   operator = (const PointerToArray<Element> &copy);
   INLINE void clear();
 
+private:
+  TypeHandle _type_handle;
+
 private:
   // This static empty array is kept around just so we can return
-  // something meangful when begin() or end() is called and we have a
+  // something meaningful when begin() or end() is called and we have a
   // NULL pointer.  It might not be shared properly between different
   // .so's, since it's a static member of a template class, but we
   // don't really care.
   static pvector<Element> _empty_array;
 #endif  // CPPPARSER
+
+  friend class ConstPointerToArray<Element>;
 };
 
 ////////////////////////////////////////////////////////////////////
@@ -232,12 +237,10 @@ public:
   typedef TYPENAME pvector<Element>::difference_type difference_type;
   typedef TYPENAME pvector<Element>::size_type size_type;
 
-  INLINE ConstPointerToArray();
+  INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element));
   INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
   INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
 
-  INLINE PStatCollectorForwardBase *get_col() const;
-
   // Duplicating the interface of vector.
 
   INLINE iterator begin() const;
@@ -282,6 +285,9 @@ public:
   operator = (const ConstPointerToArray<Element> &copy);
   INLINE void clear();
 
+private:
+  TypeHandle _type_handle;
+
 private:
   // This static empty array is kept around just so we can return
   // something meangful when begin() or end() is called and we have a
@@ -290,6 +296,8 @@ private:
   // don't really care.
   static pvector<Element> _empty_array;
 #endif  // CPPPARSER
+
+  friend class PointerToArray<Element>;
 };
 
 

+ 4 - 65
panda/src/express/pointerToArrayBase.I

@@ -24,7 +24,7 @@
 ////////////////////////////////////////////////////////////////////
 template<class Element>
 INLINE ReferenceCountedVector<Element>::
-ReferenceCountedVector() {
+ReferenceCountedVector(TypeHandle type_handle) : pvector<Element>(type_handle) {
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -38,9 +38,6 @@ ReferenceCountedVector(const ReferenceCountedVector<Element> &copy) :
   NodeReferenceCount(copy),
   pvector<Element>(copy)
 {
-#ifdef DO_PSTATS
-  set_col(copy._col);
-#endif  // DO_PSTATS
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -50,8 +47,8 @@ ReferenceCountedVector(const ReferenceCountedVector<Element> &copy) :
 ////////////////////////////////////////////////////////////////////
 template<class Element>
 INLINE ReferenceCountedVector<Element>::
-ReferenceCountedVector(TYPENAME ReferenceCountedVector<Element>::size_type initial_size) :
-  pvector<Element>(initial_size)
+ReferenceCountedVector(TYPENAME ReferenceCountedVector<Element>::size_type initial_size, TypeHandle type_handle) :
+  pvector<Element>(initial_size, type_handle)
 {
 }
 
@@ -63,43 +60,8 @@ ReferenceCountedVector(TYPENAME ReferenceCountedVector<Element>::size_type initi
 template<class Element>
 INLINE ReferenceCountedVector<Element>::
 ~ReferenceCountedVector() {
-  adjust_size(size(), 0);
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: ReferenceCountedVector::get_col
-//       Access: Public
-//  Description: Returns the pointer to the PStatCollector object that
-//               tracks the total allocated size of this buffer.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE PStatCollectorForwardBase *ReferenceCountedVector<Element>::
-get_col() const {
-#ifdef DO_PSTATS
-  return _col;
-#else
-  return NULL;
-#endif  // DO_PSTATS
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ReferenceCountedVector::set_col
-//       Access: Public
-//  Description: Changes the pointer to the PStatCollector object that
-//               tracks the total allocated size of this buffer.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE void ReferenceCountedVector<Element>::
-set_col(PStatCollectorForwardBase *col) {
-#ifdef DO_PSTATS
-  if (_col != col) {
-    adjust_size(size(), 0);
-    _col = col;
-    adjust_size(0, size());
-  }
-#endif  // DO_PSTATS
-}
-
+ 
 ////////////////////////////////////////////////////////////////////
 //     Function: ReferenceCountedVector::size
 //       Access: Public
@@ -119,7 +81,6 @@ size() const {
 template<class Element>
 INLINE TYPENAME ReferenceCountedVector<Element>::iterator ReferenceCountedVector<Element>::
 insert(iterator position, const Element &x) {
-  adjust_size(0, 1);
   return pvector<Element>::insert(position, x);
 }
 
@@ -131,7 +92,6 @@ insert(iterator position, const Element &x) {
 template<class Element>
 INLINE void ReferenceCountedVector<Element>::
 insert(iterator position, size_type n, const Element &x) {
-  adjust_size(0, n);
   pvector<Element>::insert(position, n, x);
 }
 
@@ -143,7 +103,6 @@ insert(iterator position, size_type n, const Element &x) {
 template<class Element>
 INLINE void ReferenceCountedVector<Element>::
 erase(iterator position) {
-  adjust_size(1, 0);
   pvector<Element>::erase(position);
 }
 
@@ -155,7 +114,6 @@ erase(iterator position) {
 template<class Element>
 INLINE void ReferenceCountedVector<Element>::
 erase(iterator first, iterator last) {
-  adjust_size(last - first, 0);
   pvector<Element>::erase(first, last);
 }
 
@@ -167,7 +125,6 @@ erase(iterator first, iterator last) {
 template<class Element>
 INLINE void ReferenceCountedVector<Element>::
 pop_back() {
-  adjust_size(1, 0);
   pvector<Element>::pop_back();
 }
 
@@ -179,27 +136,9 @@ pop_back() {
 template<class Element>
 INLINE void ReferenceCountedVector<Element>::
 clear() {
-  adjust_size(size(), 0);
   pvector<Element>::clear();
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ReferenceCountedVector::adjust_size
-//       Access: Private
-//  Description: This internal function is used to update the
-//               connected PStatCollector (if any) with the change in
-//               size.
-////////////////////////////////////////////////////////////////////
-template<class Element>
-INLINE void ReferenceCountedVector<Element>::
-adjust_size(size_t orig_size, size_t new_size) {
-#ifdef DO_PSTATS
-  if (_col != (PStatCollectorForwardBase *)NULL) {
-    _col->add_level((float)new_size - (float)orig_size);
-  }
-#endif  // DO_PSTATS
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PointerToArrayBase::Constructor
 //       Access: Protected

+ 2 - 12
panda/src/express/pointerToArrayBase.h

@@ -49,15 +49,12 @@ public:
   typedef TYPENAME pvector<Element>::iterator iterator;
   typedef TYPENAME pvector<Element>::size_type size_type;
 
-  INLINE ReferenceCountedVector();
+  INLINE ReferenceCountedVector(TypeHandle type_handle);
   INLINE ReferenceCountedVector(const ReferenceCountedVector<Element> &copy);
-  INLINE ReferenceCountedVector(size_type initial_size);
+  INLINE ReferenceCountedVector(size_type initial_size, TypeHandle type_handle);
   INLINE ~ReferenceCountedVector();
   ALLOC_DELETED_CHAIN(ReferenceCountedVector<Element>);
 
-  INLINE PStatCollectorForwardBase *get_col() const;
-  INLINE void set_col(PStatCollectorForwardBase *col);
-
   INLINE size_type size() const;
 
   INLINE iterator insert(iterator position, const Element &x);
@@ -68,13 +65,6 @@ public:
 
   INLINE void pop_back();
   INLINE void clear();
-
-private:
-  INLINE void adjust_size(size_t orig_size, size_t new_size);
-
-#ifdef DO_PSTATS
-  PT(PStatCollectorForwardBase) _col;
-#endif
 };
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 2
panda/src/gobj/geomVertexArrayData.I

@@ -121,7 +121,7 @@ unclean_set_num_rows(int n) {
 ////////////////////////////////////////////////////////////////////
 INLINE void GeomVertexArrayData::
 clear_rows() {
-  set_data(PTA_uchar());
+  set_data(PTA_uchar(GeomVertexArrayData::get_class_type()));
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -201,7 +201,8 @@ set_data(CPTA_uchar array) {
 ////////////////////////////////////////////////////////////////////
 INLINE GeomVertexArrayData::CData::
 CData() :
-  _usage_hint(UH_unspecified)
+  _usage_hint(UH_unspecified),
+  _data(GeomVertexArrayData::get_class_type())
 {
   _data.node_ref();
 }

+ 5 - 12
panda/src/gobj/geomVertexArrayData.cxx

@@ -29,8 +29,6 @@ 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++:pvector:array:Vertex Data"));
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexArrayData::Default Constructor
 //       Access: Private
@@ -308,7 +306,7 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) {
 PTA_uchar GeomVertexArrayData::
 reverse_data_endianness(const PTA_uchar &data) {
   // First, make a complete copy of the data.
-  PTA_uchar new_data;
+  PTA_uchar new_data(get_class_type());
   new_data.v() = data.v();
 
   int num_columns = _array_format->get_num_columns();
@@ -397,7 +395,7 @@ write_raw_data(BamWriter *manager, Datagram &dg, const PTA_uchar &data) {
 PTA_uchar GeomVertexArrayData::
 read_raw_data(BamReader *manager, DatagramIterator &scan) {
   size_t size = scan.get_uint32();
-  PTA_uchar data = PTA_uchar::empty_array(size);
+  PTA_uchar data = PTA_uchar::empty_array(size, get_class_type());
   const unsigned char *source_data = 
     (const unsigned char *)scan.get_datagram().get_data();
   memcpy(data, source_data + scan.get_current_index(), size);
@@ -467,7 +465,6 @@ finalize(BamReader *manager) {
 
   // Now is also the time to node_ref the data.
   cdata->_data.node_ref();
-  cdata->_data.set_col(_vdata_mem_pcollector);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -569,7 +566,7 @@ set_num_rows(int n) {
     if (_cdata->_data.get_node_ref_count() > 1) {
       // Copy-on-write: the data is already reffed somewhere else,
       // so we're just going to make a copy.
-      PTA_uchar new_data;
+      PTA_uchar new_data(GeomVertexArrayData::get_class_type());
       new_data.reserve(n * stride);
       new_data.insert(new_data.end(), n * stride, 0);
       memcpy(new_data, _cdata->_data, 
@@ -577,7 +574,6 @@ set_num_rows(int n) {
       _cdata->_data.node_unref();
       _cdata->_data = new_data;
       _cdata->_data.node_ref();
-      _cdata->_data.set_col(GeomVertexArrayData::_vdata_mem_pcollector);
       
     } else {
       // We've got the only reference to the data, so we can change
@@ -611,12 +607,11 @@ unclean_set_num_rows(int n) {
   
   if (delta != 0) {
     // Just make a new array.  No reason to keep the old one around.
-    PTA_uchar new_data = PTA_uchar::empty_array(n * stride);
+    PTA_uchar new_data = PTA_uchar::empty_array(n * stride, GeomVertexArrayData::get_class_type());
 
     _cdata->_data.node_unref();
     _cdata->_data = new_data;
     _cdata->_data.node_ref();
-    _cdata->_data.set_col(GeomVertexArrayData::_vdata_mem_pcollector);
     _cdata->_modified = Geom::get_next_modified();
 
     return true;
@@ -639,10 +634,9 @@ modify_data() {
   if (_cdata->_data.get_node_ref_count() > 1) {
     PTA_uchar orig_data = _cdata->_data;
     _cdata->_data.node_unref();
-    _cdata->_data = PTA_uchar();
+    _cdata->_data = PTA_uchar(GeomVertexArrayData::get_class_type());
     _cdata->_data.v() = orig_data.v();
     _cdata->_data.node_ref();
-    _cdata->_data.set_col(GeomVertexArrayData::_vdata_mem_pcollector);
   }
   _cdata->_modified = Geom::get_next_modified();
 
@@ -659,6 +653,5 @@ set_data(CPTA_uchar array) {
   _cdata->_data.node_unref();
   _cdata->_data = (PTA_uchar &)array;
   _cdata->_data.node_ref();
-  _cdata->_data.set_col(GeomVertexArrayData::_vdata_mem_pcollector);
   _cdata->_modified = Geom::get_next_modified();
 }

+ 0 - 4
panda/src/gobj/geomVertexArrayData.h

@@ -32,7 +32,6 @@
 #include "cycleDataStageWriter.h"
 #include "pipelineCycler.h"
 #include "pStatCollector.h"
-#include "pStatCollectorForward.h"
 #include "pmap.h"
 
 class PreparedGraphicsObjects;
@@ -161,9 +160,6 @@ private:
   typedef CycleDataStageReader<CData> CDStageReader;
   typedef CycleDataStageWriter<CData> CDStageWriter;
 
-private:
-  static PT(PStatCollectorForward) _vdata_mem_pcollector;
-
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &dg);

+ 8 - 18
panda/src/gobj/texture.cxx

@@ -41,8 +41,6 @@
 
 #include <stddef.h>
 
-PT(PStatCollectorForward) Texture::_tex_mem_pcollector = new PStatCollectorForward(PStatCollector("Main memory:C++:pvector:array:Texture Data"));
-
 TypeHandle Texture::_type_handle;
 
 ////////////////////////////////////////////////////////////////////
@@ -971,7 +969,7 @@ get_ram_image() {
   }
 
   if (_ram_images.empty()) {
-    return CPTA_uchar();
+    return CPTA_uchar(get_class_type());
   }
 
   return _ram_images[0]._image;
@@ -1004,7 +1002,6 @@ set_ram_image(PTA_uchar image, Texture::CompressionMode compression,
       _ram_images[0]._page_size != page_size ||
       _ram_image_compression != compression) {
     _ram_images[0]._image = image;
-    _ram_images[0]._image.set_col(_tex_mem_pcollector);
     _ram_images[0]._page_size = page_size;
     _ram_image_compression = compression;
     ++_image_modified;
@@ -1082,7 +1079,7 @@ get_ram_mipmap_image(int n) {
   if (n < (int)_ram_images.size()) {
     return _ram_images[n]._image;
   }
-  return CPTA_uchar();
+  return CPTA_uchar(get_class_type());
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -1096,15 +1093,14 @@ get_ram_mipmap_image(int n) {
 ////////////////////////////////////////////////////////////////////
 PTA_uchar Texture::
 make_ram_mipmap_image(int n) {
-  nassertr(_ram_image_compression == CM_off, PTA_uchar());
+  nassertr(_ram_image_compression == CM_off, PTA_uchar(get_class_type()));
 
   while (n >= (int)_ram_images.size()) {
     _ram_images.push_back(RamImage());
     _ram_images.back()._page_size = 0;
   }
 
-  _ram_images[n]._image = PTA_uchar::empty_array(get_expected_ram_mipmap_image_size(n));
-  _ram_images[n]._image.set_col(_tex_mem_pcollector);
+  _ram_images[n]._image = PTA_uchar::empty_array(get_expected_ram_mipmap_image_size(n), get_class_type());
   _ram_images[n]._page_size = get_expected_ram_mipmap_page_size(n);
   ++_image_modified;
   return _ram_images[n]._image;
@@ -1136,7 +1132,6 @@ set_ram_mipmap_image(int n, PTA_uchar image, size_t page_size) {
   if (_ram_images[n]._image != image ||
       _ram_images[n]._page_size != page_size) {
     _ram_images[n]._image = image;
-    _ram_images[n]._image.set_col(_tex_mem_pcollector);
     _ram_images[n]._page_size = page_size;
     ++_image_modified;
   }
@@ -2406,8 +2401,7 @@ do_make_ram_image() {
   _ram_images.clear();
   _ram_images.push_back(RamImage());
   _ram_images[0]._page_size = get_expected_ram_page_size();
-  _ram_images[0]._image = PTA_uchar::empty_array(get_expected_ram_image_size());
-  _ram_images[0]._image.set_col(_tex_mem_pcollector);
+  _ram_images[0]._image = PTA_uchar::empty_array(get_expected_ram_image_size(), get_class_type());
   _ram_image_compression = CM_off;
 }
 
@@ -2736,7 +2730,6 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
   }
 
   nassertv(p == &image[idx] + page_size);
-  image.set_col(_tex_mem_pcollector);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -2999,8 +2992,7 @@ filter_2d_mipmap_pages(Texture::RamImage &to, const Texture::RamImage &from,
 
   size_t to_row_size = (size_t)to_x_size * pixel_size;
   to._page_size = (size_t)to_y_size * to_row_size;
-  to._image = PTA_uchar::empty_array(to._page_size * _z_size);
-  to._image.set_col(_tex_mem_pcollector);
+  to._image = PTA_uchar::empty_array(to._page_size * _z_size, get_class_type());
 
   Filter2DComponent *filter_component = (_component_type == T_unsigned_byte ? &filter_2d_unsigned_byte : filter_2d_unsigned_short);
 
@@ -3096,8 +3088,7 @@ filter_3d_mipmap_level(Texture::RamImage &to, const Texture::RamImage &from,
   size_t to_row_size = (size_t)to_x_size * pixel_size;
   size_t to_page_size = (size_t)to_y_size * to_row_size;
   to._page_size = to_page_size;
-  to._image = PTA_uchar::empty_array(to_page_size * to_z_size);
-  to._image.set_col(_tex_mem_pcollector);
+  to._image = PTA_uchar::empty_array(to_page_size * to_z_size, get_class_type());
 
   Filter3DComponent *filter_component = (_component_type == T_unsigned_byte ? &filter_3d_unsigned_byte : filter_3d_unsigned_short);
 
@@ -3497,12 +3488,11 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
       size_t u_size = scan.get_uint32();
 
       // fill the _image buffer with image data
-      PTA_uchar image = PTA_uchar::empty_array(u_size);
+      PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type());
       for (size_t u_idx = 0; u_idx < u_size; ++u_idx) {
         image[(int)u_idx] = scan.get_uint8();
       }
       _ram_images[n]._image = image;
-      _ram_images[n]._image.set_col(_tex_mem_pcollector);
     }
     _loaded_from_image = true;
     ++_image_modified;

+ 0 - 3
panda/src/gobj/texture.h

@@ -27,7 +27,6 @@
 #include "internalName.h"
 #include "graphicsStateGuardianBase.h"
 #include "updateSeq.h"
-#include "pStatCollectorForward.h"
 #include "pmap.h"
 #include "config_gobj.h"
 
@@ -536,8 +535,6 @@ private:
   typedef pmap<string, PT(TypedReferenceCount) > AuxData;
   AuxData _aux_data;
 
-  static PT(PStatCollectorForward) _tex_mem_pcollector;
-
   // Datagram stuff
 public:
   static void register_with_read_factory();

+ 3 - 3
panda/src/pgraph/pandaNode.cxx

@@ -3631,9 +3631,9 @@ CData() {
   _net_draw_show_mask = DrawMask::all_off();
   ++_next_update;
 
-  _down = new PandaNode::Down;
-  _stashed = new PandaNode::Down;
-  _up = new PandaNode::Up;
+  _down = new PandaNode::Down(PandaNode::get_class_type());
+  _stashed = new PandaNode::Down(PandaNode::get_class_type());
+  _up = new PandaNode::Up(PandaNode::get_class_type());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 2
panda/src/pgraph/pandaNode.h

@@ -365,7 +365,7 @@ public:
   };
 
 private:
-  typedef CopyOnWriteObj< ov_multiset<DownConnection> > Down;
+  typedef CopyOnWriteObj1< ov_multiset<DownConnection>, TypeHandle > Down;
 
   class EXPCL_PANDA UpConnection {
   public:
@@ -378,7 +378,7 @@ private:
     // children do not circularly reference each other.
     PandaNode *_parent;
   };
-  typedef CopyOnWriteObj< ov_set<UpConnection> > Up;
+  typedef CopyOnWriteObj1< ov_set<UpConnection>, TypeHandle > Up;
 
   // We also maintain a set of NodePathComponents in the node.  This
   // represents the set of instances of this node that we have

+ 2 - 0
panda/src/pnmtext/Sources.pp

@@ -23,4 +23,6 @@
     pnmTextGlyph.h pnmTextGlyph.I \
     pnmTextMaker.h pnmTextMaker.I
 
+  #define IGATESCAN all
+
 #end lib_target

+ 1 - 1
panda/src/pnmtext/freetypeFont.h

@@ -49,7 +49,7 @@ protected:
   bool load_font(const char *font_data, int data_length, int face_index);
   void unload_font();
 
-public:
+PUBLISHED:
   INLINE ~FreetypeFont();
 
   INLINE bool set_point_size(float point_size);

+ 1 - 1
panda/src/pnmtext/pnmTextMaker.h

@@ -41,7 +41,7 @@ class PNMTextGlyph;
 //               traversal.
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA PNMTextMaker : public FreetypeFont {
-public:
+PUBLISHED:
   PNMTextMaker(const Filename &font_filename, int face_index);
   PNMTextMaker(const char *font_data, int data_length, int face_index);
   ~PNMTextMaker();

+ 6 - 0
panda/src/pstatclient/config_pstats.cxx

@@ -62,6 +62,12 @@ ConfigVariableDouble pstats_history
 ConfigVariableDouble pstats_average_time
 ("pstats-average-time", 3.0);
 
+ConfigVariableBool pstats_mem_other
+("pstats-mem-other", true,
+ PRC_DESC("Set this true to collect memory categories smaller than 0.1% of "
+          "the total into a single \"Other\" category, or false to show "
+          "each nonzero memory category."));
+
 ////////////////////////////////////////////////////////////////////
 //     Function: init_libpstatclient
 //  Description: Initializes the library.  This must be called at

+ 2 - 0
panda/src/pstatclient/config_pstats.h

@@ -46,6 +46,8 @@ extern EXPCL_PANDA ConfigVariableBool pstats_scroll_mode;
 extern EXPCL_PANDA ConfigVariableDouble pstats_history;
 extern EXPCL_PANDA ConfigVariableDouble pstats_average_time;
 
+extern EXPCL_PANDA ConfigVariableBool pstats_mem_other;
+
 extern EXPCL_PANDA void init_libpstatclient();
 
 #endif

+ 24 - 2
panda/src/pstatclient/pStatClient.cxx

@@ -34,6 +34,7 @@
 
 PStatCollector PStatClient::_total_size_pcollector("Main memory");
 PStatCollector PStatClient::_cpp_size_pcollector("Main memory:C++");
+PStatCollector PStatClient::_cpp_other_size_pcollector("Main memory:C++:Other");
 PStatCollector PStatClient::_interpreter_size_pcollector("Main memory:Interpreter");
 PStatCollector PStatClient::_pstats_pcollector("*:PStats");
 PStatCollector PStatClient::_clock_wait_pcollector("Wait:Clock Wait:Sleep");
@@ -227,14 +228,30 @@ main_tick() {
     while ((int)type_handle_cols.size() < num_typehandles) {
       type_handle_cols.push_back(TypeHandleCollector());
     }
-    
+
+    size_t total_usage = 0;
+    int i;
+    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;
+        size_t usage = type.get_memory_usage(mc);
+        total_usage += usage;
+      }
+    }
+    size_t min_usage = total_usage / 1024;
+    if (!pstats_mem_other) {
+      min_usage = 0;
+    }
+    size_t other_usage = total_usage;
+
     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()) {
+        if (usage > min_usage || col.is_valid()) {
           // We have some memory usage on this TypeHandle.  See if we
           // have a collector for it.
           if (!col.is_valid()) {
@@ -243,9 +260,14 @@ main_tick() {
             col = PStatCollector(strm.str());
           }
           col.set_level(usage);
+          other_usage -= usage;
         }
       }
     }
+
+    // The remaining amount--all collectors smaller than 0.1% of the
+    // total--go into "other".
+    _cpp_other_size_pcollector.set_level(other_usage);
   }
 #endif  // DO_MEMORY_USAGE
 

+ 1 - 0
panda/src/pstatclient/pStatClient.h

@@ -222,6 +222,7 @@ private:
 
   static PStatCollector _total_size_pcollector;
   static PStatCollector _cpp_size_pcollector;
+  static PStatCollector _cpp_other_size_pcollector;
   static PStatCollector _interpreter_size_pcollector;
   static PStatCollector _pstats_pcollector;
   static PStatCollector _clock_wait_pcollector;

+ 1 - 0
panda/src/putil/buttonHandle.cxx

@@ -22,6 +22,7 @@
 // This is initialized to zero by static initialization.
 ButtonHandle ButtonHandle::_none;
 
+TypeHandle ButtonHandle::_type_handle;
 
 ////////////////////////////////////////////////////////////////////
 //     Function: ButtonHandle::get_name

+ 13 - 0
panda/src/putil/buttonHandle.h

@@ -20,6 +20,8 @@
 #define BUTTONHANDLE_H
 
 #include "pandabase.h"
+#include "typeHandle.h"
+#include "register_type.h"
 
 ////////////////////////////////////////////////////////////////////
 //       Class : ButtonHandle
@@ -56,6 +58,17 @@ private:
   int _index;
   static ButtonHandle _none;
 
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    register_type(_type_handle, "ButtonHandle");
+  }
+
+private:
+  static TypeHandle _type_handle;
+
 friend class ButtonRegistry;
 };
 

+ 3 - 0
panda/src/putil/config_util.cxx

@@ -24,6 +24,7 @@
 #include "bamReaderParam.h"
 #include "bitArray.h"
 #include "bitMask.h"
+#include "buttonHandle.h"
 #include "cachedTypedWritableReferenceCount.h"
 #include "clockObject.h"
 #include "configurable.h"
@@ -89,6 +90,8 @@ ConfigureFn(config_util) {
   BamReaderParam::init_type();
   BitArray::init_type();
   BitMask32::init_type();
+  BitMask64::init_type();
+  ButtonHandle::init_type();
   CachedTypedWritableReferenceCount::init_type();
   ClockObject::init_type();
   Configurable::init_type();

+ 73 - 0
panda/src/putil/copyOnWriteObject.I

@@ -20,6 +20,9 @@
 template<class Base>
 TypeHandle CopyOnWriteObj<Base>::_type_handle;
 
+template<class Base, class Param1>
+TypeHandle CopyOnWriteObj1<Base, Param1>::_type_handle;
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CopyOnWriteObject::Constructor
 //       Access: Public
@@ -151,3 +154,73 @@ init_type() {
                           base_type, 
                           CopyOnWriteObject::get_class_type());
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: CopyOnWriteObj1::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class Base, class Param1>
+INLINE CopyOnWriteObj1<Base, Param1>::
+CopyOnWriteObj1(Param1 p1) : Base(p1) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CopyOnWriteObj1::Copy Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class Base, class Param1>
+INLINE CopyOnWriteObj1<Base, Param1>::
+CopyOnWriteObj1(const Base &copy) : 
+  Base(copy) 
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CopyOnWriteObj1::Copy Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class Base, class Param1>
+INLINE CopyOnWriteObj1<Base, Param1>::
+CopyOnWriteObj1(const CopyOnWriteObj1<Base, Param1> &copy) : 
+  CopyOnWriteObject(copy),
+  Base(copy) 
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CopyOnWriteObj1::make_cow_copy
+//       Access: Protected, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class Base, class Param1>
+PT(CopyOnWriteObject) CopyOnWriteObj1<Base, Param1>::
+make_cow_copy() {
+  return new CopyOnWriteObj1<Base, Param1>(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CopyOnWriteObj1::init_type
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class Base, class Param1>
+void CopyOnWriteObj1<Base, Param1>::
+init_type() {
+#if defined(HAVE_RTTI) && !defined(__EDG__)
+  // If we have RTTI, we can determine the name of the base type.
+  string base_name = typeid(Base).name();
+#else
+  string base_name = "unknown";
+#endif
+
+  TypeHandle base_type = register_dynamic_type(base_name);
+
+  CopyOnWriteObject::init_type();
+  _type_handle =
+    register_dynamic_type("CopyOnWriteObj1<" + base_name + ">",
+                          base_type, 
+                          CopyOnWriteObject::get_class_type());
+}

+ 33 - 0
panda/src/putil/copyOnWriteObject.h

@@ -117,6 +117,39 @@ private:
   static TypeHandle _type_handle;
 };
 
+////////////////////////////////////////////////////////////////////
+//       Class : CopyOnWriteObj1
+// Description : For objects (e.g. pvectors) whose constructor
+//               takes a single parameter.
+////////////////////////////////////////////////////////////////////
+template<class Base, class Param1>
+class CopyOnWriteObj1 : public CopyOnWriteObject, public Base {
+public:
+  INLINE CopyOnWriteObj1(Param1 p1);
+  INLINE CopyOnWriteObj1(const Base &copy);
+  INLINE CopyOnWriteObj1(const CopyOnWriteObj1<Base, Param1> &copy);
+
+protected:
+  virtual PT(CopyOnWriteObject) make_cow_copy();
+
+public:
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+PUBLISHED:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+
+public:
+  static void init_type();
+
+private:
+  static TypeHandle _type_handle;
+};
+
 #include "copyOnWriteObject.I"
 
 #endif