mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
implement cache-check-timestamps for models
This commit is contained in:
parent
7db604c791
commit
ec81b415a5
@ -30,9 +30,15 @@ has_model(const Filename &filename) {
|
|||||||
// Description: Loads the given filename up as a model, if it has
|
// Description: Loads the given filename up as a model, if it has
|
||||||
// not already been loaded, and returns true to indicate
|
// not already been loaded, and returns true to indicate
|
||||||
// success, or false to indicate failure. If this
|
// success, or false to indicate failure. If this
|
||||||
// returns true, it is guaranteed that a subsequent call
|
// returns true, it is probable that a subsequent call
|
||||||
// to load_model() with the same model name will
|
// to load_model() with the same model name will
|
||||||
// return a valid Node pointer.
|
// return a valid PandaNode.
|
||||||
|
//
|
||||||
|
// However, even if this returns true, it is still
|
||||||
|
// possible for a subsequent call to load_model() to
|
||||||
|
// fail. This can happen if cache-check-timestamps is
|
||||||
|
// true, and the on-disk file is subsequently modified
|
||||||
|
// to replace it with an invalid model.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE bool ModelPool::
|
INLINE bool ModelPool::
|
||||||
verify_model(const Filename &filename) {
|
verify_model(const Filename &filename) {
|
||||||
@ -45,8 +51,11 @@ verify_model(const Filename &filename) {
|
|||||||
// Description: Loads the given filename up as a model, if it has
|
// Description: Loads the given filename up as a model, if it has
|
||||||
// not already been loaded, and returns the new model.
|
// not already been loaded, and returns the new model.
|
||||||
// If a model with the same filename was previously
|
// If a model with the same filename was previously
|
||||||
// loaded, returns that one instead. If the model
|
// loaded, returns that one instead (unless
|
||||||
// file cannot be found, returns NULL.
|
// cache-check-timestamps is true and the file has
|
||||||
|
// recently changed). If the model file cannot be
|
||||||
|
// found, or cannot be loaded for some reason, returns
|
||||||
|
// NULL.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE ModelRoot *ModelPool::
|
INLINE ModelRoot *ModelPool::
|
||||||
load_model(const Filename &filename, const LoaderOptions &options) {
|
load_model(const Filename &filename, const LoaderOptions &options) {
|
||||||
@ -57,9 +66,8 @@ load_model(const Filename &filename, const LoaderOptions &options) {
|
|||||||
// Function: ModelPool::add_model
|
// Function: ModelPool::add_model
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
// Description: Adds the indicated already-loaded model to the
|
// Description: Adds the indicated already-loaded model to the
|
||||||
// pool. The model will always replace any
|
// pool. The model will replace any previously-loaded
|
||||||
// previously-loaded model in the pool that had the
|
// model in the pool that had the same filename.
|
||||||
// same filename.
|
|
||||||
//
|
//
|
||||||
// This two-parameter version of this method is
|
// This two-parameter version of this method is
|
||||||
// deprecated; use the one-parameter add_model(model)
|
// deprecated; use the one-parameter add_model(model)
|
||||||
@ -91,9 +99,8 @@ release_model(const Filename &filename) {
|
|||||||
// Function: ModelPool::add_model
|
// Function: ModelPool::add_model
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
// Description: Adds the indicated already-loaded model to the
|
// Description: Adds the indicated already-loaded model to the
|
||||||
// pool. The model will always replace any
|
// pool. The model will replace any previously-loaded
|
||||||
// previously-loaded model in the pool that had the
|
// model in the pool that had the same filename.
|
||||||
// same filename.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void ModelPool::
|
INLINE void ModelPool::
|
||||||
add_model(ModelRoot *model) {
|
add_model(ModelRoot *model) {
|
||||||
@ -105,9 +112,10 @@ add_model(ModelRoot *model) {
|
|||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
// Description: Removes the indicated model from the pool,
|
// Description: Removes the indicated model from the pool,
|
||||||
// indicating it will never be loaded again; the model
|
// indicating it will never be loaded again; the model
|
||||||
// may then be freed. If this function is never called,
|
// may then be freed. If this function (and
|
||||||
// a reference count will be maintained on every model
|
// garbage_collect()) is never called, a reference count
|
||||||
// every loaded, and models will never be freed.
|
// will be maintained on every model every loaded, and
|
||||||
|
// models will never be freed.
|
||||||
//
|
//
|
||||||
// The model's get_fullpath() value should not have been
|
// The model's get_fullpath() value should not have been
|
||||||
// changed during its lifetime, or this function may
|
// changed during its lifetime, or this function may
|
||||||
|
@ -57,16 +57,67 @@ ns_has_model(const Filename &filename) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
ModelRoot *ModelPool::
|
ModelRoot *ModelPool::
|
||||||
ns_load_model(const Filename &filename, const LoaderOptions &options) {
|
ns_load_model(const Filename &filename, const LoaderOptions &options) {
|
||||||
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||||
|
|
||||||
|
PT(ModelRoot) cached_model;
|
||||||
|
bool got_cached_model = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
LightMutexHolder holder(_lock);
|
LightMutexHolder holder(_lock);
|
||||||
Models::const_iterator ti;
|
Models::const_iterator ti;
|
||||||
ti = _models.find(filename);
|
ti = _models.find(filename);
|
||||||
if (ti != _models.end()) {
|
if (ti != _models.end()) {
|
||||||
// This model was previously loaded.
|
// This filename was previously loaded.
|
||||||
return (*ti).second;
|
cached_model = (*ti).second;
|
||||||
|
got_cached_model = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (got_cached_model) {
|
||||||
|
if (pgraph_cat.is_debug()) {
|
||||||
|
pgraph_cat.debug()
|
||||||
|
<< "ModelPool found " << cached_model << " for " << filename << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cached_model == NULL) {
|
||||||
|
// This filename was previously attempted, but it did not
|
||||||
|
// exist (or the model could not be loaded for some reason).
|
||||||
|
if (cache_check_timestamps) {
|
||||||
|
// Check to see if there is a file there now.
|
||||||
|
if (vfs->exists(filename)) {
|
||||||
|
// There is, so try to load it.
|
||||||
|
got_cached_model = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// This filename was previously attempted, and successfully
|
||||||
|
// loaded.
|
||||||
|
if (cache_check_timestamps && cached_model->get_timestamp() != 0 &&
|
||||||
|
!cached_model->get_fullpath().empty()) {
|
||||||
|
// Compare the timestamp to the file on-disk.
|
||||||
|
PT(VirtualFile) vfile = vfs->get_file(cached_model->get_fullpath());
|
||||||
|
if (vfile == NULL) {
|
||||||
|
// The file has disappeared! Look further along the model-path.
|
||||||
|
got_cached_model = false;
|
||||||
|
|
||||||
|
} else if (vfile->get_timestamp() > cached_model->get_timestamp()) {
|
||||||
|
// The file still exists, but it has a newer timestamp than
|
||||||
|
// the one we previously loaded. Force it to re-load.
|
||||||
|
got_cached_model = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (got_cached_model) {
|
||||||
|
if (pgraph_cat.is_debug()) {
|
||||||
|
pgraph_cat.debug()
|
||||||
|
<< "ModelPool returning " << cached_model << " for " << filename << "\n";
|
||||||
|
}
|
||||||
|
return cached_model;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look on disk for the current file.
|
||||||
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) &
|
||||||
~(LoaderOptions::LF_search | LoaderOptions::LF_report_errors));
|
~(LoaderOptions::LF_search | LoaderOptions::LF_report_errors));
|
||||||
@ -97,11 +148,15 @@ ns_load_model(const Filename &filename, const LoaderOptions &options) {
|
|||||||
// another thread.
|
// another thread.
|
||||||
Models::const_iterator ti;
|
Models::const_iterator ti;
|
||||||
ti = _models.find(filename);
|
ti = _models.find(filename);
|
||||||
if (ti != _models.end()) {
|
if (ti != _models.end() && (*ti).second != cached_model) {
|
||||||
// This model was previously loaded.
|
// This model was previously loaded.
|
||||||
return (*ti).second;
|
return (*ti).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pgraph_cat.is_debug()) {
|
||||||
|
pgraph_cat.debug()
|
||||||
|
<< "ModelPool storing " << node << " for " << filename << "\n";
|
||||||
|
}
|
||||||
_models[filename] = node;
|
_models[filename] = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user