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

This commit is contained in:
David Rose 2006-10-23 20:50:09 +00:00
parent 064fd1dc07
commit 763808f8e4
5 changed files with 103 additions and 24 deletions

View File

@ -40,7 +40,7 @@ has_model(const string &filename) {
////////////////////////////////////////////////////////////////////
INLINE bool ModelPool::
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
// file cannot be found, returns NULL.
////////////////////////////////////////////////////////////////////
INLINE PandaNode *ModelPool::
INLINE ModelRoot *ModelPool::
load_model(const string &filename, const LoaderOptions &options) {
return get_ptr()->ns_load_model(filename, options);
}
@ -66,7 +66,7 @@ load_model(const string &filename, const LoaderOptions &options) {
// same filename.
////////////////////////////////////////////////////////////////////
INLINE void ModelPool::
add_model(const string &filename, PandaNode *model) {
add_model(const string &filename, ModelRoot *model) {
get_ptr()->ns_add_model(filename, model);
}

View File

@ -61,7 +61,7 @@ ns_has_model(const string &filename) {
// Access: Private
// Description: The nonstatic implementation of load_model().
////////////////////////////////////////////////////////////////////
PandaNode *ModelPool::
ModelRoot *ModelPool::
ns_load_model(const string &filename, const LoaderOptions &options) {
{
MutexHolder holder(_lock);
@ -78,11 +78,20 @@ ns_load_model(const string &filename, const LoaderOptions &options) {
LoaderOptions new_options(options);
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.
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().
////////////////////////////////////////////////////////////////////
void ModelPool::
ns_add_model(const string &filename, PandaNode *model) {
ns_add_model(const string &filename, ModelRoot *model) {
MutexHolder holder(_lock);
// We blow away whatever model was there previously, if any.
_models[filename] = model;
@ -155,8 +164,8 @@ ns_garbage_collect() {
Models::iterator 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()) {
loader_cat.debug()
<< "Releasing " << (*ti).first << "\n";
@ -184,7 +193,7 @@ ns_list_contents(ostream &out) const {
Models::const_iterator ti;
for (ti = _models.begin(); ti != _models.end(); ++ti) {
out << " " << (*ti).first
<< " (count = " << (*ti).second->get_ref_count() << ")\n";
<< " (count = " << (*ti).second->get_model_ref_count() << ")\n";
}
}

View File

@ -22,7 +22,7 @@
#include "pandabase.h"
#include "filename.h"
#include "pandaNode.h"
#include "modelRoot.h"
#include "pointerTo.h"
#include "pmutex.h"
#include "pmap.h"
@ -51,10 +51,10 @@ class EXPCL_PANDA ModelPool {
PUBLISHED:
INLINE static bool has_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());
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_all_models();
@ -67,9 +67,9 @@ private:
INLINE ModelPool();
bool ns_has_model(const string &filename);
PandaNode *ns_load_model(const string &filename,
ModelRoot *ns_load_model(const string &filename,
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_all_models();
int ns_garbage_collect();
@ -80,7 +80,7 @@ private:
static ModelPool *_global_ptr;
Mutex _lock;
typedef pmap<string, PT(PandaNode) > Models;
typedef pmap<string, PT(ModelRoot) > Models;
Models _models;
};

View File

@ -16,24 +16,80 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: ModelRoot::Constructor
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE ModelRoot::
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
// Access: Public
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
INLINE ModelRoot::
ModelRoot(const ModelRoot &copy) :
ModelNode(copy)
ModelNode(copy),
_reference(copy._reference)
{
}
////////////////////////////////////////////////////////////////////
// Function: ModelRoot::ModelReference::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE ModelRoot::ModelReference::
ModelReference() {
}

View File

@ -20,7 +20,7 @@
#define MODELROOT_H
#include "pandabase.h"
#include "referenceCount.h"
#include "modelNode.h"
////////////////////////////////////////////////////////////////////
@ -34,7 +34,18 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA ModelRoot : public ModelNode {
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:
INLINE ModelRoot(const ModelRoot &copy);
@ -42,6 +53,9 @@ protected:
public:
virtual PandaNode *make_copy() const;
private:
PT(ModelReference) _reference;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);