integrate HashFilename with Filename via Filename::set_pattern()

This commit is contained in:
David Rose 2005-09-23 17:23:30 +00:00
parent c0bc0d4d32
commit 60d2c8e349
22 changed files with 319 additions and 475 deletions

View File

@ -23,8 +23,8 @@
////////////////////////////////////////////////////////////////////
INLINE Filename::
Filename(const string &filename) {
(*this) = filename;
_flags = 0;
(*this) = filename;
}
////////////////////////////////////////////////////////////////////
@ -34,8 +34,8 @@ Filename(const string &filename) {
////////////////////////////////////////////////////////////////////
INLINE Filename::
Filename(const char *filename) {
(*this) = filename;
_flags = 0;
(*this) = filename;
}
@ -45,13 +45,15 @@ Filename(const char *filename) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE Filename::
Filename(const Filename &copy)
: _filename(copy._filename),
_dirname_end(copy._dirname_end),
_basename_start(copy._basename_start),
_basename_end(copy._basename_end),
_extension_start(copy._extension_start),
_flags(copy._flags)
Filename(const Filename &copy) :
_filename(copy._filename),
_dirname_end(copy._dirname_end),
_basename_start(copy._basename_start),
_basename_end(copy._basename_end),
_extension_start(copy._extension_start),
_hash_start(copy._hash_start),
_hash_end(copy._hash_end),
_flags(copy._flags)
{
}
@ -103,6 +105,19 @@ executable_filename(const string &filename) {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: Filename::pattern_filename named constructor
// Access: Published
// Description: Constructs a filename that represents a sequence of
// numbered files. See set_pattern().
////////////////////////////////////////////////////////////////////
INLINE Filename Filename::
pattern_filename(const string &filename) {
Filename result(filename);
result.set_pattern(true);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: Filename::Destructor
// Access: Published
@ -124,6 +139,7 @@ operator = (const string &filename) {
locate_basename();
locate_extension();
locate_hash();
return *this;
}
@ -150,6 +166,8 @@ operator = (const Filename &copy) {
_basename_start = copy._basename_start;
_basename_end = copy._basename_end;
_extension_start = copy._extension_start;
_hash_start = copy._hash_start;
_hash_end = copy._hash_end;
_flags = copy._flags;
return *this;
}
@ -388,6 +406,75 @@ get_type() const {
return (Type)(_flags & (int)F_type);
}
////////////////////////////////////////////////////////////////////
// Function: Filename::set_pattern
// Access: Published
// Description: Sets the flag indicating whether this is a filename
// pattern. When this is true, the filename is
// understood to be a placeholder for a numbered
// sequence of filename, such as an image sequence. In
// this case, a sequence of one or more hash characters
// ("#") should appear in the filename string; these
// characters will be filled in with the corresponding
// number (or more) of digits representing the sequence
// number. Sequence numbers always begin counting at 0.
//
// When this is true, methods like has_hash() and
// get_hash_to_end() and get_filename_index() may be
// called. Methods like is_exists() will implicitly
// test for existance of filename sequence 0.
////////////////////////////////////////////////////////////////////
INLINE void Filename::
set_pattern(bool pattern) {
if (pattern != get_pattern()) {
if (pattern) {
_flags |= F_pattern;
} else {
_flags &= ~F_pattern;
}
locate_hash();
}
}
////////////////////////////////////////////////////////////////////
// Function: Filename::get_pattern
// Access: Published
// Description: Returns the flag indicating whether this is a
// filename pattern. See set_pattern().
////////////////////////////////////////////////////////////////////
INLINE bool Filename::
get_pattern() const {
return (_flags & F_pattern) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: Filename::has_hash
// Access: Published
// Description: Returns true if the filename is indicated to be a
// filename pattern (that is, set_pattern(true) was
// called), and the filename pattern did include a
// sequence of hash marks, or false if it was not a
// filename pattern or did not include hash marks. If
// this is true, then get_filename_index() will return a
// different filename each time.
////////////////////////////////////////////////////////////////////
INLINE bool Filename::
has_hash() const {
return (_hash_start != _hash_end);
}
////////////////////////////////////////////////////////////////////
// Function: Filename::get_hash_to_end
// Access: Published
// Description: Returns the part of the filename beginning at the
// hash sequence (if any), and continuing to the end of
// the filename.
////////////////////////////////////////////////////////////////////
INLINE string Filename::
get_hash_to_end() const {
return _filename.substr(_hash_start);
}
////////////////////////////////////////////////////////////////////
// Function: Filename::is_local
// Access: Published

View File

@ -284,6 +284,7 @@ Filename(const Filename &dirname, const Filename &basename) {
if (dirname.empty()) {
(*this) = basename;
} else {
_flags = basename._flags;
string dirpath = dirname.get_fullpath();
if (dirpath[dirpath.length() - 1] == '/') {
(*this) = dirpath + basename.get_fullpath();
@ -291,7 +292,6 @@ Filename(const Filename &dirname, const Filename &basename) {
(*this) = dirpath + "/" + basename.get_fullpath();
}
}
_flags = 0;
}
////////////////////////////////////////////////////////////////////
@ -494,6 +494,7 @@ set_dirname(const string &s) {
_extension_start += length_change;
}
}
locate_hash();
}
////////////////////////////////////////////////////////////////////
@ -507,6 +508,7 @@ void Filename::
set_basename(const string &s) {
_filename.replace(_basename_start, string::npos, s);
locate_extension();
locate_hash();
}
@ -526,6 +528,7 @@ set_fullpath_wo_extension(const string &s) {
_basename_end += length_change;
_extension_start += length_change;
}
locate_hash();
}
@ -548,6 +551,7 @@ set_basename_wo_extension(const string &s) {
_basename_end += length_change;
_extension_start += length_change;
}
locate_hash();
}
@ -578,6 +582,51 @@ set_extension(const string &s) {
// Replace an existing extension.
_filename.replace(_extension_start, string::npos, s);
}
locate_hash();
}
////////////////////////////////////////////////////////////////////
// Function: Filename::get_filename_index
// Access: Published
// Description: If the pattern flag is set for this Filename and the
// filename string actually includes a sequence of hash
// marks, then this returns a new Filename with the
// sequence of hash marks replaced by the indicated
// index number.
//
// If the pattern flag is not set for this Filename or
// it does not contain a sequence of hash marks, this
// quietly returns the original filename.
////////////////////////////////////////////////////////////////////
Filename Filename::
get_filename_index(int index) const {
Filename file(*this);
if (_hash_end != _hash_start) {
ostringstream strm;
strm << _filename.substr(0, _hash_start)
<< setw(_hash_end - _hash_start) << setfill('0') << index
<< _filename.substr(_hash_end);
file.set_fullpath(strm.str());
}
file.set_pattern(false);
return file;
}
////////////////////////////////////////////////////////////////////
// Function: Filename::set_hash_to_end
// Access: Published
// Description: Replaces the part of the filename from the beginning
// of the hash sequence to the end of the filename.
////////////////////////////////////////////////////////////////////
void Filename::
set_hash_to_end(const string &s) {
_filename.replace(_hash_start, string::npos, s);
locate_basename();
locate_extension();
locate_hash();
}
////////////////////////////////////////////////////////////////////
@ -705,7 +754,9 @@ make_absolute() {
void Filename::
make_absolute(const Filename &start_directory) {
if (is_local()) {
(*this) = Filename(start_directory, _filename);
Filename new_filename(start_directory, _filename);
new_filename._flags = _flags;
(*this) = new_filename;
}
standardize();
@ -748,7 +799,6 @@ make_canonical() {
return true;
}
// Temporarily save the current working directory.
Filename cwd = ExecutionEnvironment::get_cwd();
return r_make_canonical(cwd);
}
@ -772,6 +822,8 @@ make_canonical() {
////////////////////////////////////////////////////////////////////
bool Filename::
make_true_case() {
assert(!get_pattern());
if (empty()) {
return true;
}
@ -828,6 +880,8 @@ make_true_case() {
////////////////////////////////////////////////////////////////////
string Filename::
to_os_specific() const {
assert(!get_pattern());
if (empty()) {
return string();
}
@ -865,6 +919,8 @@ to_os_specific() const {
////////////////////////////////////////////////////////////////////
string Filename::
to_os_generic() const {
assert(!get_pattern());
#ifdef WIN32
return back_to_front_slash(to_os_specific());
#else // WIN32
@ -882,7 +938,7 @@ to_os_generic() const {
////////////////////////////////////////////////////////////////////
bool Filename::
exists() const {
string os_specific = to_os_specific();
string os_specific = get_filename_index(0).to_os_specific();
#ifdef WIN32_VC
bool exists = false;
@ -913,7 +969,7 @@ exists() const {
////////////////////////////////////////////////////////////////////
bool Filename::
is_regular_file() const {
string os_specific = to_os_specific();
string os_specific = get_filename_index(0).to_os_specific();
#ifdef WIN32_VC
bool isreg = false;
@ -943,7 +999,7 @@ is_regular_file() const {
////////////////////////////////////////////////////////////////////
bool Filename::
is_directory() const {
string os_specific = to_os_specific();
string os_specific = get_filename_index(0).to_os_specific();
#ifdef WIN32_VC
bool isdir = false;
@ -981,7 +1037,7 @@ is_executable() const {
}
#else /* WIN32_VC */
string os_specific = to_os_specific();
string os_specific = get_filename_index(0).to_os_specific();
if (access(os_specific.c_str(), X_OK) == 0) {
return true;
}
@ -1008,8 +1064,8 @@ int Filename::
compare_timestamps(const Filename &other,
bool this_missing_is_old,
bool other_missing_is_old) const {
string os_specific = to_os_specific();
string other_os_specific = other.to_os_specific();
string os_specific = get_filename_index(0).to_os_specific();
string other_os_specific = other.get_filename_index(0).to_os_specific();
#ifdef WIN32_VC
struct _stat this_buf;
@ -1085,7 +1141,7 @@ resolve_filename(const DSearchPath &searchpath,
string found;
if (is_local()) {
found = searchpath.find_file(get_fullpath());
found = searchpath.find_file(*this);
if (found.empty()) {
// We didn't find it with the given extension; can we try the
@ -1093,7 +1149,7 @@ resolve_filename(const DSearchPath &searchpath,
if (get_extension().empty() && !default_extension.empty()) {
Filename try_ext = *this;
try_ext.set_extension(default_extension);
found = searchpath.find_file(try_ext.get_fullpath());
found = searchpath.find_file(try_ext);
}
}
} else {
@ -1234,6 +1290,8 @@ find_on_searchpath(const DSearchPath &searchpath) {
////////////////////////////////////////////////////////////////////
bool Filename::
scan_directory(vector_string &contents) const {
assert(!get_pattern());
#if defined(WIN32_VC)
// Use Windows' FindFirstFile() / FindNextFile() to walk through the
// list of files in a directory.
@ -1374,6 +1432,7 @@ scan_directory(vector_string &contents) const {
////////////////////////////////////////////////////////////////////
bool Filename::
open_read(ifstream &stream) const {
assert(!get_pattern());
assert(is_text() || is_binary());
ios_openmode open_mode = ios::in;
@ -1409,6 +1468,7 @@ open_read(ifstream &stream) const {
////////////////////////////////////////////////////////////////////
bool Filename::
open_write(ofstream &stream, bool truncate) const {
assert(!get_pattern());
assert(is_text() || is_binary());
ios_openmode open_mode = ios::out;
@ -1459,6 +1519,7 @@ open_write(ofstream &stream, bool truncate) const {
////////////////////////////////////////////////////////////////////
bool Filename::
open_append(ofstream &stream) const {
assert(!get_pattern());
assert(is_text() || is_binary());
ios_openmode open_mode = ios::app;
@ -1495,6 +1556,7 @@ open_append(ofstream &stream) const {
////////////////////////////////////////////////////////////////////
bool Filename::
open_read_write(fstream &stream) const {
assert(!get_pattern());
assert(is_text() || is_binary());
ios_openmode open_mode = ios::out | ios::in;
@ -1534,6 +1596,7 @@ open_read_write(fstream &stream) const {
////////////////////////////////////////////////////////////////////
bool Filename::
touch() const {
assert(!get_pattern());
#ifdef WIN32_VC
// In Windows, we have to use the Windows API to do this reliably.
@ -1616,6 +1679,7 @@ touch() const {
////////////////////////////////////////////////////////////////////
bool Filename::
unlink() const {
assert(!get_pattern());
string os_specific = to_os_specific();
return (::unlink(os_specific.c_str()) == 0);
}
@ -1631,6 +1695,7 @@ unlink() const {
////////////////////////////////////////////////////////////////////
bool Filename::
rename_to(const Filename &other) const {
assert(!get_pattern());
string os_specific = to_os_specific();
string other_os_specific = other.to_os_specific();
return (rename(os_specific.c_str(),
@ -1652,6 +1717,7 @@ rename_to(const Filename &other) const {
////////////////////////////////////////////////////////////////////
bool Filename::
make_dir() const {
assert(!get_pattern());
if (empty()) {
return false;
}
@ -1787,6 +1853,39 @@ locate_extension() {
// there is no dot.
}
////////////////////////////////////////////////////////////////////
// Function: Filename::locate_hash
// Access: Protected
// Description: Identifies the part of the filename that contains the
// sequence of hash marks, if any.
////////////////////////////////////////////////////////////////////
void Filename::
locate_hash() {
if (!get_pattern()) {
// If it's not a pattern-type filename, these are always set to
// the end of the string.
_hash_end = string::npos;
_hash_start = string::npos;
} else {
// If it is a pattern-type filename, we must search for the hash
// marks, which could be anywhere (but are usually toward the
// end).
_hash_end = _filename.rfind('#');
if (_hash_end == string::npos) {
_hash_end = string::npos;
_hash_start = string::npos;
} else {
_hash_start = _hash_end;
++_hash_end;
while (_hash_start > 0 && _filename[_hash_start - 1] == '#') {
--_hash_start;
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: Filename::get_common_prefix

View File

@ -58,6 +58,7 @@ public:
F_type = 0x0f,
F_binary = 0x10,
F_text = 0x20,
F_pattern = 0x40,
};
PUBLISHED:
@ -75,6 +76,8 @@ PUBLISHED:
INLINE static Filename dso_filename(const string &filename);
INLINE static Filename executable_filename(const string &filename);
INLINE static Filename pattern_filename(const string &filename);
static Filename from_os_specific(const string &os_specific,
Type type = T_general);
static Filename expand_from(const string &user_string,
@ -124,6 +127,15 @@ PUBLISHED:
INLINE void set_type(Type type);
INLINE Type get_type() const;
INLINE void set_pattern(bool pattern);
INLINE bool get_pattern() const;
INLINE bool has_hash() const;
Filename get_filename_index(int index) const;
INLINE string get_hash_to_end() const;
void set_hash_to_end(const string &s);
void extract_components(vector_string &components) const;
void standardize();
@ -176,6 +188,7 @@ PUBLISHED:
protected:
void locate_basename();
void locate_extension();
void locate_hash();
size_t get_common_prefix(const string &other) const;
static int count_slashes(const string &str);
bool r_make_canonical(const Filename &cwd);
@ -187,6 +200,8 @@ protected:
size_t _basename_start;
size_t _basename_end;
size_t _extension_start;
size_t _hash_start;
size_t _hash_end;
int _flags;
};

View File

@ -54,7 +54,7 @@ public:
}
};
private:
protected:
Filename _filename;
Filename _fullpath;

View File

@ -33,7 +33,6 @@
#include "pt_EggMaterial.h"
#include "config_egg.h"
#include "hashFilename.h"
#include "dSearchPath.h"
#include "deg_2_rad.h"
#include "dcast.h"
@ -429,27 +428,14 @@ resolve_filenames(const DSearchPath &searchpath) {
EggNode *child = *ci;
if (child->is_of_type(EggTexture::get_class_type())) {
EggTexture *tex = DCAST(EggTexture, child);
if (tex->has_hash_filename()) {
HashFilename tex_filename = tex->get_filename();
tex_filename.resolve_filename(searchpath);
tex->set_filename(tex_filename);
if (tex->has_alpha_filename()) {
HashFilename alpha_filename = tex->get_alpha_filename();
alpha_filename.resolve_filename(searchpath);
tex->set_alpha_filename(alpha_filename);
}
} else {
Filename tex_filename = tex->get_filename();
tex_filename.resolve_filename(searchpath);
tex->set_filename(tex_filename);
if (tex->has_alpha_filename()) {
Filename alpha_filename = tex->get_alpha_filename();
alpha_filename.resolve_filename(searchpath);
tex->set_alpha_filename(alpha_filename);
}
Filename tex_filename = tex->get_filename();
tex_filename.resolve_filename(searchpath);
tex->set_filename(tex_filename);
if (tex->has_alpha_filename()) {
Filename alpha_filename = tex->get_alpha_filename();
alpha_filename.resolve_filename(searchpath);
tex->set_alpha_filename(alpha_filename);
}
} else if (child->is_of_type(EggFilenameNode::get_class_type())) {

View File

@ -17,21 +17,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggTexture::has_hash_filename
// Access: Published
// Description: Returns true if the texture filename is expected to
// contain a hash mark standing in for a sequence
// number, or false if the filename is a literal
// filename. This will be true only if TextureType is
// TT_3d_texture or TT_cube_map.
////////////////////////////////////////////////////////////////////
INLINE bool EggTexture::
has_hash_filename() const {
return (_texture_type == TT_3d_texture ||
_texture_type == TT_cube_map);
}
////////////////////////////////////////////////////////////////////
// Function: EggTexture::set_texture_type
// Access: Published
@ -40,6 +25,12 @@ has_hash_filename() const {
INLINE void EggTexture::
set_texture_type(TextureType texture_type) {
_texture_type = texture_type;
bool pattern_filename =
(_texture_type == TT_3d_texture || _texture_type == TT_cube_map);
_filename.set_pattern(pattern_filename);
_fullpath.set_pattern(pattern_filename);
}
////////////////////////////////////////////////////////////////////

View File

@ -150,8 +150,6 @@ PUBLISHED:
TG_point_sprite,
};
INLINE bool has_hash_filename() const;
INLINE void set_texture_type(TextureType texture_type);
INLINE TextureType get_texture_type() const;

View File

@ -869,11 +869,11 @@ load_texture(TextureDef &def, const EggTexture *egg_tex) {
break;
case EggTexture::TT_3d_texture:
tex = TexturePool::load_3d_texture(HashFilename(egg_tex->get_fullpath()));
tex = TexturePool::load_3d_texture(egg_tex->get_fullpath());
break;
case EggTexture::TT_cube_map:
tex = TexturePool::load_cube_map(HashFilename(egg_tex->get_fullpath()));
tex = TexturePool::load_cube_map(egg_tex->get_fullpath());
break;
}

View File

@ -26,6 +26,18 @@ INLINE VirtualFile::
VirtualFile() {
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFile::get_original_filename
// Access: Published
// Description: Returns the original filename as it was used to
// locate this VirtualFile. This is usually, but not
// always, the same string returned by get_filename().
////////////////////////////////////////////////////////////////////
INLINE const Filename &VirtualFile::
get_original_filename() const {
return _original_filename;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFile::read_file
// Access: Public
@ -38,6 +50,19 @@ read_file() const {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFile::set_original_filename
// Access: Public
// Description: Stores the original filename that was used to locate
// this VirtualFile. This is normally called only by
// the VirtualFileSystem, as it creates each
// VirtualFile.
////////////////////////////////////////////////////////////////////
INLINE void VirtualFile::
set_original_filename(const Filename &filename) {
_original_filename = filename;
}
INLINE ostream &
operator << (ostream &out, const VirtualFile &file) {

View File

@ -43,6 +43,7 @@ public:
PUBLISHED:
virtual VirtualFileSystem *get_file_system() const=0;
virtual Filename get_filename() const=0;
INLINE const Filename &get_original_filename() const;
virtual bool is_directory() const;
virtual bool is_regular_file() const;
@ -59,6 +60,7 @@ PUBLISHED:
virtual streampos get_file_size(istream *stream) const;
public:
INLINE void set_original_filename(const Filename &filename);
bool read_file(string &result) const;
static bool read_file(istream *stream, string &result);
static bool read_file(istream *stream, string &result, size_t max_bytes);
@ -71,6 +73,8 @@ protected:
private:
void r_ls_all(ostream &out, const Filename &root) const;
Filename _original_filename;
public:
virtual TypeHandle get_type() const {

View File

@ -290,7 +290,7 @@ get_file(const Filename &filename) const {
pathname = Filename(_cwd, filename);
}
pathname.standardize();
string strpath = pathname.get_fullpath().substr(1);
string strpath = pathname.get_filename_index(0).get_fullpath().substr(1);
// Now scan all the mount points, from the back (since later mounts
// override more recent ones), until a match is found.
@ -304,14 +304,14 @@ get_file(const Filename &filename) const {
if (strpath == mount_point) {
// Here's an exact match on the mount point. This filename is
// the root directory of this mount object.
if (found_match(found_file, composite_file, mount, "")) {
if (found_match(found_file, composite_file, mount, "", pathname)) {
return found_file;
}
} else if (mount_point.empty()) {
// This is the root mount point; all files are in here.
if (mount->has_file(strpath)) {
// Bingo!
if (found_match(found_file, composite_file, mount, strpath)) {
if (found_match(found_file, composite_file, mount, strpath, pathname)) {
return found_file;
}
}
@ -322,7 +322,7 @@ get_file(const Filename &filename) const {
Filename local_filename = strpath.substr(mount_point.length() + 1);
if (mount->has_file(local_filename)) {
// Bingo!
if (found_match(found_file, composite_file, mount, local_filename)) {
if (found_match(found_file, composite_file, mount, local_filename, pathname)) {
return found_file;
}
}
@ -381,7 +381,7 @@ resolve_filename(Filename &filename,
PT(VirtualFile) found;
if (filename.is_local()) {
found = find_file(filename.get_fullpath(), searchpath);
found = find_file(filename, searchpath);
if (found.is_null()) {
// We didn't find it with the given extension; can we try the
@ -389,7 +389,7 @@ resolve_filename(Filename &filename,
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);
found = find_file(try_ext, searchpath);
}
}
} else {
@ -408,7 +408,7 @@ resolve_filename(Filename &filename,
}
if (!found.is_null()) {
filename = found->get_filename();
filename = found->get_original_filename();
return true;
}
@ -670,10 +670,12 @@ normalize_mount_point(const string &mount_point) const {
////////////////////////////////////////////////////////////////////
bool VirtualFileSystem::
found_match(PT(VirtualFile) &found_file, VirtualFileComposite *&composite_file,
VirtualFileMount *mount, const string &local_filename) const {
VirtualFileMount *mount, const string &local_filename,
const Filename &original_filename) const {
if (found_file == (VirtualFile *)NULL) {
// This was our first match. Save it.
found_file = new VirtualFileSimple(mount, local_filename);
found_file->set_original_filename(original_filename);
if (!mount->is_directory(local_filename)) {
// If it's not a directory, we're done.
return true;
@ -690,7 +692,8 @@ found_match(PT(VirtualFile) &found_file, VirtualFileComposite *&composite_file,
// need a composite directory.
if (composite_file == (VirtualFileComposite *)NULL) {
composite_file =
new VirtualFileComposite((VirtualFileSystem *)this, found_file->get_filename());
new VirtualFileComposite((VirtualFileSystem *)this, found_file->get_original_filename());
composite_file->set_original_filename(original_filename);
composite_file->add_component(found_file);
found_file = composite_file;
}

View File

@ -94,7 +94,8 @@ public:
private:
Filename normalize_mount_point(const string &mount_point) const;
bool found_match(PT(VirtualFile) &found_file, VirtualFileComposite *&composite_file,
VirtualFileMount *mount, const string &local_filename) const;
VirtualFileMount *mount, const string &local_filename,
const Filename &original_filename) const;
static void parse_option(const string &option,
int &flags, string &password);

View File

@ -29,7 +29,6 @@
#include "preparedGraphicsObjects.h"
#include "pnmImage.h"
#include "virtualFileSystem.h"
#include "hashFilename.h"
#include <stddef.h>
@ -450,10 +449,11 @@ write(const Filename &name, int z) const {
// corresponding number of digits.
////////////////////////////////////////////////////////////////////
bool Texture::
read_pages(const HashFilename &fullpath_template, int z_size) {
if (!fullpath_template.has_hash()) {
read_pages(Filename fullpath_pattern, int z_size) {
fullpath_pattern.set_pattern(true);
if (!fullpath_pattern.has_hash()) {
gobj_cat.error()
<< "Template " << fullpath_template << " contains no hash marks.\n";
<< "Template " << fullpath_pattern << " contains no hash marks.\n";
return false;
}
@ -478,7 +478,7 @@ read_pages(const HashFilename &fullpath_template, int z_size) {
if (z_size != 0) {
set_z_size(z_size);
for (int z = 0; z < z_size; z++) {
if (!read(fullpath_template.get_filename_index(z), z)) {
if (!read(fullpath_pattern.get_filename_index(z), z)) {
return false;
}
}
@ -487,14 +487,14 @@ read_pages(const HashFilename &fullpath_template, int z_size) {
int z = 0;
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
Filename file = fullpath_template.get_filename_index(z);
Filename file = fullpath_pattern.get_filename_index(z);
while (vfs->exists(file)) {
if (!read(file, z)) {
return false;
}
++z;
file = fullpath_template.get_filename_index(z);
file = fullpath_pattern.get_filename_index(z);
}
}
@ -515,15 +515,16 @@ read_pages(const HashFilename &fullpath_template, int z_size) {
// corresponding number of digits.
////////////////////////////////////////////////////////////////////
bool Texture::
write_pages(const HashFilename &fullpath_template) {
if (!fullpath_template.has_hash()) {
write_pages(Filename fullpath_pattern) {
fullpath_pattern.set_pattern(true);
if (!fullpath_pattern.has_hash()) {
gobj_cat.error()
<< "Template " << fullpath_template << " contains no hash marks.\n";
<< "Template " << fullpath_pattern << " contains no hash marks.\n";
return false;
}
for (int z = 0; z < _z_size; z++) {
if (!write(fullpath_template.get_filename_index(z), z)) {
if (!write(fullpath_pattern.get_filename_index(z), z)) {
return false;
}
}

View File

@ -31,7 +31,6 @@ class PNMImage;
class TextureContext;
class FactoryParams;
class PreparedGraphicsObjects;
class HashFilename;
class CullTraverser;
class CullTraverserData;
@ -168,8 +167,8 @@ PUBLISHED:
int primary_file_num_channels = 0, int alpha_file_channel = 0);
bool write(const Filename &fullpath, int z = 0) const;
bool read_pages(const HashFilename &fullpath_template, int z_size = 0);
bool write_pages(const HashFilename &fullpath_template);
bool read_pages(Filename fullpath_pattern, int z_size = 0);
bool write_pages(Filename fullpath_pattern);
virtual bool load(const PNMImage &pnmimage, int z = 0);
bool store(PNMImage &pnmimage, int z = 0) const;

View File

@ -84,8 +84,8 @@ load_texture(const string &filename, const string &alpha_filename,
// filled in with the index number of each level.
////////////////////////////////////////////////////////////////////
INLINE Texture *TexturePool::
load_3d_texture(const string &filename_template) {
return get_global_ptr()->ns_load_3d_texture(filename_template);
load_3d_texture(const string &filename_pattern) {
return get_global_ptr()->ns_load_3d_texture(filename_pattern);
}
////////////////////////////////////////////////////////////////////
@ -98,8 +98,8 @@ load_3d_texture(const string &filename_template) {
// the index number of each pagee.
////////////////////////////////////////////////////////////////////
INLINE Texture *TexturePool::
load_cube_map(const string &filename_template) {
return get_global_ptr()->ns_load_cube_map(filename_template);
load_cube_map(const string &filename_pattern) {
return get_global_ptr()->ns_load_cube_map(filename_pattern);
}
////////////////////////////////////////////////////////////////////

View File

@ -296,42 +296,33 @@ ns_load_texture(const Filename &orig_filename,
// Description: The nonstatic implementation of load_3d_texture().
////////////////////////////////////////////////////////////////////
Texture *TexturePool::
ns_load_3d_texture(const HashFilename &filename_template) {
// Look up filename 0 on the model path.
Filename filename = filename_template.get_filename_index(0);
if (!_fake_texture_image.empty()) {
filename = _fake_texture_image;
}
ns_load_3d_texture(const Filename &filename_pattern) {
Filename filename(filename_pattern);
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(filename, get_texture_path()) ||
vfs->resolve_filename(filename, get_model_path());
// Then, replace everything before the hash code with the directory
// we've found.
string hash = filename_template.get_hash_to_end();
HashFilename hash_filename(filename.substr(0, filename.length() - hash.length()) + hash);
Textures::const_iterator ti;
ti = _textures.find(hash_filename);
ti = _textures.find(filename);
if (ti != _textures.end()) {
// This texture was previously loaded.
return (*ti).second;
}
gobj_cat.info()
<< "Loading 3-d texture " << hash_filename << "\n";
PT(Texture) tex = make_texture(hash_filename.get_extension());
<< "Loading 3-d texture " << filename << "\n";
PT(Texture) tex = make_texture(filename.get_extension());
tex->setup_3d_texture();
if (!tex->read_pages(hash_filename)) {
if (!tex->read_pages(filename)) {
// This texture was not found or could not be read.
report_texture_unreadable(filename);
}
// Set the original filename, before we searched along the path.
tex->set_filename(filename_template);
tex->set_filename(filename_pattern);
_textures[hash_filename] = tex;
_textures[filename] = tex;
return tex;
}
@ -341,42 +332,33 @@ ns_load_3d_texture(const HashFilename &filename_template) {
// Description: The nonstatic implementation of load_cube_map().
////////////////////////////////////////////////////////////////////
Texture *TexturePool::
ns_load_cube_map(const HashFilename &filename_template) {
// Look up filename 0 on the model path.
Filename filename = filename_template.get_filename_index(0);
if (!_fake_texture_image.empty()) {
filename = _fake_texture_image;
}
ns_load_cube_map(const Filename &filename_pattern) {
Filename filename(filename_pattern);
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(filename, get_texture_path()) ||
vfs->resolve_filename(filename, get_model_path());
// Then, replace everything before the hash code with the directory
// we've found.
string hash = filename_template.get_hash_to_end();
HashFilename hash_filename(filename.substr(0, filename.length() - hash.length()) + hash);
Textures::const_iterator ti;
ti = _textures.find(hash_filename);
ti = _textures.find(filename);
if (ti != _textures.end()) {
// This texture was previously loaded.
return (*ti).second;
}
gobj_cat.info()
<< "Loading cube map texture " << hash_filename << "\n";
PT(Texture) tex = make_texture(hash_filename.get_extension());
<< "Loading cube map texture " << filename << "\n";
PT(Texture) tex = make_texture(filename.get_extension());
tex->setup_cube_map();
if (!tex->read_pages(hash_filename)) {
if (!tex->read_pages(filename)) {
// This texture was not found or could not be read.
report_texture_unreadable(filename);
}
// Set the original filename, before we searched along the path.
tex->set_filename(filename_template);
tex->set_filename(filename_pattern);
_textures[hash_filename] = tex;
_textures[filename] = tex;
return tex;
}

View File

@ -23,7 +23,6 @@
#include "texture.h"
#include "filename.h"
#include "config_gobj.h"
#include "hashFilename.h"
#include "pmap.h"
@ -48,8 +47,8 @@ PUBLISHED:
const string &alpha_filename,
int primary_file_num_channels = 0,
int alpha_file_channel = 0);
INLINE static Texture *load_3d_texture(const string &filename_template);
INLINE static Texture *load_cube_map(const string &filename_template);
INLINE static Texture *load_3d_texture(const string &filename_pattern);
INLINE static Texture *load_cube_map(const string &filename_pattern);
INLINE static Texture *get_normalization_cube_map(int size);
@ -87,8 +86,8 @@ private:
const Filename &orig_alpha_filename,
int primary_file_num_channels,
int alpha_file_channel);
Texture *ns_load_3d_texture(const HashFilename &filename_template);
Texture *ns_load_cube_map(const HashFilename &filename_template);
Texture *ns_load_3d_texture(const Filename &filename_pattern);
Texture *ns_load_cube_map(const Filename &filename_pattern);
Texture *ns_get_normalization_cube_map(int size);
void ns_add_texture(Texture *texture);

View File

@ -32,7 +32,6 @@
firstOfPairCompare.I firstOfPairCompare.h \
firstOfPairLess.I firstOfPairLess.h \
globalPointerRegistry.I globalPointerRegistry.h \
hashFilename.I hashFilename.h \
indirectCompareNames.I indirectCompareNames.h \
indirectCompareSort.I indirectCompareSort.h \
indirectCompareTo.I indirectCompareTo.h \
@ -74,7 +73,6 @@
factoryBase.cxx \
factoryParam.cxx factoryParams.cxx \
globalPointerRegistry.cxx \
hashFilename.cxx \
ioPtaDatagramFloat.cxx \
ioPtaDatagramInt.cxx ioPtaDatagramShort.cxx \
keyboardButton.cxx lineStream.cxx lineStreamBuf.cxx \
@ -119,7 +117,6 @@
firstOfPairCompare.I firstOfPairCompare.h \
firstOfPairLess.I firstOfPairLess.h \
globalPointerRegistry.I globalPointerRegistry.h \
hashFilename.I hashFilename.h \
indirectCompareNames.I indirectCompareNames.h \
indirectCompareSort.I indirectCompareSort.h \
indirectCompareTo.I indirectCompareTo.h \

View File

@ -1,112 +0,0 @@
// Filename: hashFilename.I
// Created by: drose (02Aug05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: HashFilename::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE HashFilename::
HashFilename(const string &filename_pattern) :
Filename(filename_pattern)
{
locate_hash();
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE HashFilename::
HashFilename(const HashFilename &copy) :
Filename(copy),
_hash_start(copy._hash_start),
_hash_end(copy._hash_end)
{
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE HashFilename::
HashFilename(const Filename &copy) :
Filename(copy)
{
locate_hash();
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::Copy Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void HashFilename::
operator = (const HashFilename &copy) {
Filename::operator = (copy);
_hash_start = copy._hash_start;
_hash_end = copy._hash_end;
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::Copy Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void HashFilename::
operator = (const Filename &copy) {
Filename::operator = (copy);
locate_hash();
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE HashFilename::
~HashFilename() {
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::has_hash
// Access: Published
// Description: Returns true if the filename pattern did include a
// sequence of hash marks, false otherwise. If this is
// true, then get_filename_index() will return a
// different filename each time.
////////////////////////////////////////////////////////////////////
INLINE bool HashFilename::
has_hash() const {
return (_hash_start != _hash_end);
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::get_hash_to_end
// Access: Published
// Description: Returns the part of the filename beginning at the
// hash sequence (if any), and continuing to the end of
// the filename.
////////////////////////////////////////////////////////////////////
INLINE string HashFilename::
get_hash_to_end() const {
return _filename.substr(_hash_start);
}

View File

@ -1,165 +0,0 @@
// Filename: hashFilename.cxx
// Created by: drose (02Aug05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "hashFilename.h"
////////////////////////////////////////////////////////////////////
// Function: HashFilename::get_filename_index
// Access: Published
// Description: Returns a Filename, derived from the HashFilename,
// with the sequence of hash marks (if any) replaced by
// the indicated index number. If the HashFilename does
// not contain a sequence of hash marks, this quietly
// returns the original filename.
////////////////////////////////////////////////////////////////////
Filename HashFilename::
get_filename_index(int index) const {
Filename file(*this);
if (_hash_end != _hash_start) {
ostringstream strm;
strm << _filename.substr(0, _hash_start)
<< setw(_hash_end - _hash_start) << setfill('0') << index
<< _filename.substr(_hash_end);
file.set_fullpath(strm.str());
}
return file;
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::set_hash_to_end
// Access: Published
// Description: Replaces the part of the filename from the beginning
// of the hash sequence to the end of the filename.
////////////////////////////////////////////////////////////////////
void HashFilename::
set_hash_to_end(const string &s) {
_filename.replace(_hash_start, string::npos, s);
locate_basename();
locate_extension();
locate_hash();
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::resolve_filename
// Access: Published
// 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 HashFilename::
resolve_filename(const DSearchPath &searchpath,
const string &default_extension) {
if (!has_hash()) {
return Filename::resolve_filename(searchpath, default_extension);
}
Filename file0 = get_filename_index(0);
if (!file0.resolve_filename(searchpath, default_extension)) {
return false;
}
int change = file0.length() - length();
if (file0.length() < _hash_start || _hash_end + change < 0 ||
file0.substr(_hash_end + change) != substr(_hash_end)) {
// Hmm, somehow the suffix part of the filename--everything after
// the hash sequence--was changed by the above resolve operation.
// Abandon ship.
return false;
}
// Replace the prefix part of the filename--everything before the
// hash sequence.
_filename = file0.substr(0, _hash_start + change) + substr(_hash_start);
_hash_start += change;
_hash_end += change;
return true;
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::find_on_searchpath
// Access: Published
// Description: Performs the reverse of the resolve_filename()
// operation: assuming that the current filename is
// fully-specified pathname (i.e. beginning with '/'),
// look on the indicated search path for a directory
// under which the file can be found. When found,
// adjust the Filename to be relative to the indicated
// directory name.
//
// Returns the index of the directory on the searchpath
// at which the file was found, or -1 if it was not
// found.
////////////////////////////////////////////////////////////////////
int HashFilename::
find_on_searchpath(const DSearchPath &searchpath) {
if (!has_hash()) {
return Filename::find_on_searchpath(searchpath);
}
Filename file0 = get_filename_index(0);
int index = file0.find_on_searchpath(searchpath);
if (index == -1) {
return -1;
}
int change = file0.length() - length();
if (file0.length() < _hash_start || _hash_end + change < 0 ||
file0.substr(_hash_end + change) != substr(_hash_end)) {
// Hmm, somehow the suffix part of the filename--everything after
// the hash sequence--was changed by the above resolve operation.
// Abandon ship.
return false;
}
// Replace the prefix part of the filename--everything before the
// hash sequence.
_filename = file0.substr(0, _hash_start + change) + substr(_hash_start);
_hash_start += change;
_hash_end += change;
return index;
}
////////////////////////////////////////////////////////////////////
// Function: HashFilename::locate_hash
// Access: Private
// Description: Identifies the part of the filename that contains the
// sequence of hash marks, if any.
////////////////////////////////////////////////////////////////////
void HashFilename::
locate_hash() {
_hash_end = _filename.rfind('#');
if (_hash_end == string::npos) {
_hash_end = string::npos;
_hash_start = string::npos;
} else {
_hash_start = _hash_end;
++_hash_end;
while (_hash_start > 0 && _filename[_hash_start - 1] == '#') {
--_hash_start;
}
}
}

View File

@ -1,65 +0,0 @@
// Filename: hashFilename.h
// Created by: drose (02Aug05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef HASHFILENAME_H
#define HASHFILENAME_H
#include "pandabase.h"
#include "filename.h"
////////////////////////////////////////////////////////////////////
// Class : HashFilename
// Description : This is a specialization on Filename that is intended
// to be used to record a filename pattern for reading a
// numeric sequence of filenames in a directory; for
// instance, as used by TexturePool::load_cube_map().
//
// The Filename may include a string of one or more hash
// marks ('#') in the basename or extension part. These
// will be filled in with digits when
// get_filename_index() is called.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA HashFilename : public Filename {
PUBLISHED:
INLINE HashFilename(const string &filename_pattern = string());
INLINE HashFilename(const HashFilename &copy);
INLINE HashFilename(const Filename &copy);
INLINE void operator = (const HashFilename &copy);
INLINE void operator = (const Filename &copy);
INLINE ~HashFilename();
INLINE bool has_hash() const;
Filename get_filename_index(int index) const;
INLINE string get_hash_to_end() const;
void set_hash_to_end(const string &s);
bool resolve_filename(const DSearchPath &searchpath,
const string &default_extension = string());
int find_on_searchpath(const DSearchPath &searchpath);
private:
void locate_hash();
size_t _hash_start;
size_t _hash_end;
};
#include "hashFilename.I"
#endif

View File

@ -18,7 +18,6 @@
#include "factoryParam.cxx"
#include "factoryParams.cxx"
#include "globalPointerRegistry.cxx"
#include "hashFilename.cxx"
#include "ioPtaDatagramFloat.cxx"
#include "ioPtaDatagramInt.cxx"
#include "ioPtaDatagramShort.cxx"