Browse Source

defer creation of PStatCollectorDef

David Rose 21 years ago
parent
commit
84bcfefc13

+ 74 - 0
panda/src/pstatclient/pStatClient.I

@@ -82,6 +82,18 @@ get_num_collectors() const {
   return _collectors.size();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PStatClient::get_collector_def
+//       Access: Published
+//  Description: Returns the definition body of the nth collector.
+////////////////////////////////////////////////////////////////////
+INLINE PStatCollectorDef *PStatClient::
+get_collector_def(int index) const {
+  nassertr(index >= 0 && index < (int)_collectors.size(), NULL);
+
+  return _collectors[index].get_def(this, index);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PStatClient::get_num_threads
 //       Access: Published
@@ -238,3 +250,65 @@ INLINE const PStatClientImpl *PStatClient::
 get_impl() const {
   return ((PStatClient *)this)->get_impl();
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: PStatClient::Collector::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE PStatClient::Collector::
+Collector(int parent_index, const string &name) :
+  _def(NULL),
+  _parent_index(parent_index),
+  _name(name)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PStatClient::Collector::get_parent_index
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE int PStatClient::Collector::
+get_parent_index() const {
+  return _parent_index;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PStatClient::Collector::get_name
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE const string &PStatClient::Collector::
+get_name() const {
+  return _name;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PStatClient::Collector::is_active
+//       Access: Public
+//  Description: Returns true if the indicated collector has been
+//               designated as active, false otherwise.  This might
+//               return initially false until the collector def has
+//               actually been created.
+////////////////////////////////////////////////////////////////////
+INLINE bool PStatClient::Collector::
+is_active() const {
+  return _def != (PStatCollectorDef *)NULL && _def->_is_active;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PStatClient::Collector::get_def
+//       Access: Public
+//  Description: Returns the PStatCollectorDef that contains all of
+//               the information about the collector.  If this object
+//               has not yet been created, creates it.
+////////////////////////////////////////////////////////////////////
+INLINE PStatCollectorDef *PStatClient::Collector::
+get_def(const PStatClient *client, int this_index) const {
+  if (_def == (PStatCollectorDef *)NULL) {
+    ((Collector *)this)->make_def(client, this_index);
+  }
+
+  return _def;
+}

+ 44 - 42
panda/src/pstatclient/pStatClient.cxx

@@ -62,10 +62,10 @@ PStatClient() :
   // We always have a collector at index 0 named "Frame".  This tracks
   // the total frame time and is the root of all other collectors.  We
   // have to make this one by hand since it's the root.
-  Collector collector;
-  collector._def = new PStatCollectorDef(0, "Frame");
-  collector._def->_parent_index = 0;
-  collector._def->_suggested_color.set(0.5, 0.5, 0.5);
+  Collector collector(0, "Frame");
+  //collector._def = new PStatCollectorDef(0, "Frame");
+  //collector._def->_parent_index = 0;
+  //collector._def->_suggested_color.set(0.5, 0.5, 0.5);
   _collectors.push_back(collector);
 
   // We also always have a thread at index 0 named "Main".
@@ -97,21 +97,6 @@ get_collector(int index) const {
   return PStatCollector((PStatClient *)this, index);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PStatClient::get_collector_def
-//       Access: Published
-//  Description: Returns the definition body of the nth collector.
-////////////////////////////////////////////////////////////////////
-const PStatCollectorDef &PStatClient::
-get_collector_def(int index) const {
-#ifndef NDEBUG
-  static PStatCollectorDef bogus;
-  nassertr(index >= 0 && index < (int)_collectors.size(), bogus);
-#endif
-
-  return *_collectors[index]._def;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PStatClient::get_collector_name
 //       Access: Published
@@ -121,8 +106,7 @@ string PStatClient::
 get_collector_name(int index) const {
   nassertr(index >= 0 && index < (int)_collectors.size(), string());
 
-  const PStatCollectorDef *def = _collectors[index]._def;
-  return def->_name;
+  return _collectors[index].get_name();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -137,11 +121,12 @@ string PStatClient::
 get_collector_fullname(int index) const {
   nassertr(index >= 0 && index < (int)_collectors.size(), string());
 
-  const PStatCollectorDef *def = _collectors[index]._def;
-  if (def->_parent_index == 0) {
-    return def->_name;
+  int parent_index = _collectors[index].get_parent_index();
+  if (parent_index == 0) {
+    return _collectors[index].get_name();
   } else {
-    return get_collector_fullname(def->_parent_index) + ":" + def->_name;
+    return get_collector_fullname(parent_index) + ":" + 
+      _collectors[index].get_name();
   }
 }
 
@@ -315,7 +300,7 @@ make_collector_with_name(int parent_index, const string &name) {
   // A special case: if we asked for a child the same name as its
   // parent, we really meant the parent.  That is, "Frame:Frame" is
   // really the same collector as "Frame".
-  if (parent._def->_name == name) {
+  if (parent.get_name() == name) {
     return PStatCollector(this, parent_index);
   }
 
@@ -333,12 +318,13 @@ make_collector_with_name(int parent_index, const string &name) {
   parent._children.insert(ThingsByName::value_type(name, new_index));
 
   // Extending the vector invalidates the parent reference, above.
-  _collectors.push_back(Collector());
+  _collectors.push_back(Collector(parent_index, name));
+
   Collector &collector = _collectors.back();
-  collector._def = new PStatCollectorDef(new_index, name);
 
-  collector._def->set_parent(*_collectors[parent_index]._def);
-  initialize_collector_def(this, collector._def);
+  // collector._def = new PStatCollectorDef(new_index, name);
+  // collector._def->set_parent(*_collectors[parent_index]._def);
+  // initialize_collector_def(this, collector._def);
 
   // We need one PerThreadData for each thread.
   while (collector._per_thread.size() < _threads.size()) {
@@ -406,7 +392,7 @@ is_active(int collector_index, int thread_index) const {
   nassertr(thread_index >= 0 && thread_index < (int)_threads.size(), false);
 
   return (client_is_connected() &&
-          _collectors[collector_index]._def->_is_active &&
+          _collectors[collector_index].is_active() &&
           _threads[thread_index]._is_active);
 }
 
@@ -424,7 +410,7 @@ is_started(int collector_index, int thread_index) const {
   nassertr(collector_index >= 0 && collector_index < (int)_collectors.size(), false);
   nassertr(thread_index >= 0 && thread_index < (int)_threads.size(), false);
 
-  return (_collectors[collector_index]._def->_is_active &&
+  return (_collectors[collector_index].is_active() &&
           _threads[thread_index]._is_active &&
           _collectors[collector_index]._per_thread[thread_index]._nested_count != 0);
 }
@@ -444,7 +430,7 @@ start(int collector_index, int thread_index) {
 #endif
 
   if (client_is_connected() && 
-      _collectors[collector_index]._def->_is_active &&
+      _collectors[collector_index].is_active() &&
       _threads[thread_index]._is_active) {
     if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
       // This collector wasn't already started in this thread; record
@@ -471,7 +457,7 @@ start(int collector_index, int thread_index, float as_of) {
 #endif
 
   if (client_is_connected() && 
-      _collectors[collector_index]._def->_is_active &&
+      _collectors[collector_index].is_active() &&
       _threads[thread_index]._is_active) {
     if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
       // This collector wasn't already started in this thread; record
@@ -497,7 +483,7 @@ stop(int collector_index, int thread_index) {
 #endif
 
   if (client_is_connected() && 
-      _collectors[collector_index]._def->_is_active &&
+      _collectors[collector_index].is_active() &&
       _threads[thread_index]._is_active) {
     if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
       pstats_cat.warning()
@@ -533,7 +519,7 @@ stop(int collector_index, int thread_index, float as_of) {
 #endif
 
   if (client_is_connected() &&
-      _collectors[collector_index]._def->_is_active &&
+      _collectors[collector_index].is_active() &&
       _threads[thread_index]._is_active) {
     if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
       pstats_cat.warning()
@@ -565,7 +551,7 @@ stop(int collector_index, int thread_index, float as_of) {
 ////////////////////////////////////////////////////////////////////
 void PStatClient::
 clear_level(int collector_index, int thread_index) {
-  if (_collectors[collector_index]._def->_is_active) {
+  if (_collectors[collector_index].is_active()) {
     _collectors[collector_index]._per_thread[thread_index]._has_level = false;
     _collectors[collector_index]._per_thread[thread_index]._level = 0.0;
   }
@@ -582,8 +568,8 @@ clear_level(int collector_index, int thread_index) {
 ////////////////////////////////////////////////////////////////////
 void PStatClient::
 set_level(int collector_index, int thread_index, float level) {
-  if (client_is_connected() && _collectors[collector_index]._def->_is_active) {
-    level *= _collectors[collector_index]._def->_factor;
+  if (client_is_connected() && _collectors[collector_index].is_active()) {
+    level *= get_collector_def(collector_index)->_factor;
     _collectors[collector_index]._per_thread[thread_index]._has_level = true;
     _collectors[collector_index]._per_thread[thread_index]._level = level;
   }
@@ -602,8 +588,8 @@ set_level(int collector_index, int thread_index, float level) {
 ////////////////////////////////////////////////////////////////////
 void PStatClient::
 add_level(int collector_index, int thread_index, float increment) {
-  if (client_is_connected() && _collectors[collector_index]._def->_is_active) {
-    increment *= _collectors[collector_index]._def->_factor;
+  if (client_is_connected() && _collectors[collector_index].is_active()) {
+    increment *= get_collector_def(collector_index)->_factor;
     _collectors[collector_index]._per_thread[thread_index]._has_level = true;
     _collectors[collector_index]._per_thread[thread_index]._level += increment;
   }
@@ -620,7 +606,23 @@ add_level(int collector_index, int thread_index, float increment) {
 float PStatClient::
 get_level(int collector_index, int thread_index) const {
   return _collectors[collector_index]._per_thread[thread_index]._level /
-    _collectors[collector_index]._def->_factor;
+    get_collector_def(collector_index)->_factor;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PStatClient::Collector::make_def
+//       Access: Private
+//  Description: Creates the new PStatCollectorDef for this collector.
+////////////////////////////////////////////////////////////////////
+void PStatClient::Collector::
+make_def(const PStatClient *client, int this_index) {
+  _def = new PStatCollectorDef(this_index, _name);
+  if (_parent_index != this_index) {
+    const PStatCollectorDef *parent_def = 
+      client->_collectors[_parent_index].get_def(client, _parent_index);
+    _def->set_parent(*parent_def);
+  }
+  initialize_collector_def(client, _def);
 }
 
 #endif // DO_PSTATS

+ 22 - 2
panda/src/pstatclient/pStatClient.h

@@ -23,6 +23,7 @@
 
 #include "pStatFrameData.h"
 #include "pStatClientImpl.h"
+#include "pStatCollectorDef.h"
 #include "luse.h"
 #include "pmap.h"
 
@@ -61,7 +62,7 @@ PUBLISHED:
 
   INLINE int get_num_collectors() const;
   PStatCollector get_collector(int index) const;
-  const PStatCollectorDef &get_collector_def(int index) const;
+  INLINE PStatCollectorDef *get_collector_def(int index) const;
   string get_collector_name(int index) const;
   string get_collector_fullname(int index) const;
 
@@ -132,9 +133,28 @@ private:
   // stuff in PStatCollector and PStatCollectorDef is just fluff.)
   class Collector {
   public:
+    INLINE Collector(int parent_index, const string &name);
+    INLINE int get_parent_index() const;
+    INLINE const string &get_name() const;
+    INLINE bool is_active() const;
+    INLINE PStatCollectorDef *get_def(const PStatClient *client, int this_index) const;
+      
+  private:
+    void make_def(const PStatClient *client, int this_index);
+
+  private:
+    // This pointer is initially NULL, and will be filled in when it
+    // is first needed.
     PStatCollectorDef *_def;
-    ThingsByName _children;
 
+    // This data is used to create the PStatCollectorDef when it is
+    // needed.
+    int _parent_index;
+    string _name;
+
+  public:
+    // Relations to other collectors.
+    ThingsByName _children;
     PerThread _per_thread;
   };
   typedef pvector<Collector> Collectors;

+ 1 - 1
panda/src/pstatclient/pStatClientImpl.cxx

@@ -370,7 +370,7 @@ report_new_collectors() {
     PStatClientControlMessage message;
     message._type = PStatClientControlMessage::T_define_collectors;
     while (_collectors_reported < (int)_client->_collectors.size()) {
-      message._collectors.push_back(_client->_collectors[_collectors_reported]._def);
+      message._collectors.push_back(_client->get_collector_def(_collectors_reported));
       _collectors_reported++;
     }
 

+ 1 - 1
panda/src/pstatclient/pStatProperties.cxx

@@ -236,7 +236,7 @@ initialize_collector_def_from_table(const string &fullname, PStatCollectorDef *d
 //               by name; if one is found, the properties are applied.
 ////////////////////////////////////////////////////////////////////
 void
-initialize_collector_def(PStatClient *client, PStatCollectorDef *def) {
+initialize_collector_def(const PStatClient *client, PStatCollectorDef *def) {
   string fullname;
 
   if (def->_index == 0) {

+ 1 - 1
panda/src/pstatclient/pStatProperties.h

@@ -29,7 +29,7 @@ EXPCL_PANDA int get_current_pstat_major_version();
 EXPCL_PANDA int get_current_pstat_minor_version();
 
 #ifdef DO_PSTATS
-void initialize_collector_def(PStatClient *client, PStatCollectorDef *def);
+void initialize_collector_def(const PStatClient *client, PStatCollectorDef *def);
 #endif  // DO_PSTATS
 
 #endif