loader uses vfs

This commit is contained in:
David Rose 2002-08-04 16:58:35 +00:00
parent c1db2dc152
commit fa59c3e37f
27 changed files with 541 additions and 136 deletions

View File

@ -94,12 +94,15 @@ add_directory(Multifile &multifile, const Filename &directory_name) {
okflag = false; okflag = false;
} else { } else {
if (verbose) { string new_subfile_name =
cout << subfile_name << "\n"; multifile.add_subfile(subfile_name, subfile_name);
} if (new_subfile_name.empty()) {
if (!multifile.add_subfile(subfile_name, subfile_name)) {
cerr << "Unable to add " << subfile_name << ".\n"; cerr << "Unable to add " << subfile_name << ".\n";
okflag = false; okflag = false;
} else {
if (verbose) {
cout << new_subfile_name << "\n";
}
} }
} }
} }
@ -140,12 +143,15 @@ add_files(int argc, char *argv[]) {
okflag = false; okflag = false;
} else { } else {
if (verbose) { string new_subfile_name =
cout << subfile_name << "\n"; multifile.add_subfile(subfile_name, subfile_name);
} if (new_subfile_name.empty()) {
if (!multifile.add_subfile(subfile_name, subfile_name)) {
cerr << "Unable to add " << subfile_name << ".\n"; cerr << "Unable to add " << subfile_name << ".\n";
okflag = false; okflag = false;
} else {
if (verbose) {
cout << new_subfile_name << "\n";
}
} }
} }
} }

View File

@ -24,9 +24,10 @@
#include "eggPoolUniquifier.h" #include "eggPoolUniquifier.h"
#include "config_egg.h" #include "config_egg.h"
#include <config_util.h> #include "config_util.h"
#include <string_utils.h> #include "string_utils.h"
#include <dSearchPath.h> #include "dSearchPath.h"
#include "virtualFileSystem.h"
extern int eggyyparse(void); extern int eggyyparse(void);
#include "parserDefs.h" #include "parserDefs.h"
@ -45,6 +46,20 @@ TypeHandle EggData::_type_handle;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool EggData:: bool EggData::
resolve_egg_filename(Filename &egg_filename, const DSearchPath &searchpath) { resolve_egg_filename(Filename &egg_filename, const DSearchPath &searchpath) {
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (egg_filename.is_fully_qualified() && vfs->exists(egg_filename)) {
return true;
}
vfs->resolve_filename(egg_filename, searchpath, "egg") ||
vfs->resolve_filename(egg_filename, get_egg_path(), "egg") ||
vfs->resolve_filename(egg_filename, get_model_path(), "egg");
return vfs->exists(egg_filename);
} else {
if (egg_filename.is_fully_qualified() && egg_filename.exists()) { if (egg_filename.is_fully_qualified() && egg_filename.exists()) {
return true; return true;
} }
@ -55,6 +70,7 @@ resolve_egg_filename(Filename &egg_filename, const DSearchPath &searchpath) {
return egg_filename.exists(); return egg_filename.exists();
} }
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: EggData::read // Function: EggData::read
@ -76,6 +92,32 @@ read(Filename filename) {
return false; return false;
} }
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
filename.set_text();
set_egg_filename(filename);
istream *file = vfs->open_read_file(filename);
if (file == (istream *)NULL) {
egg_cat.error() << "Unable to open " << filename << "\n";
return false;
}
egg_cat.info()
<< "Reading " << filename << "\n";
bool read_ok = read(*file);
delete file;
return read_ok;
} else {
if (!resolve_egg_filename(filename)) {
egg_cat.error()
<< "Could not find " << filename << "\n";
return false;
}
filename.set_text(); filename.set_text();
set_egg_filename(filename); set_egg_filename(filename);
@ -90,6 +132,7 @@ read(Filename filename) {
return read(file); return read(file);
} }
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -20,6 +20,8 @@
#include "eggLoader.h" #include "eggLoader.h"
#include "config_egg2pg.h" #include "config_egg2pg.h"
#include "sceneGraphReducer.h" #include "sceneGraphReducer.h"
#include "virtualFileSystem.h"
#include "config_util.h"
static PT(PandaNode) static PT(PandaNode)
load_from_loader(EggLoader &loader) { load_from_loader(EggLoader &loader) {
@ -54,29 +56,56 @@ load_from_loader(EggLoader &loader) {
PT(PandaNode) PT(PandaNode)
load_egg_file(const string &filename, CoordinateSystem cs) { load_egg_file(const string &filename, CoordinateSystem cs) {
Filename egg_filename = Filename::text_filename(filename); Filename egg_filename = Filename::text_filename(filename);
if (!egg_filename.exists()) { if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->exists(egg_filename)) {
egg2pg_cat.error() egg2pg_cat.error()
<< "Could not find " << egg_filename << "\n"; << "Could not find " << egg_filename << "\n";
return NULL; return NULL;
} }
} else {
if (!egg_filename.exists()) {
egg2pg_cat.error()
<< "Could not find " << egg_filename << "\n";
return NULL;
}
}
egg2pg_cat.info() egg2pg_cat.info()
<< "Reading " << egg_filename << "\n"; << "Reading " << egg_filename << "\n";
ifstream file;
if (!egg_filename.open_read(file)) {
egg2pg_cat.error()
<< "Could not open " << egg_filename << " for reading.\n";
return NULL;
}
EggLoader loader; EggLoader loader;
loader._data.set_egg_filename(egg_filename); loader._data.set_egg_filename(egg_filename);
if (cs != CS_default) { if (cs != CS_default) {
loader._data.set_coordinate_system(cs); loader._data.set_coordinate_system(cs);
} }
bool okflag;
if (!loader._data.read(file)) { if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
istream *istr = vfs->open_read_file(egg_filename);
if (istr == (istream *)NULL) {
egg2pg_cat.error()
<< "Could not open " << egg_filename << " for reading.\n";
return NULL;
}
okflag = loader._data.read(*istr);
delete istr;
} else {
ifstream file;
if (!egg_filename.open_read(file)) {
egg2pg_cat.error()
<< "Could not open " << egg_filename << " for reading.\n";
return NULL;
}
okflag = loader._data.read(file);
}
if (!okflag) {
egg2pg_cat.error() egg2pg_cat.error()
<< "Error reading " << egg_filename << "\n"; << "Error reading " << egg_filename << "\n";
return NULL; return NULL;

View File

@ -13,9 +13,8 @@
checksumHashGenerator.I checksumHashGenerator.h circBuffer.I \ checksumHashGenerator.I checksumHashGenerator.h circBuffer.I \
circBuffer.h clockObject.I clockObject.h config_express.h \ circBuffer.h clockObject.I clockObject.h config_express.h \
datagram.I datagram.h datagramGenerator.I \ datagram.I datagram.h datagramGenerator.I \
datagramGenerator.h datagramInputFile.I datagramInputFile.h \ datagramGenerator.h \
datagramIterator.I datagramIterator.h datagramOutputFile.I \ datagramIterator.I datagramIterator.h datagramSink.I datagramSink.h \
datagramOutputFile.h datagramSink.I datagramSink.h \
dcast.T dcast.h \ dcast.T dcast.h \
error_utils.h \ error_utils.h \
get_config_path.h hashGeneratorBase.I hashGeneratorBase.h \ get_config_path.h hashGeneratorBase.I hashGeneratorBase.h \
@ -51,8 +50,8 @@
#define INCLUDED_SOURCES \ #define INCLUDED_SOURCES \
buffer.cxx checksumHashGenerator.cxx clockObject.cxx \ buffer.cxx checksumHashGenerator.cxx clockObject.cxx \
config_express.cxx datagram.cxx datagramGenerator.cxx \ config_express.cxx datagram.cxx datagramGenerator.cxx \
datagramInputFile.cxx datagramIterator.cxx \ datagramIterator.cxx \
datagramOutputFile.cxx datagramSink.cxx dcast.cxx error_utils.cxx \ datagramSink.cxx dcast.cxx error_utils.cxx \
get_config_path.cxx \ get_config_path.cxx \
hashGeneratorBase.cxx hashVal.cxx indent.cxx \ hashGeneratorBase.cxx hashVal.cxx indent.cxx \
memoryInfo.cxx memoryUsage.cxx memoryUsagePointerCounts.cxx \ memoryInfo.cxx memoryUsage.cxx memoryUsagePointerCounts.cxx \
@ -71,10 +70,9 @@
bigEndian.h buffer.I buffer.h checksumHashGenerator.I \ bigEndian.h buffer.I buffer.h checksumHashGenerator.I \
checksumHashGenerator.h circBuffer.I circBuffer.h clockObject.I \ checksumHashGenerator.h circBuffer.I circBuffer.h clockObject.I \
clockObject.h config_express.h datagram.I datagram.h \ clockObject.h config_express.h datagram.I datagram.h \
datagramGenerator.I datagramGenerator.h datagramInputFile.I \ datagramGenerator.I datagramGenerator.h \
datagramInputFile.h datagramIterator.I datagramIterator.h \ datagramIterator.I datagramIterator.h \
datagramOutputFile.I datagramOutputFile.h datagramSink.I \ datagramSink.I datagramSink.h dcast.T dcast.h \
datagramSink.h dcast.T dcast.h \
error_utils.h get_config_path.h hashGeneratorBase.I \ error_utils.h get_config_path.h hashGeneratorBase.I \
hashGeneratorBase.h hashVal.I hashVal.h \ hashGeneratorBase.h hashVal.I hashVal.h \
indent.I indent.h \ indent.I indent.h \

View File

@ -5,9 +5,7 @@
#include "config_express.cxx" #include "config_express.cxx"
#include "datagram.cxx" #include "datagram.cxx"
#include "datagramGenerator.cxx" #include "datagramGenerator.cxx"
#include "datagramInputFile.cxx"
#include "datagramIterator.cxx" #include "datagramIterator.cxx"
#include "datagramOutputFile.cxx"
#include "datagramSink.cxx" #include "datagramSink.cxx"
#include "dcast.cxx" #include "dcast.cxx"
#include "get_config_path.cxx" #include "get_config_path.cxx"

View File

@ -114,9 +114,7 @@ normalize_streampos(streampos fpos) const {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE Multifile::Subfile:: INLINE Multifile::Subfile::
Subfile(const string &name) : Subfile() {
_name(name)
{
_index_start = 0; _index_start = 0;
_data_start = 0; _data_start = 0;
_data_length = 0; _data_length = 0;

View File

@ -288,21 +288,21 @@ set_scale_factor(size_t scale_factor) {
// The file named by filename will be read and added to // The file named by filename will be read and added to
// the Multifile at the next call to flush(). // the Multifile at the next call to flush().
// //
// Returns true on success, false on failure. // Returns the subfile name on success (it might have
// been modified slightly), or empty string on failure.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool Multifile:: string Multifile::
add_subfile(const string &subfile_name, const Filename &filename) { add_subfile(const string &subfile_name, const Filename &filename) {
nassertr(is_write_valid(), false); nassertr(is_write_valid(), string());
if (!filename.exists()) { if (!filename.exists()) {
return false; return string();
} }
Subfile *subfile = new Subfile(subfile_name); Subfile *subfile = new Subfile;
subfile->_source_filename = filename; subfile->_source_filename = filename;
subfile->_source_filename.set_binary(); subfile->_source_filename.set_binary();
return add_new_subfile(subfile); return add_new_subfile(subfile_name, subfile);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -537,7 +537,8 @@ get_num_subfiles() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
int Multifile:: int Multifile::
find_subfile(const string &subfile_name) const { find_subfile(const string &subfile_name) const {
Subfile find_subfile(subfile_name); Subfile find_subfile;
find_subfile._name = subfile_name;
Subfiles::const_iterator fi; Subfiles::const_iterator fi;
fi = _subfiles.find(&find_subfile); fi = _subfiles.find(&find_subfile);
if (fi == _subfiles.end()) { if (fi == _subfiles.end()) {
@ -561,7 +562,8 @@ has_directory(const string &subfile_name) const {
if (!prefix.empty()) { if (!prefix.empty()) {
prefix += '/'; prefix += '/';
} }
Subfile find_subfile(prefix); Subfile find_subfile;
find_subfile._name = prefix;
Subfiles::const_iterator fi; Subfiles::const_iterator fi;
fi = _subfiles.upper_bound(&find_subfile); fi = _subfiles.upper_bound(&find_subfile);
if (fi == _subfiles.end()) { if (fi == _subfiles.end()) {
@ -597,7 +599,8 @@ scan_directory(vector_string &contents, const string &subfile_name) const {
if (!prefix.empty()) { if (!prefix.empty()) {
prefix += '/'; prefix += '/';
} }
Subfile find_subfile(prefix); Subfile find_subfile;
find_subfile._name = prefix;
Subfiles::const_iterator fi; Subfiles::const_iterator fi;
fi = _subfiles.upper_bound(&find_subfile); fi = _subfiles.upper_bound(&find_subfile);
@ -818,16 +821,18 @@ open_read_write(iostream *multifile_stream) {
// Description: Adds a file on disk as a subfile to the Multifile. // Description: Adds a file on disk as a subfile to the Multifile.
// The indicated istream will be read and its contents // The indicated istream will be read and its contents
// added to the Multifile at the next call to flush(). // added to the Multifile at the next call to flush().
//
// Returns the subfile name on success (it might have
// been modified slightly), or empty string on failure.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool Multifile:: string Multifile::
add_subfile(const string &subfile_name, istream *subfile_data) { add_subfile(const string &subfile_name, istream *subfile_data) {
nassertr(is_write_valid(), false); nassertr(is_write_valid(), string());
Subfile *subfile = new Subfile(subfile_name);
Subfile *subfile = new Subfile;
subfile->_source = subfile_data; subfile->_source = subfile_data;
return add_new_subfile(subfile); return add_new_subfile(subfile_name, subfile);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -930,14 +935,28 @@ pad_to_streampos(streampos fpos) {
// Description: Adds a newly-allocated Subfile pointer to the // Description: Adds a newly-allocated Subfile pointer to the
// Multifile. // Multifile.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool Multifile:: string Multifile::
add_new_subfile(Subfile *subfile) { add_new_subfile(const string &subfile_name, Subfile *subfile) {
if (_next_index != (streampos)0) { if (_next_index != (streampos)0) {
// If we're adding a Subfile to an already-existing Multifile, we // If we're adding a Subfile to an already-existing Multifile, we
// will eventually need to repack the file. // will eventually need to repack the file.
_needs_repack = true; _needs_repack = true;
} }
// Normalize the Subfile name: eliminate ./, leading slash, etc.
Filename name = subfile_name;
name.standardize();
if (name.empty() || name == "/") {
// Invalid empty name.
return name;
}
if (name[0] == '/') {
subfile->_name = name.get_fullpath().substr(1);
} else {
subfile->_name = name;
}
pair<Subfiles::iterator, bool> insert_result = _subfiles.insert(subfile); pair<Subfiles::iterator, bool> insert_result = _subfiles.insert(subfile);
if (!insert_result.second) { if (!insert_result.second) {
// Hmm, unable to insert. There must already be a subfile by that // Hmm, unable to insert. There must already be a subfile by that
@ -949,7 +968,7 @@ add_new_subfile(Subfile *subfile) {
} }
_new_subfiles.push_back(subfile); _new_subfiles.push_back(subfile);
return true; return subfile->_name;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -1031,7 +1050,7 @@ read_index() {
_last_index = 0; _last_index = 0;
streampos index_forward; streampos index_forward;
Subfile *subfile = new Subfile(""); Subfile *subfile = new Subfile;
index_forward = subfile->read_index(*_read, _next_index, this); index_forward = subfile->read_index(*_read, _next_index, this);
while (index_forward != (streampos)0) { while (index_forward != (streampos)0) {
_last_index = _next_index; _last_index = _next_index;
@ -1049,7 +1068,7 @@ read_index() {
} }
_read->seekg(index_forward); _read->seekg(index_forward);
_next_index = index_forward; _next_index = index_forward;
subfile = new Subfile(""); subfile = new Subfile;
index_forward = subfile->read_index(*_read, _next_index, this); index_forward = subfile->read_index(*_read, _next_index, this);
} }
if (subfile->is_index_invalid()) { if (subfile->is_index_invalid()) {

View File

@ -57,7 +57,7 @@ PUBLISHED:
void set_scale_factor(size_t scale_factor); void set_scale_factor(size_t scale_factor);
INLINE size_t get_scale_factor() const; INLINE size_t get_scale_factor() const;
bool add_subfile(const string &subfile_name, const Filename &filename); string add_subfile(const string &subfile_name, const Filename &filename);
bool flush(); bool flush();
bool repack(); bool repack();
@ -81,7 +81,7 @@ public:
bool open_read(istream *multifile_stream); bool open_read(istream *multifile_stream);
bool open_write(ostream *multifile_stream); bool open_write(ostream *multifile_stream);
bool open_read_write(iostream *multifile_stream); bool open_read_write(iostream *multifile_stream);
bool add_subfile(const string &subfile_name, istream *subfile_data); string add_subfile(const string &subfile_name, istream *subfile_data);
bool extract_subfile_to(int index, ostream &out); bool extract_subfile_to(int index, ostream &out);
istream *open_read_subfile(int index); istream *open_read_subfile(int index);
@ -95,7 +95,7 @@ private:
class Subfile { class Subfile {
public: public:
INLINE Subfile(const string &name); INLINE Subfile();
INLINE bool operator < (const Subfile &other) const; INLINE bool operator < (const Subfile &other) const;
streampos read_index(istream &read, streampos fpos, streampos read_index(istream &read, streampos fpos,
Multifile *multfile); Multifile *multfile);
@ -122,7 +122,7 @@ private:
INLINE streampos normalize_streampos(streampos fpos) const; INLINE streampos normalize_streampos(streampos fpos) const;
streampos pad_to_streampos(streampos fpos); streampos pad_to_streampos(streampos fpos);
bool add_new_subfile(Subfile *subfile); string add_new_subfile(const string &subfile_name, Subfile *subfile);
void clear_subfiles(); void clear_subfiles();
bool read_index(); bool read_index();
bool write_header(); bool write_header();

View File

@ -19,6 +19,7 @@
#include "texturePool.h" #include "texturePool.h"
#include "config_gobj.h" #include "config_gobj.h"
#include "config_util.h" #include "config_util.h"
#include "virtualFileSystem.h"
TexturePool *TexturePool::_global_ptr = (TexturePool *)NULL; TexturePool *TexturePool::_global_ptr = (TexturePool *)NULL;
@ -35,8 +36,15 @@ ns_has_texture(Filename filename) {
filename = fake_texture_image; filename = fake_texture_image;
} }
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(filename, get_texture_path());
vfs->resolve_filename(filename, get_model_path());
} else {
filename.resolve_filename(get_texture_path()); filename.resolve_filename(get_texture_path());
filename.resolve_filename(get_model_path()); filename.resolve_filename(get_model_path());
}
Textures::const_iterator ti; Textures::const_iterator ti;
ti = _textures.find(filename); ti = _textures.find(filename);
@ -59,8 +67,15 @@ ns_load_texture(Filename filename) {
filename = fake_texture_image; filename = fake_texture_image;
} }
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(filename, get_texture_path());
vfs->resolve_filename(filename, get_model_path());
} else {
filename.resolve_filename(get_texture_path()); filename.resolve_filename(get_texture_path());
filename.resolve_filename(get_model_path()); filename.resolve_filename(get_model_path());
}
Textures::const_iterator ti; Textures::const_iterator ti;
ti = _textures.find(filename); ti = _textures.find(filename);
@ -93,11 +108,21 @@ ns_load_texture(Filename filename, Filename grayfilename) {
return ns_load_texture(fake_texture_image); return ns_load_texture(fake_texture_image);
} }
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(filename, get_texture_path());
vfs->resolve_filename(filename, get_model_path());
vfs->resolve_filename(grayfilename, get_texture_path());
vfs->resolve_filename(grayfilename, get_model_path());
} else {
filename.resolve_filename(get_texture_path()); filename.resolve_filename(get_texture_path());
filename.resolve_filename(get_model_path()); filename.resolve_filename(get_model_path());
grayfilename.resolve_filename(get_texture_path()); grayfilename.resolve_filename(get_texture_path());
grayfilename.resolve_filename(get_model_path()); grayfilename.resolve_filename(get_model_path());
}
Textures::const_iterator ti; Textures::const_iterator ti;
ti = _textures.find(filename); ti = _textures.find(filename);

View File

@ -24,6 +24,7 @@
#include "bamReader.h" #include "bamReader.h"
#include "bamWriter.h" #include "bamWriter.h"
#include "filename.h" #include "filename.h"
#include "virtualFileSystem.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: BamFile::Constructor // Function: BamFile::Constructor
@ -58,12 +59,22 @@ open_read(const Filename &filename, bool report_errors) {
Filename bam_filename(filename); Filename bam_filename(filename);
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->exists(bam_filename)) {
if (report_errors) {
loader_cat.error() << "Could not find " << bam_filename << "\n";
}
return false;
}
} else {
if (!bam_filename.exists()) { if (!bam_filename.exists()) {
if (report_errors) { if (report_errors) {
loader_cat.error() << "Could not find " << bam_filename << "\n"; loader_cat.error() << "Could not find " << bam_filename << "\n";
} }
return false; return false;
} }
}
loader_cat.info() << "Reading " << bam_filename << "\n"; loader_cat.info() << "Reading " << bam_filename << "\n";

View File

@ -21,6 +21,8 @@
#include "loaderFileTypeRegistry.h" #include "loaderFileTypeRegistry.h"
#include "config_pgraph.h" #include "config_pgraph.h"
#include "config_util.h"
#include "virtualFileSystem.h"
#include "event.h" #include "event.h"
#include "pt_Event.h" #include "pt_Event.h"
#include "throw_event.h" #include "throw_event.h"
@ -370,6 +372,8 @@ load_unknown_file_type(const Filename &filename) const {
return (PandaNode *)NULL; return (PandaNode *)NULL;
} }
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
for (int i = 0; i < num_types; i++) { for (int i = 0; i < num_types; i++) {
LoaderConsiderFile consider; LoaderConsiderFile consider;
consider._type = reg->get_type(i); consider._type = reg->get_type(i);
@ -381,10 +385,16 @@ load_unknown_file_type(const Filename &filename) const {
consider._type->resolve_filename(consider._path); consider._type->resolve_filename(consider._path);
} }
if (use_vfs) {
if (vfs->exists(consider._path)) {
files.push_back(consider);
}
} else {
if (consider._path.exists()) { if (consider._path.exists()) {
files.push_back(consider); files.push_back(consider);
} }
} }
}
if (files.empty()) { if (files.empty()) {
loader_cat.error() loader_cat.error()
@ -456,6 +466,8 @@ resolve_unknown_file_type(Filename &filename) const {
return; return;
} }
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
for (int i = 0; i < num_types; i++) { for (int i = 0; i < num_types; i++) {
LoaderConsiderFile consider; LoaderConsiderFile consider;
consider._type = reg->get_type(i); consider._type = reg->get_type(i);
@ -467,10 +479,16 @@ resolve_unknown_file_type(Filename &filename) const {
consider._type->resolve_filename(consider._path); consider._type->resolve_filename(consider._path);
} }
if (use_vfs) {
if (vfs->exists(consider._path)) {
files.push_back(consider);
}
} else {
if (consider._path.exists()) { if (consider._path.exists()) {
files.push_back(consider); files.push_back(consider);
} }
} }
}
if (files.empty()) { if (files.empty()) {
// Couldn't find it anywhere. // Couldn't find it anywhere.

View File

@ -20,6 +20,7 @@
#include "config_pgraph.h" #include "config_pgraph.h"
#include "bamFile.h" #include "bamFile.h"
#include "virtualFileSystem.h"
#include "config_util.h" #include "config_util.h"
#include "dcast.h" #include "dcast.h"
@ -63,9 +64,15 @@ get_extension() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void LoaderFileTypeBam:: void LoaderFileTypeBam::
resolve_filename(Filename &path) const { resolve_filename(Filename &path) const {
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(path, get_bam_path());
vfs->resolve_filename(path, get_model_path());
} else {
path.resolve_filename(get_bam_path()); path.resolve_filename(get_bam_path());
path.resolve_filename(get_model_path()); path.resolve_filename(get_model_path());
} }
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: LoaderFileTypeBam::load_file // Function: LoaderFileTypeBam::load_file

View File

@ -20,6 +20,8 @@
cycleData.h cycleData.I \ cycleData.h cycleData.I \
cycleDataReader.h cycleDataReader.I \ cycleDataReader.h cycleDataReader.I \
cycleDataWriter.h cycleDataWriter.I \ cycleDataWriter.h cycleDataWriter.I \
datagramInputFile.I datagramInputFile.h \
datagramOutputFile.I datagramOutputFile.h \
drawMask.h \ drawMask.h \
factoryBase.I factoryBase.h \ factoryBase.I factoryBase.h \
factoryParam.I factoryParam.h factoryParams.I \ factoryParam.I factoryParam.h factoryParams.I \
@ -64,6 +66,7 @@
cycleData.cxx \ cycleData.cxx \
cycleDataReader.cxx \ cycleDataReader.cxx \
cycleDataWriter.cxx \ cycleDataWriter.cxx \
datagramInputFile.cxx datagramOutputFile.cxx \
factoryBase.cxx \ factoryBase.cxx \
factoryParam.cxx factoryParams.cxx globPattern.cxx \ factoryParam.cxx factoryParams.cxx globPattern.cxx \
globalPointerRegistry.cxx ioPtaDatagramFloat.cxx \ globalPointerRegistry.cxx ioPtaDatagramFloat.cxx \
@ -99,6 +102,8 @@
cycleData.h cycleData.I \ cycleData.h cycleData.I \
cycleDataReader.h cycleDataReader.I \ cycleDataReader.h cycleDataReader.I \
cycleDataWriter.h cycleDataWriter.I \ cycleDataWriter.h cycleDataWriter.I \
datagramInputFile.I datagramInputFile.h \
datagramOutputFile.I datagramOutputFile.h \
drawMask.h \ drawMask.h \
factoryBase.I factoryBase.h factoryParam.I factoryParam.h \ factoryBase.I factoryBase.h factoryParam.I factoryParam.h \
factoryParams.I factoryParams.h \ factoryParams.I factoryParams.h \

View File

@ -100,3 +100,9 @@ get_sound_path() {
static DSearchPath *sound_path = NULL; static DSearchPath *sound_path = NULL;
return get_config_path("sound-path", sound_path); return get_config_path("sound-path", sound_path);
} }
// Set this true to use the VirtualFileSystem mechanism for loading
// models, etc. Since the VirtualFileSystem maps to the same as the
// actual file system by default, there is probably no reason to set
// this false, except for testing or if you mistrust the new code.
const bool use_vfs = config_util.GetBool("use-vfs", false);

View File

@ -46,4 +46,6 @@ EXPCL_PANDA DSearchPath &get_texture_path();
EXPCL_PANDA DSearchPath &get_sound_path(); EXPCL_PANDA DSearchPath &get_sound_path();
END_PUBLISH END_PUBLISH
extern EXPCL_PANDA const bool use_vfs;
#endif /* __CONFIG_UTIL_H__ */ #endif /* __CONFIG_UTIL_H__ */

View File

@ -26,21 +26,8 @@ INLINE DatagramInputFile::
DatagramInputFile() { DatagramInputFile() {
_error = true; _error = true;
_read_first_datagram = false; _read_first_datagram = false;
} _in = (istream *)NULL;
_owns_in = false;
////////////////////////////////////////////////////////////////////
// Function: DatagramInputFile::open
// Access: Public
// Description: Opens the indicated filename for reading. Returns
// true if successful, false on failure.
////////////////////////////////////////////////////////////////////
INLINE bool DatagramInputFile::
open(Filename filename) {
// DatagramInputFiles are always binary.
_read_first_datagram = false;
_error = false;
filename.set_binary();
return filename.open_read(_in);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -51,5 +38,10 @@ open(Filename filename) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DatagramInputFile:: INLINE void DatagramInputFile::
close() { close() {
_in.close(); _in_file.close();
if (_owns_in) {
delete _in;
_in = (istream *)NULL;
_owns_in = false;
}
} }

View File

@ -20,6 +20,8 @@
#include "numeric_types.h" #include "numeric_types.h"
#include "datagramIterator.h" #include "datagramIterator.h"
#include "profileTimer.h" #include "profileTimer.h"
#include "config_util.h"
#include "virtualFileSystem.h"
#include "datagramInputFile.h" #include "datagramInputFile.h"
@ -28,6 +30,37 @@
EXPCL_PANDAEXPRESS ProfileTimer Skyler_timer_file; EXPCL_PANDAEXPRESS ProfileTimer Skyler_timer_file;
#endif //] #endif //]
////////////////////////////////////////////////////////////////////
// Function: DatagramInputFile::open
// Access: Public
// Description: Opens the indicated filename for reading. Returns
// true if successful, false on failure.
////////////////////////////////////////////////////////////////////
bool DatagramInputFile::
open(Filename filename) {
// DatagramInputFiles are always binary.
_read_first_datagram = false;
_error = false;
filename.set_binary();
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
PT(VirtualFile) file = vfs->get_file(filename);
if (file == (VirtualFile *)NULL) {
// No such file.
return false;
}
_in = file->open_read_file();
_owns_in = (_in != (istream *)NULL);
return _owns_in && !_in->fail();
} else {
_in = &_in_file;
_owns_in = false;
return filename.open_read(_in_file);
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DatagramInputFile::read_header // Function: DatagramInputFile::read_header
// Access: Public // Access: Public
@ -44,8 +77,8 @@ read_header(string &header, size_t num_bytes) {
char *buffer = (char *)alloca(num_bytes); char *buffer = (char *)alloca(num_bytes);
nassertr(buffer != (char *)NULL, false); nassertr(buffer != (char *)NULL, false);
_in.read(buffer, num_bytes); _in->read(buffer, num_bytes);
if (_in.fail() || _in.eof()) { if (_in->fail() || _in->eof()) {
return false; return false;
} }
@ -70,8 +103,8 @@ get_datagram(Datagram &data) {
// First, get the size of the upcoming datagram. We do this with // First, get the size of the upcoming datagram. We do this with
// the help of a second datagram. // the help of a second datagram.
char sizebuf[sizeof(PN_uint32)]; char sizebuf[sizeof(PN_uint32)];
_in.read(sizebuf, sizeof(PN_uint32)); _in->read(sizebuf, sizeof(PN_uint32));
if (_in.fail() || _in.eof()) { if (_in->fail() || _in->eof()) {
#ifdef SKYLER_TIMER //[ #ifdef SKYLER_TIMER //[
Skyler_timer_file.off("DatagramInputFile::get_datagram"); Skyler_timer_file.off("DatagramInputFile::get_datagram");
#endif //] #endif //]
@ -86,8 +119,8 @@ get_datagram(Datagram &data) {
char *buffer = new char[num_bytes]; char *buffer = new char[num_bytes];
nassertr(buffer != (char *)NULL, false); nassertr(buffer != (char *)NULL, false);
_in.read(buffer, num_bytes); _in->read(buffer, num_bytes);
if (_in.fail() || _in.eof()) { if (_in->fail() || _in->eof()) {
_error = true; _error = true;
delete[] buffer; delete[] buffer;
#ifdef SKYLER_TIMER //[ #ifdef SKYLER_TIMER //[
@ -113,7 +146,7 @@ get_datagram(Datagram &data) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DatagramInputFile:: bool DatagramInputFile::
is_eof() { is_eof() {
return _in.eof(); return _in->eof();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -124,7 +157,7 @@ is_eof() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DatagramInputFile:: bool DatagramInputFile::
is_error() { is_error() {
if (_in.fail()) { if (_in->fail()) {
_error = true; _error = true;
} }
return _error; return _error;

View File

@ -34,7 +34,7 @@ class EXPCL_PANDAEXPRESS DatagramInputFile : public DatagramGenerator {
public: public:
INLINE DatagramInputFile(); INLINE DatagramInputFile();
INLINE bool open(Filename filename); bool open(Filename filename);
bool read_header(string &header, size_t num_bytes); bool read_header(string &header, size_t num_bytes);
virtual bool get_datagram(Datagram &data); virtual bool get_datagram(Datagram &data);
@ -46,7 +46,9 @@ public:
private: private:
bool _read_first_datagram; bool _read_first_datagram;
bool _error; bool _error;
ifstream _in; ifstream _in_file;
istream *_in;
bool _owns_in;
}; };
#include "datagramInputFile.I" #include "datagramInputFile.I"

View File

@ -11,6 +11,8 @@
#include "cycleData.cxx" #include "cycleData.cxx"
#include "cycleDataReader.cxx" #include "cycleDataReader.cxx"
#include "cycleDataWriter.cxx" #include "cycleDataWriter.cxx"
#include "datagramInputFile.cxx"
#include "datagramOutputFile.cxx"
#include "factoryBase.cxx" #include "factoryBase.cxx"
#include "factoryParam.cxx" #include "factoryParam.cxx"
#include "factoryParams.cxx" #include "factoryParams.cxx"

View File

@ -165,7 +165,7 @@ ls(ostream &out) const {
CPT(VirtualFileList) contents = scan_directory(); CPT(VirtualFileList) contents = scan_directory();
if (contents == NULL) { if (contents == NULL) {
if (!is_directory()) { if (!is_directory()) {
out << get_filename() << " is not a directory.\n"; out << get_filename() << "\n";
} else { } else {
out << get_filename() << " cannot be read.\n"; out << get_filename() << " cannot be read.\n";
} }

View File

@ -68,6 +68,7 @@ is_regular_file(const Filename &file) const {
istream *VirtualFileMountSystem:: istream *VirtualFileMountSystem::
open_read_file(const Filename &file) const { open_read_file(const Filename &file) const {
Filename pathname(_physical_filename, file); Filename pathname(_physical_filename, file);
pathname.set_binary();
ifstream *stream = new ifstream; ifstream *stream = new ifstream;
if (!pathname.open_read(*stream)) { if (!pathname.open_read(*stream)) {
// Couldn't open the file for some reason. // Couldn't open the file for some reason.

View File

@ -15,3 +15,112 @@
// panda3d@yahoogroups.com . // panda3d@yahoogroups.com .
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::exists
// Access: Published
// Description: Convenience function; returns true if the named file
// exists.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
exists(const Filename &filename) const {
return get_file(filename) != (VirtualFile *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::is_directory
// Access: Published
// Description: Convenience function; returns true if the named file
// exists and is a directory.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
is_directory(const Filename &filename) const {
PT(VirtualFile) file = get_file(filename);
return (file != (VirtualFile *)NULL && file->is_directory());
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::is_regular_file
// Access: Published
// Description: Convenience function; returns true if the named file
// exists and is a regular file.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
is_regular_file(const Filename &filename) const {
PT(VirtualFile) file = get_file(filename);
return (file != (VirtualFile *)NULL && file->is_regular_file());
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::read_file
// Access: Published
// Description: Convenience function; fills the datagram up with the
// data from the indicated file, if it exists and can be
// read. Returns true on success, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
read_file(const Filename &filename, Datagram &data) const {
PT(VirtualFile) file = get_file(filename);
return (file != (VirtualFile *)NULL && file->read_file(data));
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::open_read_file
// Access: Published
// Description: Convenience function; returns a newly allocated
// istream if the file exists and can be read, or NULL
// otherwise. Does not return an invalid istream.
////////////////////////////////////////////////////////////////////
INLINE istream *VirtualFileSystem::
open_read_file(const Filename &filename) const {
PT(VirtualFile) file = get_file(filename);
if (file == (VirtualFile *)NULL) {
return NULL;
}
istream *str = file->open_read_file();
if (str != (istream *)NULL && str->fail()) {
delete str;
str = (istream *)NULL;
}
return str;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::ls
// Access: Published
// Description: Convenience function; lists the files within the
// indicated directory. This accepts a string instead
// of a Filename purely for programmer convenience at
// the Python prompt.
////////////////////////////////////////////////////////////////////
INLINE void VirtualFileSystem::
ls(const string &filename) const {
PT(VirtualFile) file = get_file(filename);
if (file == (VirtualFile *)NULL) {
util_cat.info()
<< "Not found: " << filename << "\n";
} else {
file->ls();
}
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::ls_all
// Access: Published
// Description: Convenience function; lists the files within the
// indicated directory, and all files below,
// recursively. This accepts a string instead of a
// Filename purely for programmer convenience at the
// Python prompt.
////////////////////////////////////////////////////////////////////
INLINE void VirtualFileSystem::
ls_all(const string &filename) const {
PT(VirtualFile) file = get_file(filename);
if (file == (VirtualFile *)NULL) {
util_cat.info()
<< "Not found: " << filename << "\n";
} else {
file->ls_all();
}
}

View File

@ -22,6 +22,8 @@
#include "virtualFileMountSystem.h" #include "virtualFileMountSystem.h"
#include "dSearchPath.h" #include "dSearchPath.h"
#include "dcast.h" #include "dcast.h"
#include "config_util.h"
#include "executionEnvironment.h"
VirtualFileSystem *VirtualFileSystem::_global_ptr = NULL; VirtualFileSystem *VirtualFileSystem::_global_ptr = NULL;
@ -239,9 +241,12 @@ unmount_all() {
// resolve relative pathnames in get_file() and/or // resolve relative pathnames in get_file() and/or
// find_file(). Returns true if successful, false // find_file(). Returns true if successful, false
// otherwise. // otherwise.
//
// This accepts a string rather than a Filename simply
// for programmer convenience from the Python prompt.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool VirtualFileSystem:: bool VirtualFileSystem::
chdir(const Filename &new_directory) { chdir(const string &new_directory) {
if (new_directory == "/") { if (new_directory == "/") {
// We can always return to the root. // We can always return to the root.
_cwd = new_directory; _cwd = new_directory;
@ -274,11 +279,11 @@ get_cwd() const {
// the file if it is found, or NULL if it is not. // the file if it is found, or NULL if it is not.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
PT(VirtualFile) VirtualFileSystem:: PT(VirtualFile) VirtualFileSystem::
get_file(const Filename &file) const { get_file(const Filename &filename) const {
nassertr(!file.empty(), NULL); nassertr(!filename.empty(), NULL);
Filename pathname(file); Filename pathname(filename);
if (pathname.is_local()) { if (pathname.is_local()) {
pathname = Filename(_cwd, file); pathname = Filename(_cwd, filename);
} }
pathname.standardize(); pathname.standardize();
string strpath = pathname.get_fullpath().substr(1); string strpath = pathname.get_fullpath().substr(1);
@ -333,14 +338,14 @@ get_file(const Filename &file) const {
// found. // found.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
PT(VirtualFile) VirtualFileSystem:: PT(VirtualFile) VirtualFileSystem::
find_file(const Filename &file, const DSearchPath &searchpath) const { find_file(const Filename &filename, const DSearchPath &searchpath) const {
if (file.is_local()) { if (!filename.is_local()) {
return get_file(file); return get_file(filename);
} }
int num_directories = searchpath.get_num_directories(); int num_directories = searchpath.get_num_directories();
for (int i = 0; i < num_directories; i++) { for (int i = 0; i < num_directories; i++) {
Filename match(searchpath.get_directory(i), file); Filename match(searchpath.get_directory(i), filename);
PT(VirtualFile) found_file = get_file(match); PT(VirtualFile) found_file = get_file(match);
if (found_file != (VirtualFile *)NULL) { if (found_file != (VirtualFile *)NULL) {
return found_file; return found_file;
@ -350,6 +355,58 @@ find_file(const Filename &file, const DSearchPath &searchpath) const {
return NULL; return NULL;
} }
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::resolve_filename
// Access: Public
// Description: Searches the given search path for the filename. If
// it is found, updates the filename to the full
// pathname found and returns true; otherwise, returns
// false.
////////////////////////////////////////////////////////////////////
bool VirtualFileSystem::
resolve_filename(Filename &filename,
const DSearchPath &searchpath,
const string &default_extension) const {
PT(VirtualFile) found;
if (filename.is_local()) {
found = find_file(filename.get_fullpath(), searchpath);
if (found.is_null()) {
// We didn't find it with the given extension; can we try the
// default extension?
if (filename.get_extension().empty() && !default_extension.empty()) {
Filename try_ext = filename;
try_ext.set_extension(default_extension);
found = find_file(try_ext.get_fullpath(), searchpath);
}
}
} else {
if (exists(filename)) {
// The full pathname exists. Return true.
return true;
} else {
// The full pathname doesn't exist with the given extension;
// does it exist with the default extension?
if (filename.get_extension().empty() && !default_extension.empty()) {
Filename try_ext = filename;
try_ext.set_extension(default_extension);
found = get_file(try_ext);
}
}
}
if (!found.is_null()) {
filename = found->get_filename();
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::write // Function: VirtualFileSystem::write
// Access: Published // Access: Published
@ -383,7 +440,34 @@ VirtualFileSystem *VirtualFileSystem::
get_global_ptr() { get_global_ptr() {
if (_global_ptr == (VirtualFileSystem *)NULL) { if (_global_ptr == (VirtualFileSystem *)NULL) {
_global_ptr = new VirtualFileSystem; _global_ptr = new VirtualFileSystem;
// Set up the default mounts. First, there is always the root
// mount.
_global_ptr->mount("/", "/", 0); _global_ptr->mount("/", "/", 0);
// Then, we add whatever mounts are listed in the Configrc file.
Config::ConfigTable::Symbol mounts;
config_util.GetAll("vfs-mount", mounts);
Config::ConfigTable::Symbol::iterator si;
for (si = mounts.begin(); si != mounts.end(); ++si) {
string mount_desc = (*si).Val();
// The last space marks the beginning of the mount point.
// Spaces before that are part of the system filename.
size_t space = mount_desc.rfind(' ');
if (space == string::npos) {
util_cat.warning()
<< "No space in vfs-mount descriptor: " << mount_desc << "\n";
} else {
string fn = trim_right(mount_desc.substr(0, space));
fn = ExecutionEnvironment::expand_string(fn);
Filename physical_filename = Filename::from_os_specific(fn);
string mount_point = mount_desc.substr(space + 1);
_global_ptr->mount(physical_filename, mount_point, 0);
}
}
} }
return _global_ptr; return _global_ptr;

View File

@ -21,11 +21,15 @@
#include "pandabase.h" #include "pandabase.h"
#include "virtualFile.h"
#include "filename.h" #include "filename.h"
#include "pointerTo.h"
#include "pmap.h" #include "pmap.h"
#include "config_util.h"
class Multifile; class Multifile;
class VirtualFileMount; class VirtualFileMount;
class VirtualFileComposite;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : VirtualFileSystem // Class : VirtualFileSystem
@ -55,12 +59,25 @@ PUBLISHED:
int unmount_point(const string &mount_point); int unmount_point(const string &mount_point);
int unmount_all(); int unmount_all();
bool chdir(const Filename &new_directory); bool chdir(const string &new_directory);
const Filename &get_cwd() const; const Filename &get_cwd() const;
PT(VirtualFile) get_file(const Filename &file) const; PT(VirtualFile) get_file(const Filename &filename) const;
PT(VirtualFile) find_file(const Filename &file, PT(VirtualFile) find_file(const Filename &filename,
const DSearchPath &searchpath) const; const DSearchPath &searchpath) const;
bool resolve_filename(Filename &filename,
const DSearchPath &searchpath,
const string &default_extension = string()) const;
INLINE bool exists(const Filename &filename) const;
INLINE bool is_directory(const Filename &filename) const;
INLINE bool is_regular_file(const Filename &filename) const;
INLINE bool read_file(const Filename &filename, Datagram &data) const;
INLINE istream *open_read_file(const Filename &filename) const;
INLINE void ls(const string &filename) const;
INLINE void ls_all(const string &filename) const;
void write(ostream &out) const; void write(ostream &out) const;