Răsfoiți Sursa

make ModelPool::garbage_collect() behave sensibly in the new loadModel() world

David Rose 19 ani în urmă
părinte
comite
763808f8e4

+ 3 - 3
panda/src/pgraph/modelPool.I

@@ -40,7 +40,7 @@ has_model(const string &filename) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool ModelPool::
 INLINE bool ModelPool::
 verify_model(const string &filename) {
 verify_model(const string &filename) {
-  return load_model(filename) != (PandaNode *)NULL;
+  return load_model(filename) != (ModelRoot *)NULL;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -52,7 +52,7 @@ verify_model(const string &filename) {
 //               loaded, returns that one instead.  If the model
 //               loaded, returns that one instead.  If the model
 //               file cannot be found, returns NULL.
 //               file cannot be found, returns NULL.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE PandaNode *ModelPool::
+INLINE ModelRoot *ModelPool::
 load_model(const string &filename, const LoaderOptions &options) {
 load_model(const string &filename, const LoaderOptions &options) {
   return get_ptr()->ns_load_model(filename, options);
   return get_ptr()->ns_load_model(filename, options);
 }
 }
@@ -66,7 +66,7 @@ load_model(const string &filename, const LoaderOptions &options) {
 //               same filename.
 //               same filename.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void ModelPool::
 INLINE void ModelPool::
-add_model(const string &filename, PandaNode *model) {
+add_model(const string &filename, ModelRoot *model) {
   get_ptr()->ns_add_model(filename, model);
   get_ptr()->ns_add_model(filename, model);
 }
 }
 
 

+ 18 - 9
panda/src/pgraph/modelPool.cxx

@@ -61,7 +61,7 @@ ns_has_model(const string &filename) {
 //       Access: Private
 //       Access: Private
 //  Description: The nonstatic implementation of load_model().
 //  Description: The nonstatic implementation of load_model().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-PandaNode *ModelPool::
+ModelRoot *ModelPool::
 ns_load_model(const string &filename, const LoaderOptions &options) {
 ns_load_model(const string &filename, const LoaderOptions &options) {
   {
   {
     MutexHolder holder(_lock);
     MutexHolder holder(_lock);
@@ -78,11 +78,20 @@ ns_load_model(const string &filename, const LoaderOptions &options) {
   LoaderOptions new_options(options);
   LoaderOptions new_options(options);
   new_options.set_flags(new_options.get_flags() | LoaderOptions::LF_no_ram_cache);
   new_options.set_flags(new_options.get_flags() | LoaderOptions::LF_no_ram_cache);
 
 
-  PT(PandaNode) node = model_loader.load_sync(filename, new_options);
-
-  if (node.is_null()) {
+  PT(PandaNode) panda_node = model_loader.load_sync(filename, new_options);
+  if (panda_node.is_null()) {
     // This model was not found.
     // This model was not found.
-    return (PandaNode *)NULL;
+    return (ModelRoot *)NULL;
+  }
+
+  PT(ModelRoot) node;
+  if (panda_node->is_of_type(ModelRoot::get_class_type())) {
+    node = DCAST(ModelRoot, panda_node);
+
+  } else {
+    // We have to construct a ModelRoot node to put it under.
+    node = new ModelRoot(filename);
+    node->add_child(panda_node);
   }
   }
 
 
   {
   {
@@ -109,7 +118,7 @@ ns_load_model(const string &filename, const LoaderOptions &options) {
 //  Description: The nonstatic implementation of add_model().
 //  Description: The nonstatic implementation of add_model().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ModelPool::
 void ModelPool::
-ns_add_model(const string &filename, PandaNode *model) {
+ns_add_model(const string &filename, ModelRoot *model) {
   MutexHolder holder(_lock);
   MutexHolder holder(_lock);
   // We blow away whatever model was there previously, if any.
   // We blow away whatever model was there previously, if any.
   _models[filename] = model;
   _models[filename] = model;
@@ -155,8 +164,8 @@ ns_garbage_collect() {
 
 
   Models::iterator ti;
   Models::iterator ti;
   for (ti = _models.begin(); ti != _models.end(); ++ti) {
   for (ti = _models.begin(); ti != _models.end(); ++ti) {
-    PandaNode *node = (*ti).second;
-    if (node->get_ref_count() == 1) {
+    ModelRoot *node = (*ti).second;
+    if (node->get_model_ref_count() == 1) {
       if (loader_cat.is_debug()) {
       if (loader_cat.is_debug()) {
         loader_cat.debug()
         loader_cat.debug()
           << "Releasing " << (*ti).first << "\n";
           << "Releasing " << (*ti).first << "\n";
@@ -184,7 +193,7 @@ ns_list_contents(ostream &out) const {
   Models::const_iterator ti;
   Models::const_iterator ti;
   for (ti = _models.begin(); ti != _models.end(); ++ti) {
   for (ti = _models.begin(); ti != _models.end(); ++ti) {
     out << "  " << (*ti).first
     out << "  " << (*ti).first
-        << " (count = " << (*ti).second->get_ref_count() << ")\n";
+        << " (count = " << (*ti).second->get_model_ref_count() << ")\n";
   }
   }
 }
 }
 
 

+ 6 - 6
panda/src/pgraph/modelPool.h

@@ -22,7 +22,7 @@
 #include "pandabase.h"
 #include "pandabase.h"
 
 
 #include "filename.h"
 #include "filename.h"
-#include "pandaNode.h"
+#include "modelRoot.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
 #include "pmutex.h"
 #include "pmutex.h"
 #include "pmap.h"
 #include "pmap.h"
@@ -51,10 +51,10 @@ class EXPCL_PANDA ModelPool {
 PUBLISHED:
 PUBLISHED:
   INLINE static bool has_model(const string &filename);
   INLINE static bool has_model(const string &filename);
   INLINE static bool verify_model(const string &filename);
   INLINE static bool verify_model(const string &filename);
-  INLINE static PandaNode *load_model(const string &filename,
+  INLINE static ModelRoot *load_model(const string &filename,
                                       const LoaderOptions &options = LoaderOptions());
                                       const LoaderOptions &options = LoaderOptions());
 
 
-  INLINE static void add_model(const string &filename, PandaNode *model);
+  INLINE static void add_model(const string &filename, ModelRoot *model);
   INLINE static void release_model(const string &filename);
   INLINE static void release_model(const string &filename);
   INLINE static void release_all_models();
   INLINE static void release_all_models();
 
 
@@ -67,9 +67,9 @@ private:
   INLINE ModelPool();
   INLINE ModelPool();
 
 
   bool ns_has_model(const string &filename);
   bool ns_has_model(const string &filename);
-  PandaNode *ns_load_model(const string &filename,
+  ModelRoot *ns_load_model(const string &filename,
                            const LoaderOptions &options);
                            const LoaderOptions &options);
-  void ns_add_model(const string &filename, PandaNode *model);
+  void ns_add_model(const string &filename, ModelRoot *model);
   void ns_release_model(const string &filename);
   void ns_release_model(const string &filename);
   void ns_release_all_models();
   void ns_release_all_models();
   int ns_garbage_collect();
   int ns_garbage_collect();
@@ -80,7 +80,7 @@ private:
   static ModelPool *_global_ptr;
   static ModelPool *_global_ptr;
 
 
   Mutex _lock;
   Mutex _lock;
-  typedef pmap<string,  PT(PandaNode) > Models;
+  typedef pmap<string,  PT(ModelRoot) > Models;
   Models _models;
   Models _models;
 };
 };
 
 

+ 60 - 4
panda/src/pgraph/modelRoot.I

@@ -16,24 +16,80 @@
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ModelRoot::Constructor
 //     Function: ModelRoot::Constructor
-//       Access: Public
+//       Access: Published
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE ModelRoot::
 INLINE ModelRoot::
 ModelRoot(const string &name) :
 ModelRoot(const string &name) :
-  ModelNode(name)
+  ModelNode(name),
+  _reference(new ModelRoot::ModelReference)
 {
 {
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: ModelRoot::get_model_ref_count
+//       Access: Published
+//  Description: Returns the number of copies that exist of this
+//               particular ModelRoot node.  Each time
+//               ModelRoot::copy_subgraph() or make_copy() is called
+//               (or some other copying mechanism, such as
+//               NodePath.copy_to(), is used), this count will
+//               increment by one in all copies; when one of the
+//               copies is destructed, this count will decrement.
+////////////////////////////////////////////////////////////////////
+INLINE int ModelRoot::
+get_model_ref_count() const {
+  return _reference->get_ref_count();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ModelRoot::get_reference
+//       Access: Published
+//  Description: Returns the pointer that represents the object shared
+//               between all copies of this ModelRoot.  Since there's
+//               not much associated with this object other than a
+//               reference count, normally there's not much reason to
+//               get the pointer (though it may be compared
+//               pointerwise with other ModelRoot objects).
+////////////////////////////////////////////////////////////////////
+INLINE ModelRoot::ModelReference *ModelRoot::
+get_reference() const {
+  return _reference;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ModelRoot::set_reference
+//       Access: Published
+//  Description: Changes the pointer that represents the object shared
+//               between all copies of this ModelRoot.  This will
+//               disassociate this ModelRoot from all of its copies.
+//               Normally, there's no reason to do this.
+////////////////////////////////////////////////////////////////////
+INLINE void ModelRoot::
+set_reference(ModelRoot::ModelReference *ref) {
+  _reference = ref;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ModelRoot::Copy Constructor
 //     Function: ModelRoot::Copy Constructor
-//       Access: Public
+//       Access: Protected
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE ModelRoot::
 INLINE ModelRoot::
 ModelRoot(const ModelRoot &copy) :
 ModelRoot(const ModelRoot &copy) :
-  ModelNode(copy)
+  ModelNode(copy),
+  _reference(copy._reference)
 {
 {
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: ModelRoot::ModelReference::Constructor
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE ModelRoot::ModelReference::
+ModelReference() {
+}

+ 16 - 2
panda/src/pgraph/modelRoot.h

@@ -20,7 +20,7 @@
 #define MODELROOT_H
 #define MODELROOT_H
 
 
 #include "pandabase.h"
 #include "pandabase.h"
-
+#include "referenceCount.h"
 #include "modelNode.h"
 #include "modelNode.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -34,7 +34,18 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA ModelRoot : public ModelNode {
 class EXPCL_PANDA ModelRoot : public ModelNode {
 PUBLISHED:
 PUBLISHED:
-  INLINE ModelRoot(const string &name );
+  INLINE ModelRoot(const string &name);
+
+  INLINE int get_model_ref_count() const;
+
+  // This class is used to unify references to the same model.
+  class ModelReference : public ReferenceCount {
+  PUBLISHED:
+    INLINE ModelReference();
+  };
+
+  INLINE ModelReference *get_reference() const;
+  INLINE void set_reference(ModelReference *ref);
 
 
 protected:
 protected:
   INLINE ModelRoot(const ModelRoot &copy);
   INLINE ModelRoot(const ModelRoot &copy);
@@ -42,6 +53,9 @@ protected:
 public:
 public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
 
 
+private:
+  PT(ModelReference) _reference;
+
 public:
 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);