Browse Source

further fixes to bam loader ordering

David Rose 18 years ago
parent
commit
0ebafd6c75

+ 0 - 1
panda/src/gobj/geomVertexArrayData.cxx

@@ -623,7 +623,6 @@ fillin(DatagramIterator &scan, BamReader *manager, void *extra_data) {
   } else {
   } else {
     // Now, the array data is just stored directly.
     // Now, the array data is just stored directly.
     size_t size = scan.get_uint32();
     size_t size = scan.get_uint32();
-
     _buffer.unclean_realloc(size);
     _buffer.unclean_realloc(size);
 
 
     const unsigned char *source_data = 
     const unsigned char *source_data = 

+ 17 - 1
panda/src/gobj/geomVertexData.cxx

@@ -1536,6 +1536,21 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
   return pi;
   return pi;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexData::require_fully_complete
+//       Access: Public, Virtual
+//  Description: Some objects require all of their nested pointers to
+//               have been completed before the objects themselves can
+//               be completed.  If this is the case, override this
+//               method to return true, and be careful with circular
+//               references (which would make the object unreadable
+//               from a bam file).
+////////////////////////////////////////////////////////////////////
+bool GeomVertexData::
+require_fully_complete() const {
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexData::finalize
 //     Function: GeomVertexData::finalize
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -1703,7 +1718,8 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
     // a SparseArray for each of them that reflects the complete
     // a SparseArray for each of them that reflects the complete
     // number of rows in the data.
     // number of rows in the data.
     SparseArray all_rows;
     SparseArray all_rows;
-    all_rows.set_range(0, _arrays[0].get_read_pointer()->get_num_rows());
+    CPT(GeomVertexArrayData) adata = _arrays[0].get_read_pointer();
+    all_rows.set_range(0, adata->get_num_rows());
 
 
     if (_slider_table != (SliderTable *)NULL) {
     if (_slider_table != (SliderTable *)NULL) {
       int num_sliders = _slider_table->get_num_sliders();
       int num_sliders = _slider_table->get_num_sliders();

+ 1 - 0
panda/src/gobj/geomVertexData.h

@@ -325,6 +325,7 @@ public:
   static void register_with_read_factory();
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &dg);
   virtual void write_datagram(BamWriter *manager, Datagram &dg);
   virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
   virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
+  virtual bool require_fully_complete() const;
 
 
   virtual void finalize(BamReader *manager);
   virtual void finalize(BamReader *manager);
 
 

+ 53 - 39
panda/src/putil/bamReader.cxx

@@ -301,35 +301,11 @@ resolve() {
     all_completed = true;
     all_completed = true;
     any_completed_this_pass = false;
     any_completed_this_pass = false;
     
     
-    // First do the PipelineCycler objects.    
-    CyclerPointers::iterator ci;
-    ci = _cycler_pointers.begin();
-    while (ci != _cycler_pointers.end()) {
-      PipelineCyclerBase *cycler = (*ci).first;
-      const vector_int &pointer_ids = (*ci).second;
-      
-      if (resolve_cycler_pointers(cycler, pointer_ids)) {
-        // Now remove this cycler from the list of things that need
-        // completion.  We have to be a bit careful when deleting things
-        // from the STL container while we are traversing it.
-        CyclerPointers::iterator old = ci;
-        ++ci;
-        _cycler_pointers.erase(old);
-        any_completed_this_pass = true;
-        
-      } else {
-        // Couldn't complete this cycler yet; it'll wait for next time.
-        ++ci;
-        all_completed = false;
-      }
-    }
-    
-    // Now do the main objects.
     ObjectPointers::iterator oi;
     ObjectPointers::iterator oi;
     oi = _object_pointers.begin();
     oi = _object_pointers.begin();
     while (oi != _object_pointers.end()) {
     while (oi != _object_pointers.end()) {
       int object_id = (*oi).first;
       int object_id = (*oi).first;
-      const vector_int &pointer_ids = (*oi).second;
+      PointerReference &pref = (*oi).second;
 
 
       CreatedObjs::iterator ci = _created_objs.find(object_id);
       CreatedObjs::iterator ci = _created_objs.find(object_id);
       nassertr(ci != _created_objs.end(), false);
       nassertr(ci != _created_objs.end(), false);
@@ -338,7 +314,7 @@ resolve() {
       
       
       TypedWritable *object_ptr = created_obj._ptr;
       TypedWritable *object_ptr = created_obj._ptr;
 
 
-      if (resolve_object_pointers(object_ptr, pointer_ids)) {
+      if (resolve_object_pointers(object_ptr, pref)) {
         // Now remove this object from the list of things that need
         // Now remove this object from the list of things that need
         // completion.  We have to be a bit careful when deleting things
         // completion.  We have to be a bit careful when deleting things
         // from the STL container while we are traversing it.
         // from the STL container while we are traversing it.
@@ -574,12 +550,13 @@ read_pointer(DatagramIterator &scan) {
   // Read the object ID, and associate it with the requesting object.
   // Read the object ID, and associate it with the requesting object.
   int object_id = read_object_id(scan);
   int object_id = read_object_id(scan);
 
 
+  PointerReference &pref = _object_pointers[requestor_id];
   if (_reading_cycler == (PipelineCyclerBase *)NULL) {
   if (_reading_cycler == (PipelineCyclerBase *)NULL) {
     // This is not being read within a read_cdata() call.
     // This is not being read within a read_cdata() call.
-    _object_pointers[requestor_id].push_back(object_id);
+    pref._objects.push_back(object_id);
   } else {
   } else {
     // This *is* being read within a read_cdata() call.
     // This *is* being read within a read_cdata() call.
-    _cycler_pointers[_reading_cycler].push_back(object_id);
+    pref._cycler_pointers[_reading_cycler].push_back(object_id);
   }
   }
 
 
   // If the object ID is zero (which indicates a NULL pointer), we
   // If the object ID is zero (which indicates a NULL pointer), we
@@ -1054,7 +1031,39 @@ p_read_object() {
 //               and returns true; otherwise, returns false.
 //               and returns true; otherwise, returns false.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool BamReader::
 bool BamReader::
-resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids) {
+resolve_object_pointers(TypedWritable *object, 
+                        BamReader::PointerReference &pref) {
+  // Some objects further require all of their nested objects to have
+  // been completed (i.e. complete_pointers has been called on each
+  // nested object) before they can themselves be completed.
+  bool require_fully_complete = object->require_fully_complete();
+
+  // First do the PipelineCycler objects.    
+  CyclerPointers::iterator ci;
+  ci = pref._cycler_pointers.begin();
+  while (ci != pref._cycler_pointers.end()) {
+    PipelineCyclerBase *cycler = (*ci).first;
+    const vector_int &pointer_ids = (*ci).second;
+      
+    if (resolve_cycler_pointers(cycler, pointer_ids, require_fully_complete)) {
+      // Now remove this cycler from the list of things that need
+      // completion.  We have to be a bit careful when deleting things
+      // from the STL container while we are traversing it.
+      CyclerPointers::iterator old = ci;
+      ++ci;
+      pref._cycler_pointers.erase(old);
+      
+    } else {
+      // Couldn't complete this cycler yet; it'll wait for next time.
+      ++ci;
+    }
+  }
+
+  if (!pref._cycler_pointers.empty()) {
+    // If we didn't get all the cyclers, we have to wait.
+    return false;
+  }
+  
   // Now make sure we have all of the pointers this object is
   // Now make sure we have all of the pointers this object is
   // waiting for.  If any of the pointers has not yet been read
   // waiting for.  If any of the pointers has not yet been read
   // in, we can't resolve this object--we can't do anything for a
   // in, we can't resolve this object--we can't do anything for a
@@ -1062,15 +1071,12 @@ resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids) {
   // that object.
   // that object.
   bool is_complete = true;
   bool is_complete = true;
 
 
-  // Some objects further require all of their nested objects to have
-  // been completed (i.e. complete_pointers has been called on each
-  // nested object) before they can themselves be completed.
-  bool require_fully_complete = object->require_fully_complete();
-
   vector_typedWritable references;
   vector_typedWritable references;
 
 
   vector_int::const_iterator pi;
   vector_int::const_iterator pi;
-  for (pi = pointer_ids.begin(); pi != pointer_ids.end() && is_complete; ++pi) {
+  for (pi = pref._objects.begin(); 
+       pi != pref._objects.end() && is_complete; 
+       ++pi) {
     int child_id = (*pi);
     int child_id = (*pi);
     if (child_id == 0) {
     if (child_id == 0) {
       // A NULL pointer is a NULL pointer.
       // A NULL pointer is a NULL pointer.
@@ -1106,7 +1112,7 @@ resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids) {
       
       
   if (is_complete) {
   if (is_complete) {
     // Okay, here's the complete list of pointers for you!
     // Okay, here's the complete list of pointers for you!
-    nassertr(references.size() == pointer_ids.size(), false);
+    nassertr(references.size() == pref._objects.size(), false);
 
 
     if (bam_cat.is_spam()) {
     if (bam_cat.is_spam()) {
       bam_cat.spam()
       bam_cat.spam()
@@ -1143,7 +1149,8 @@ resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool BamReader::
 bool BamReader::
 resolve_cycler_pointers(PipelineCyclerBase *cycler,
 resolve_cycler_pointers(PipelineCyclerBase *cycler,
-                        const vector_int &pointer_ids) {
+                        const vector_int &pointer_ids,
+                        bool require_fully_complete) {
   // Now make sure we have all of the pointers this cycler is
   // Now make sure we have all of the pointers this cycler is
   // waiting for.  If any of the pointers has not yet been read
   // waiting for.  If any of the pointers has not yet been read
   // in, we can't resolve this cycler--we can't do anything for a
   // in, we can't resolve this cycler--we can't do anything for a
@@ -1175,8 +1182,15 @@ resolve_cycler_pointers(PipelineCyclerBase *cycler,
           is_complete = false;
           is_complete = false;
 
 
         } else {
         } else {
-          // Yes, it's ready.
-          references.push_back(child_obj._ptr);
+          if (require_fully_complete && 
+              _object_pointers.find(child_id) != _object_pointers.end()) {
+            // It's not yet complete itself.
+            is_complete = false;
+            
+          } else {
+            // Yes, it's ready.
+            references.push_back(child_obj._ptr);
+          }
         }
         }
       }
       }
     }
     }

+ 12 - 7
panda/src/putil/bamReader.h

@@ -149,12 +149,15 @@ private:
   INLINE static void create_factory();
   INLINE static void create_factory();
 
 
 private:
 private:
+  class PointerReference;
+
   void free_object_ids(DatagramIterator &scan);
   void free_object_ids(DatagramIterator &scan);
   int read_object_id(DatagramIterator &scan);
   int read_object_id(DatagramIterator &scan);
   int read_pta_id(DatagramIterator &scan);
   int read_pta_id(DatagramIterator &scan);
   int p_read_object();
   int p_read_object();
-  bool resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids);
-  bool resolve_cycler_pointers(PipelineCyclerBase *cycler, const vector_int &pointer_ids);
+  bool resolve_object_pointers(TypedWritable *object, PointerReference &pref);
+  bool resolve_cycler_pointers(PipelineCyclerBase *cycler, const vector_int &pointer_ids,
+                               bool require_fully_complete);
   void finalize();
   void finalize();
 
 
   INLINE bool get_datagram(Datagram &datagram);
   INLINE bool get_datagram(Datagram &datagram);
@@ -215,12 +218,14 @@ private:
   // completed, along with the object ID's of the pointers they need,
   // completed, along with the object ID's of the pointers they need,
   // in the order in which read_pointer() was called, so that we may
   // in the order in which read_pointer() was called, so that we may
   // call the appropriate complete_pointers() later.
   // call the appropriate complete_pointers() later.
-  typedef phash_map<int, vector_int, int_hash> ObjectPointers;
-  ObjectPointers _object_pointers;
-
-  // Ditto, for the PiplineCycler objects.
   typedef phash_map<PipelineCyclerBase *, vector_int, pointer_hash> CyclerPointers;
   typedef phash_map<PipelineCyclerBase *, vector_int, pointer_hash> CyclerPointers;
-  CyclerPointers _cycler_pointers;
+  class PointerReference {
+  public:
+    vector_int _objects;
+    CyclerPointers _cycler_pointers;
+  };
+  typedef phash_map<int, PointerReference, int_hash> ObjectPointers;
+  ObjectPointers _object_pointers;
 
 
   // This is the number of extra objects that must still be read (and
   // This is the number of extra objects that must still be read (and
   // saved in the _created_objs map) before returning from
   // saved in the _created_objs map) before returning from