mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
fix fmod threading issues
This commit is contained in:
parent
8fd5dff01c
commit
5b2c80e5f3
@ -29,6 +29,14 @@ ConfigureFn(config_fmodAudio) {
|
|||||||
init_libFmodAudio();
|
init_libFmodAudio();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigVariableInt fmod_audio_preload_threshold
|
||||||
|
("fmod-audio-preload-threshold", 1048576,
|
||||||
|
PRC_DESC("Files that are smaller "
|
||||||
|
"than this number of bytes will be preloaded and kept "
|
||||||
|
"resident in memory, while files that are this size or larger "
|
||||||
|
"will be streamed from disk. Set this to -1 to preload "
|
||||||
|
"every file."));
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: init_libFmodAudio
|
// Function: init_libFmodAudio
|
||||||
// Description: Initializes the library. This must be called at
|
// Description: Initializes the library. This must be called at
|
||||||
|
@ -46,9 +46,8 @@ ConfigVariableInt miles_audio_expand_mp3_threshold
|
|||||||
|
|
||||||
ConfigVariableInt miles_audio_preload_threshold
|
ConfigVariableInt miles_audio_preload_threshold
|
||||||
("miles-audio-preload-threshold", -1,
|
("miles-audio-preload-threshold", -1,
|
||||||
PRC_DESC("This is the last Miles fallback size, and should be no smaller "
|
PRC_DESC("This should be no smaller "
|
||||||
"than both miles-audio-expand-mp3-threshold and "
|
"than miles-audio-expand-mp3-threshold. Files that are smaller "
|
||||||
"miles-audio-calc-mp3-threshold. Files that are smaller "
|
|
||||||
"than this number of bytes will be preloaded and kept "
|
"than this number of bytes will be preloaded and kept "
|
||||||
"resident in memory, while files that are this size or larger "
|
"resident in memory, while files that are this size or larger "
|
||||||
"will be streamed from disk. Set this to -1 to preload "
|
"will be streamed from disk. Set this to -1 to preload "
|
||||||
|
@ -142,13 +142,6 @@ FmodAudioManager() {
|
|||||||
if (_system_is_valid) {
|
if (_system_is_valid) {
|
||||||
result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor);
|
result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor);
|
||||||
fmod_audio_errcheck("_system->set3DSettings()", result);
|
fmod_audio_errcheck("_system->set3DSettings()", result);
|
||||||
|
|
||||||
#if (FMOD_VERSION >= 0x00043100) // FMod 4.31.00 changed this API
|
|
||||||
result = _system->setFileSystem(open_callback, close_callback, read_callback, seek_callback, 0, 0, -1);
|
|
||||||
#else
|
|
||||||
result = _system->setFileSystem(open_callback, close_callback, read_callback, seek_callback, -1);
|
|
||||||
#endif
|
|
||||||
fmod_audio_errcheck("_system->setFileSystem()", result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -833,97 +826,4 @@ get_cache_limit() const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: FmodAudioManager::open_callback
|
|
||||||
// Access: Private, Static
|
|
||||||
// Description: A hook into Panda's virtual file system.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
FMOD_RESULT F_CALLBACK FmodAudioManager::
|
|
||||||
open_callback(const char *name, int, unsigned int *file_size,
|
|
||||||
void **handle, void **user_data) {
|
|
||||||
if (name == (const char *)NULL || name[0] == '\0') {
|
|
||||||
// An invalid attempt to open an unnamed file.
|
|
||||||
return FMOD_ERR_FILE_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
|
||||||
|
|
||||||
PT(VirtualFile) file = vfs->get_file(Filename(name));
|
|
||||||
if (file == (VirtualFile *)NULL) {
|
|
||||||
return FMOD_ERR_FILE_NOTFOUND;
|
|
||||||
}
|
|
||||||
istream *str = file->open_read_file(true);
|
|
||||||
|
|
||||||
(*file_size) = file->get_file_size(str);
|
|
||||||
(*handle) = (void *)str;
|
|
||||||
(*user_data) = NULL;
|
|
||||||
|
|
||||||
return FMOD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: FmodAudioManager::close_callback
|
|
||||||
// Access: Private, Static
|
|
||||||
// Description: A hook into Panda's virtual file system.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
FMOD_RESULT F_CALLBACK FmodAudioManager::
|
|
||||||
close_callback(void *handle, void *user_data) {
|
|
||||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
|
||||||
|
|
||||||
istream *str = (istream *)handle;
|
|
||||||
vfs->close_read_file(str);
|
|
||||||
|
|
||||||
return FMOD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: FmodAudioManager::read_callback
|
|
||||||
// Access: Private, Static
|
|
||||||
// Description: A hook into Panda's virtual file system.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
FMOD_RESULT F_CALLBACK FmodAudioManager::
|
|
||||||
read_callback(void *handle, void *buffer, unsigned int size_bytes,
|
|
||||||
unsigned int *bytes_read, void *user_data) {
|
|
||||||
istream *str = (istream *)handle;
|
|
||||||
str->read((char *)buffer, size_bytes);
|
|
||||||
(*bytes_read) = str->gcount();
|
|
||||||
|
|
||||||
// We can't yield here, since this callback is made within a
|
|
||||||
// sub-thread--an OS-level sub-thread spawned by FMod, not a Panda
|
|
||||||
// thread.
|
|
||||||
//thread_consider_yield();
|
|
||||||
|
|
||||||
if (str->eof()) {
|
|
||||||
if ((*bytes_read) == 0) {
|
|
||||||
return FMOD_ERR_FILE_EOF;
|
|
||||||
} else {
|
|
||||||
// Report the EOF next time.
|
|
||||||
return FMOD_OK;
|
|
||||||
}
|
|
||||||
} if (str->fail()) {
|
|
||||||
return FMOD_ERR_FILE_BAD;
|
|
||||||
} else {
|
|
||||||
return FMOD_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: FmodAudioManager::seek_callback
|
|
||||||
// Access: Private, Static
|
|
||||||
// Description: A hook into Panda's virtual file system.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
FMOD_RESULT F_CALLBACK FmodAudioManager::
|
|
||||||
seek_callback(void *handle, unsigned int pos, void *user_data) {
|
|
||||||
istream *str = (istream *)handle;
|
|
||||||
str->clear();
|
|
||||||
str->seekg(pos);
|
|
||||||
|
|
||||||
if (str->fail() && !str->eof()) {
|
|
||||||
return FMOD_ERR_FILE_COULDNOTSEEK;
|
|
||||||
} else {
|
|
||||||
return FMOD_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif //]
|
#endif //]
|
||||||
|
@ -164,20 +164,6 @@ class EXPCL_FMOD_AUDIO FmodAudioManager : public AudioManager {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static FMOD_RESULT F_CALLBACK
|
|
||||||
open_callback(const char *name, int unicode, unsigned int *file_size,
|
|
||||||
void **handle, void **user_data);
|
|
||||||
|
|
||||||
static FMOD_RESULT F_CALLBACK
|
|
||||||
close_callback(void *handle, void *user_data);
|
|
||||||
|
|
||||||
static FMOD_RESULT F_CALLBACK
|
|
||||||
read_callback(void *handle, void *buffer, unsigned int size_bytes,
|
|
||||||
unsigned int *bytes_read, void *user_data);
|
|
||||||
|
|
||||||
static FMOD_RESULT F_CALLBACK
|
|
||||||
seek_callback(void *handle, unsigned int pos, void *user_data);
|
|
||||||
|
|
||||||
FMOD::DSP *make_dsp(const FilterProperties::FilterConfig &conf);
|
FMOD::DSP *make_dsp(const FilterProperties::FilterConfig &conf);
|
||||||
void update_dsp_chain(FMOD::DSP *head, FilterProperties *config);
|
void update_dsp_chain(FMOD::DSP *head, FilterProperties *config);
|
||||||
virtual bool configure_filters(FilterProperties *config);
|
virtual bool configure_filters(FilterProperties *config);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "config_audio.h"
|
#include "config_audio.h"
|
||||||
#include "fmodAudioSound.h"
|
#include "fmodAudioSound.h"
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
|
#include "fileSystemInfo.h"
|
||||||
|
|
||||||
TypeHandle FmodAudioSound::_type_handle;
|
TypeHandle FmodAudioSound::_type_handle;
|
||||||
|
|
||||||
@ -71,46 +72,119 @@ FmodAudioSound(AudioManager *manager, Filename file_name, bool positional) {
|
|||||||
|
|
||||||
_channel = 0;
|
_channel = 0;
|
||||||
_file_name = file_name;
|
_file_name = file_name;
|
||||||
|
_file_name.set_binary();
|
||||||
FMOD_CREATESOUNDEXINFO *sound_info = NULL;
|
|
||||||
|
|
||||||
//Get the Speaker Mode [Important for later on.]
|
//Get the Speaker Mode [Important for later on.]
|
||||||
result = _manager->_system->getSpeakerMode( &_speakermode );
|
result = _manager->_system->getSpeakerMode( &_speakermode );
|
||||||
fmod_audio_errcheck("_system->getSpeakerMode()", result);
|
fmod_audio_errcheck("_system->getSpeakerMode()", result);
|
||||||
|
|
||||||
// Calculate the approximate uncompressed size of the sound.
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||||
int size = file_name.get_file_size();
|
PT(VirtualFile) file = vfs->get_file(_file_name);
|
||||||
string ext = downcase(file_name.get_extension());
|
if (file == (VirtualFile *)NULL) {
|
||||||
if (ext != "wav") size *= 10;
|
// File not found. We will display the appropriate error message
|
||||||
|
// below.
|
||||||
|
result = FMOD_ERR_FILE_NOTFOUND;
|
||||||
|
|
||||||
int flag = positional ? FMOD_3D : FMOD_2D;
|
} else {
|
||||||
int streamflag = (size > 250000) ? FMOD_CREATESTREAM : FMOD_CREATESAMPLE;
|
bool preload = (fmod_audio_preload_threshold < 0) || (file->get_file_size() < fmod_audio_preload_threshold);
|
||||||
|
int flags = FMOD_SOFTWARE;
|
||||||
|
flags |= positional ? FMOD_3D : FMOD_2D;
|
||||||
|
|
||||||
|
FMOD_CREATESOUNDEXINFO sound_info;
|
||||||
|
memset(&sound_info, 0, sizeof(sound_info));
|
||||||
|
sound_info.cbsize = sizeof(sound_info);
|
||||||
|
|
||||||
|
string ext = downcase(_file_name.get_extension());
|
||||||
if (ext == "mid") {
|
if (ext == "mid") {
|
||||||
streamflag = FMOD_CREATESTREAM;
|
// Get the MIDI parameters.
|
||||||
sound_info = &_manager->_midi_info;
|
memcpy(&sound_info, &_manager->_midi_info, sizeof(sound_info));
|
||||||
|
if (sound_info.dlsname != NULL) {
|
||||||
if (sound_info->dlsname != NULL) {
|
audio_debug("Using DLS file " << sound_info.dlsname);
|
||||||
audio_debug("Using DLS file " << sound_info->dlsname);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = _manager->_system->createSound( file_name.c_str(), FMOD_SOFTWARE | streamflag | flag ,
|
const char *name_or_data = _file_name.c_str();
|
||||||
sound_info, &_sound);
|
|
||||||
|
pvector<unsigned char> mem_buffer;
|
||||||
|
FileSystemInfo info;
|
||||||
|
if (preload) {
|
||||||
|
// Pre-read the file right now, and pass it in as a memory
|
||||||
|
// buffer. This avoids threading issues completely, because all
|
||||||
|
// of the reading happens right here.
|
||||||
|
file->read_file(mem_buffer, true);
|
||||||
|
sound_info.length = mem_buffer.size();
|
||||||
|
if (mem_buffer.size() != 0) {
|
||||||
|
name_or_data = (const char *)&mem_buffer[0];
|
||||||
|
}
|
||||||
|
flags |= FMOD_OPENMEMORY;
|
||||||
|
if (fmodAudio_cat.is_debug()) {
|
||||||
|
fmodAudio_cat.debug()
|
||||||
|
<< "Reading " << _file_name << " into memory (" << sound_info.length
|
||||||
|
<< " bytes)\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (file->get_system_info(info)) {
|
||||||
|
// The file exists on disk (or it's part of a multifile that
|
||||||
|
// exists on disk), so we can have FMod read the file directly.
|
||||||
|
// This is also safe, because FMod uses its own I/O operations
|
||||||
|
// that don't involve Panda, so this can safely happen in an
|
||||||
|
// FMod thread.
|
||||||
|
name_or_data = info.get_os_file_name().c_str();
|
||||||
|
sound_info.fileoffset = (unsigned int)info.get_file_start();
|
||||||
|
sound_info.length = (unsigned int)info.get_file_size();
|
||||||
|
flags |= FMOD_CREATESTREAM;
|
||||||
|
if (fmodAudio_cat.is_debug()) {
|
||||||
|
fmodAudio_cat.debug()
|
||||||
|
<< "Streaming " << _file_name << " from disk (" << name_or_data
|
||||||
|
<< ", " << sound_info.fileoffset << ", " << sound_info.length << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||||
|
// Otherwise, if the Panda threading system is compiled in, we
|
||||||
|
// can assign callbacks to read the file through the VFS.
|
||||||
|
name_or_data = (const char *)file.p();
|
||||||
|
sound_info.length = (unsigned int)info.get_file_size();
|
||||||
|
sound_info.useropen = open_callback;
|
||||||
|
sound_info.userclose = close_callback;
|
||||||
|
sound_info.userread = read_callback;
|
||||||
|
sound_info.userseek = seek_callback;
|
||||||
|
flags |= FMOD_CREATESTREAM;
|
||||||
|
if (fmodAudio_cat.is_debug()) {
|
||||||
|
fmodAudio_cat.debug()
|
||||||
|
<< "Streaming " << _file_name << " from disk using callbacks\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // HAVE_THREADS && !SIMPLE_THREADS
|
||||||
|
// Without threads, we can't safely read this file.
|
||||||
|
name_or_data = "";
|
||||||
|
|
||||||
|
fmodAudio_cat.warning()
|
||||||
|
<< "Cannot stream " << _file_name << "; file is not literally on disk.\n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
result =
|
||||||
|
_manager->_system->createSound(name_or_data, flags, &sound_info, &_sound);
|
||||||
|
}
|
||||||
|
|
||||||
if (result != FMOD_OK) {
|
if (result != FMOD_OK) {
|
||||||
audio_error("createSound(" << file_name << "): " << FMOD_ErrorString(result));
|
audio_error("createSound(" << _file_name << "): " << FMOD_ErrorString(result));
|
||||||
|
|
||||||
// We couldn't load the sound file. Create a blank sound record
|
// We couldn't load the sound file. Create a blank sound record
|
||||||
// instead.
|
// instead.
|
||||||
|
FMOD_CREATESOUNDEXINFO sound_info;
|
||||||
|
memset(&sound_info, 0, sizeof(sound_info));
|
||||||
char blank_data[100];
|
char blank_data[100];
|
||||||
FMOD_CREATESOUNDEXINFO exinfo;
|
|
||||||
memset(&exinfo, 0, sizeof(exinfo));
|
|
||||||
memset(blank_data, 0, sizeof(blank_data));
|
memset(blank_data, 0, sizeof(blank_data));
|
||||||
exinfo.cbsize = sizeof(exinfo);
|
sound_info.cbsize = sizeof(sound_info);
|
||||||
exinfo.length = sizeof(blank_data);
|
sound_info.length = sizeof(blank_data);
|
||||||
exinfo.numchannels = 1;
|
sound_info.numchannels = 1;
|
||||||
exinfo.defaultfrequency = 8000;
|
sound_info.defaultfrequency = 8000;
|
||||||
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
|
sound_info.format = FMOD_SOUND_FORMAT_PCM16;
|
||||||
result = _manager->_system->createSound( blank_data, FMOD_SOFTWARE | flag | FMOD_OPENMEMORY | FMOD_OPENRAW, &exinfo, &_sound);
|
int flags = FMOD_SOFTWARE | FMOD_OPENMEMORY | FMOD_OPENRAW;
|
||||||
|
|
||||||
|
result = _manager->_system->createSound( blank_data, flags, &sound_info, &_sound);
|
||||||
fmod_audio_errcheck("createSound (blank)", result);
|
fmod_audio_errcheck("createSound (blank)", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,27 +231,6 @@ play() {
|
|||||||
start_playing();
|
start_playing();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: sound_end_callback
|
|
||||||
// Access: Static
|
|
||||||
// Description: When fmod finishes playing a sound, decrements the
|
|
||||||
// reference count of the associated FmodAudioSound.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
FMOD_RESULT F_CALLBACK sound_end_callback(FMOD_CHANNEL * channel,
|
|
||||||
FMOD_CHANNEL_CALLBACKTYPE type,
|
|
||||||
void *commanddata1,
|
|
||||||
void *commanddata2) {
|
|
||||||
if (type == FMOD_CHANNEL_CALLBACKTYPE_END) {
|
|
||||||
FMOD::Channel *fc = (FMOD::Channel *)channel;
|
|
||||||
void *userdata = NULL;
|
|
||||||
FMOD_RESULT result = fc->getUserData(&userdata);
|
|
||||||
fmod_audio_errcheck("channel->getUserData()", result);
|
|
||||||
FmodAudioSound *fsound = (FmodAudioSound*)userdata;
|
|
||||||
fsound->_self_ref = fsound;
|
|
||||||
}
|
|
||||||
return FMOD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: FmodAudioSound::stop
|
// Function: FmodAudioSound::stop
|
||||||
// Access: public
|
// Access: public
|
||||||
@ -884,4 +937,147 @@ get_finished_event() const {
|
|||||||
return _finished_event;
|
return _finished_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FmodAudioSound::sound_end_callback
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: When fmod finishes playing a sound, decrements the
|
||||||
|
// reference count of the associated FmodAudioSound.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
FMOD_RESULT F_CALLBACK FmodAudioSound::
|
||||||
|
sound_end_callback(FMOD_CHANNEL * channel,
|
||||||
|
FMOD_CHANNEL_CALLBACKTYPE type,
|
||||||
|
void *commanddata1,
|
||||||
|
void *commanddata2) {
|
||||||
|
// Fortunately, this callback is made synchronously rather than
|
||||||
|
// asynchronously (it is triggered during System::update()), so we
|
||||||
|
// don't have to worry about thread-related issues here.
|
||||||
|
if (type == FMOD_CHANNEL_CALLBACKTYPE_END) {
|
||||||
|
FMOD::Channel *fc = (FMOD::Channel *)channel;
|
||||||
|
void *userdata = NULL;
|
||||||
|
FMOD_RESULT result = fc->getUserData(&userdata);
|
||||||
|
fmod_audio_errcheck("channel->getUserData()", result);
|
||||||
|
FmodAudioSound *fsound = (FmodAudioSound*)userdata;
|
||||||
|
fsound->_self_ref = fsound;
|
||||||
|
}
|
||||||
|
return FMOD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FmodAudioSound::open_callback
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: A hook into Panda's virtual file system.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
FMOD_RESULT F_CALLBACK FmodAudioSound::
|
||||||
|
open_callback(const char *name, int, unsigned int *file_size,
|
||||||
|
void **handle, void **user_data) {
|
||||||
|
// We actually pass in the VirtualFile pointer as the "name".
|
||||||
|
VirtualFile *file = (VirtualFile *)name;
|
||||||
|
if (file == (VirtualFile *)NULL) {
|
||||||
|
return FMOD_ERR_FILE_NOTFOUND;
|
||||||
|
}
|
||||||
|
if (fmodAudio_cat.is_spam()) {
|
||||||
|
fmodAudio_cat.spam()
|
||||||
|
<< "open_callback(" << *file << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
istream *str = file->open_read_file(true);
|
||||||
|
|
||||||
|
(*file_size) = file->get_file_size(str);
|
||||||
|
(*handle) = (void *)str;
|
||||||
|
(*user_data) = (void *)file;
|
||||||
|
|
||||||
|
// Explicitly ref the VirtualFile since we're storing it in a void
|
||||||
|
// pointer instead of a PT(VirtualFile).
|
||||||
|
file->ref();
|
||||||
|
|
||||||
|
return FMOD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FmodAudioSound::close_callback
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: A hook into Panda's virtual file system.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
FMOD_RESULT F_CALLBACK FmodAudioSound::
|
||||||
|
close_callback(void *handle, void *user_data) {
|
||||||
|
VirtualFile *file = (VirtualFile *)user_data;
|
||||||
|
if (fmodAudio_cat.is_spam()) {
|
||||||
|
fmodAudio_cat.spam()
|
||||||
|
<< "close_callback(" << *file << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||||
|
|
||||||
|
istream *str = (istream *)handle;
|
||||||
|
vfs->close_read_file(str);
|
||||||
|
|
||||||
|
// Explicitly unref the VirtualFile pointer.
|
||||||
|
unref_delete(file);
|
||||||
|
|
||||||
|
return FMOD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FmodAudioSound::read_callback
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: A hook into Panda's virtual file system.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
FMOD_RESULT F_CALLBACK FmodAudioSound::
|
||||||
|
read_callback(void *handle, void *buffer, unsigned int size_bytes,
|
||||||
|
unsigned int *bytes_read, void *user_data) {
|
||||||
|
VirtualFile *file = (VirtualFile *)user_data;
|
||||||
|
if (fmodAudio_cat.is_spam()) {
|
||||||
|
fmodAudio_cat.spam()
|
||||||
|
<< "read_callback(" << *file << ", " << size_bytes << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
istream *str = (istream *)handle;
|
||||||
|
str->read((char *)buffer, size_bytes);
|
||||||
|
(*bytes_read) = str->gcount();
|
||||||
|
|
||||||
|
// We can't yield here, since this callback is made within a
|
||||||
|
// sub-thread--an OS-level sub-thread spawned by FMod, not a Panda
|
||||||
|
// thread. But we will only execute this code in the true-threads
|
||||||
|
// case anyway.
|
||||||
|
//thread_consider_yield();
|
||||||
|
|
||||||
|
if (str->eof()) {
|
||||||
|
if ((*bytes_read) == 0) {
|
||||||
|
return FMOD_ERR_FILE_EOF;
|
||||||
|
} else {
|
||||||
|
// Report the EOF next time.
|
||||||
|
return FMOD_OK;
|
||||||
|
}
|
||||||
|
} if (str->fail()) {
|
||||||
|
return FMOD_ERR_FILE_BAD;
|
||||||
|
} else {
|
||||||
|
return FMOD_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FmodAudioSound::seek_callback
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: A hook into Panda's virtual file system.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
FMOD_RESULT F_CALLBACK FmodAudioSound::
|
||||||
|
seek_callback(void *handle, unsigned int pos, void *user_data) {
|
||||||
|
VirtualFile *file = (VirtualFile *)user_data;
|
||||||
|
if (fmodAudio_cat.is_spam()) {
|
||||||
|
fmodAudio_cat.spam()
|
||||||
|
<< "seek_callback(" << *file << ", " << pos << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
istream *str = (istream *)handle;
|
||||||
|
str->clear();
|
||||||
|
str->seekg(pos);
|
||||||
|
|
||||||
|
if (str->fail() && !str->eof()) {
|
||||||
|
return FMOD_ERR_FILE_COULDNOTSEEK;
|
||||||
|
} else {
|
||||||
|
return FMOD_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //]
|
#endif //]
|
||||||
|
@ -204,11 +204,27 @@ class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound {
|
|||||||
// other mismanagement.
|
// other mismanagement.
|
||||||
PT(FmodAudioSound) _self_ref;
|
PT(FmodAudioSound) _self_ref;
|
||||||
|
|
||||||
friend FMOD_RESULT F_CALLBACK sound_end_callback(FMOD_CHANNEL * channel,
|
static FMOD_RESULT F_CALLBACK
|
||||||
|
sound_end_callback(FMOD_CHANNEL * channel,
|
||||||
FMOD_CHANNEL_CALLBACKTYPE type,
|
FMOD_CHANNEL_CALLBACKTYPE type,
|
||||||
void *commanddata1,
|
void *commanddata1,
|
||||||
void *commanddata2);
|
void *commanddata2);
|
||||||
|
|
||||||
|
static FMOD_RESULT F_CALLBACK
|
||||||
|
open_callback(const char *name, int unicode, unsigned int *file_size,
|
||||||
|
void **handle, void **user_data);
|
||||||
|
|
||||||
|
static FMOD_RESULT F_CALLBACK
|
||||||
|
close_callback(void *handle, void *user_data);
|
||||||
|
|
||||||
|
static FMOD_RESULT F_CALLBACK
|
||||||
|
read_callback(void *handle, void *buffer, unsigned int size_bytes,
|
||||||
|
unsigned int *bytes_read, void *user_data);
|
||||||
|
|
||||||
|
static FMOD_RESULT F_CALLBACK
|
||||||
|
seek_callback(void *handle, unsigned int pos, void *user_data);
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//These are needed for Panda's Pointer System. DO NOT ERASE!
|
//These are needed for Panda's Pointer System. DO NOT ERASE!
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
encrypt_string.h \
|
encrypt_string.h \
|
||||||
error_utils.h \
|
error_utils.h \
|
||||||
export_dtool.h \
|
export_dtool.h \
|
||||||
|
fileSystemInfo.h fileSystemInfo.I \
|
||||||
hashGeneratorBase.I hashGeneratorBase.h \
|
hashGeneratorBase.I hashGeneratorBase.h \
|
||||||
hashVal.I hashVal.h \
|
hashVal.I hashVal.h \
|
||||||
indirectLess.I indirectLess.h \
|
indirectLess.I indirectLess.h \
|
||||||
@ -84,6 +85,7 @@
|
|||||||
datagramSink.cxx dcast.cxx \
|
datagramSink.cxx dcast.cxx \
|
||||||
encrypt_string.cxx \
|
encrypt_string.cxx \
|
||||||
error_utils.cxx \
|
error_utils.cxx \
|
||||||
|
fileSystemInfo.cxx \
|
||||||
hashGeneratorBase.cxx hashVal.cxx \
|
hashGeneratorBase.cxx hashVal.cxx \
|
||||||
memoryInfo.cxx memoryUsage.cxx memoryUsagePointerCounts.cxx \
|
memoryInfo.cxx memoryUsage.cxx memoryUsagePointerCounts.cxx \
|
||||||
memoryUsagePointers.cxx multifile.cxx \
|
memoryUsagePointers.cxx multifile.cxx \
|
||||||
@ -140,6 +142,7 @@
|
|||||||
dcast.T dcast.h \
|
dcast.T dcast.h \
|
||||||
encrypt_string.h \
|
encrypt_string.h \
|
||||||
error_utils.h \
|
error_utils.h \
|
||||||
|
fileSystemInfo.h fileSystemInfo.I \
|
||||||
hashGeneratorBase.I hashGeneratorBase.h \
|
hashGeneratorBase.I hashGeneratorBase.h \
|
||||||
hashVal.I hashVal.h \
|
hashVal.I hashVal.h \
|
||||||
indirectLess.I indirectLess.h \
|
indirectLess.I indirectLess.h \
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "dcast.cxx"
|
#include "dcast.cxx"
|
||||||
#include "encrypt_string.cxx"
|
#include "encrypt_string.cxx"
|
||||||
#include "error_utils.cxx"
|
#include "error_utils.cxx"
|
||||||
|
#include "fileSystemInfo.cxx"
|
||||||
#include "hashGeneratorBase.cxx"
|
#include "hashGeneratorBase.cxx"
|
||||||
#include "hashVal.cxx"
|
#include "hashVal.cxx"
|
||||||
#include "memoryInfo.cxx"
|
#include "memoryInfo.cxx"
|
||||||
|
103
panda/src/express/fileSystemInfo.I
Normal file
103
panda/src/express/fileSystemInfo.I
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Filename: fileSystemInfo.I
|
||||||
|
// Created by: drose (20Jun11)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FileSystemInfo::Default Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE FileSystemInfo::
|
||||||
|
FileSystemInfo() :
|
||||||
|
_file_start(0),
|
||||||
|
_file_size(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FileSystemInfo::Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE FileSystemInfo::
|
||||||
|
FileSystemInfo(const string &os_file_name, streampos file_start, streamsize file_size) :
|
||||||
|
_os_file_name(os_file_name),
|
||||||
|
_file_start(file_start),
|
||||||
|
_file_size(file_size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FileSystemInfo::Copy Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE FileSystemInfo::
|
||||||
|
FileSystemInfo(const FileSystemInfo ©) :
|
||||||
|
_os_file_name(copy._os_file_name),
|
||||||
|
_file_start(copy._file_start),
|
||||||
|
_file_size(copy._file_size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FileSystemInfo::Copy Assignment Operator
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void FileSystemInfo::
|
||||||
|
operator = (const FileSystemInfo ©) {
|
||||||
|
_os_file_name = copy._os_file_name;
|
||||||
|
_file_start = copy._file_start;
|
||||||
|
_file_size = copy._file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FileSystemInfo::get_os_file_name
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the os-specific filename that may be used to
|
||||||
|
// open this file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const string &FileSystemInfo::
|
||||||
|
get_os_file_name() const {
|
||||||
|
return _os_file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FileSystemInfo::get_file_start
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the offset within the file at which this file
|
||||||
|
// data begins.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE streampos FileSystemInfo::
|
||||||
|
get_file_start() const {
|
||||||
|
return _file_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FileSystemInfo::get_file_size
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of consecutive bytes, beginning at
|
||||||
|
// get_file_start(), that correspond to this file data.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE streamsize FileSystemInfo::
|
||||||
|
get_file_size() const {
|
||||||
|
return _file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE ostream &
|
||||||
|
operator << (ostream &out, const FileSystemInfo &info) {
|
||||||
|
info.output(out);
|
||||||
|
return out;
|
||||||
|
}
|
26
panda/src/express/fileSystemInfo.cxx
Normal file
26
panda/src/express/fileSystemInfo.cxx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Filename: fileSystemInfo.cxx
|
||||||
|
// Created by: drose (20Jun11)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "fileSystemInfo.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FileSystemInfo::output
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FileSystemInfo::
|
||||||
|
output(ostream &out) const {
|
||||||
|
out << "FileSystemInfo(" << _os_file_name << ", " << _file_start
|
||||||
|
<< ", " << _file_size << ")";
|
||||||
|
}
|
48
panda/src/express/fileSystemInfo.h
Normal file
48
panda/src/express/fileSystemInfo.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Filename: fileSystemInfo.h
|
||||||
|
// Created by: drose (20Jun11)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef FILESYSTEMINFO_H
|
||||||
|
#define FILESYSTEMINFO_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : FileSystemInfo
|
||||||
|
// Description : This class is used to return data about an actual
|
||||||
|
// file on disk by VirtualFile::get_system_info().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDAEXPRESS FileSystemInfo {
|
||||||
|
PUBLISHED:
|
||||||
|
INLINE FileSystemInfo();
|
||||||
|
INLINE FileSystemInfo(const string &os_file_name, streampos file_start, streamsize file_size);
|
||||||
|
INLINE FileSystemInfo(const FileSystemInfo ©);
|
||||||
|
INLINE void operator = (const FileSystemInfo ©);
|
||||||
|
|
||||||
|
INLINE const string &get_os_file_name() const;
|
||||||
|
INLINE streampos get_file_start() const;
|
||||||
|
INLINE streamsize get_file_size() const;
|
||||||
|
|
||||||
|
void output(ostream &out) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
string _os_file_name;
|
||||||
|
streampos _file_start;
|
||||||
|
streamsize _file_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
INLINE ostream &operator << (ostream &out, const FileSystemInfo &info);
|
||||||
|
|
||||||
|
#include "fileSystemInfo.I"
|
||||||
|
|
||||||
|
#endif
|
@ -26,6 +26,7 @@
|
|||||||
#include "referenceCount.h"
|
#include "referenceCount.h"
|
||||||
#include "pvector.h"
|
#include "pvector.h"
|
||||||
#include "openSSLWrapper.h"
|
#include "openSSLWrapper.h"
|
||||||
|
#include "fileSystemInfo.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : Multifile
|
// Class : Multifile
|
||||||
|
@ -213,6 +213,21 @@ get_timestamp() const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::get_system_info
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Populates the FileSystemInfo structure with the data
|
||||||
|
// representing where the file actually resides on disk,
|
||||||
|
// if this is knowable. Returns true if the file might
|
||||||
|
// reside on disk, and the info is populated, or false
|
||||||
|
// if it does not (or it is not known where the file
|
||||||
|
// resides), in which case the info is meaningless.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFile::
|
||||||
|
get_system_info(FileSystemInfo &info) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: VirtualFile::close_read_file
|
// Function: VirtualFile::close_read_file
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
|
|
||||||
#include "filename.h"
|
#include "filename.h"
|
||||||
|
#include "fileSystemInfo.h"
|
||||||
#include "pointerTo.h"
|
#include "pointerTo.h"
|
||||||
#include "typedReferenceCount.h"
|
#include "typedReferenceCount.h"
|
||||||
#include "ordered_vector.h"
|
#include "ordered_vector.h"
|
||||||
@ -60,6 +61,8 @@ PUBLISHED:
|
|||||||
BLOCKING virtual off_t get_file_size() const;
|
BLOCKING virtual off_t get_file_size() const;
|
||||||
BLOCKING virtual time_t get_timestamp() const;
|
BLOCKING virtual time_t get_timestamp() const;
|
||||||
|
|
||||||
|
virtual bool get_system_info(FileSystemInfo &info);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
INLINE void set_original_filename(const Filename &filename);
|
INLINE void set_original_filename(const Filename &filename);
|
||||||
bool read_file(string &result, bool auto_unwrap) const;
|
bool read_file(string &result, bool auto_unwrap) const;
|
||||||
|
@ -140,6 +140,21 @@ close_read_file(istream *stream) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMount::get_system_info
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Populates the FileSystemInfo structure with the data
|
||||||
|
// representing where the file actually resides on disk,
|
||||||
|
// if this is knowable. Returns true if the file might
|
||||||
|
// reside on disk, and the info is populated, or false
|
||||||
|
// if it does not (or it is not known where the file
|
||||||
|
// resides), in which case the info is meaningless.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMount::
|
||||||
|
get_system_info(const Filename &file, FileSystemInfo &info) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: VirtualFileMount::output
|
// Function: VirtualFileMount::output
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
virtual off_t get_file_size(const Filename &file, istream *stream) const=0;
|
virtual off_t get_file_size(const Filename &file, istream *stream) const=0;
|
||||||
virtual off_t get_file_size(const Filename &file) const=0;
|
virtual off_t get_file_size(const Filename &file) const=0;
|
||||||
virtual time_t get_timestamp(const Filename &file) const=0;
|
virtual time_t get_timestamp(const Filename &file) const=0;
|
||||||
|
virtual bool get_system_info(const Filename &file, FileSystemInfo &info);
|
||||||
|
|
||||||
virtual bool scan_directory(vector_string &contents,
|
virtual bool scan_directory(vector_string &contents,
|
||||||
const Filename &dir) const=0;
|
const Filename &dir) const=0;
|
||||||
|
@ -171,6 +171,38 @@ get_timestamp(const Filename &file) const {
|
|||||||
return _multifile->get_subfile_timestamp(subfile_index);
|
return _multifile->get_subfile_timestamp(subfile_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountMultifile::get_system_info
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Populates the FileSystemInfo structure with the data
|
||||||
|
// representing where the file actually resides on disk,
|
||||||
|
// if this is knowable. Returns true if the file might
|
||||||
|
// reside on disk, and the info is populated, or false
|
||||||
|
// if it might not (or it is not known where the file
|
||||||
|
// resides), in which case the info is meaningless.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountMultifile::
|
||||||
|
get_system_info(const Filename &file, FileSystemInfo &info) {
|
||||||
|
Filename multifile_name = _multifile->get_multifile_name();
|
||||||
|
if (multifile_name.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int subfile_index = _multifile->find_subfile(file);
|
||||||
|
if (subfile_index < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (_multifile->is_subfile_compressed(subfile_index) ||
|
||||||
|
_multifile->is_subfile_encrypted(subfile_index)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
streampos start = _multifile->get_subfile_internal_start(subfile_index);
|
||||||
|
size_t length = _multifile->get_subfile_internal_length(subfile_index);
|
||||||
|
|
||||||
|
info = FileSystemInfo(multifile_name.to_os_specific(), start, length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: VirtualFileMountMultifile::scan_directory
|
// Function: VirtualFileMountMultifile::scan_directory
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -45,6 +45,7 @@ public:
|
|||||||
virtual off_t get_file_size(const Filename &file, istream *stream) const;
|
virtual off_t get_file_size(const Filename &file, istream *stream) const;
|
||||||
virtual off_t get_file_size(const Filename &file) const;
|
virtual off_t get_file_size(const Filename &file) const;
|
||||||
virtual time_t get_timestamp(const Filename &file) const;
|
virtual time_t get_timestamp(const Filename &file) const;
|
||||||
|
virtual bool get_system_info(const Filename &file, FileSystemInfo &info);
|
||||||
|
|
||||||
virtual bool scan_directory(vector_string &contents,
|
virtual bool scan_directory(vector_string &contents,
|
||||||
const Filename &dir) const;
|
const Filename &dir) const;
|
||||||
|
@ -181,6 +181,23 @@ get_timestamp(const Filename &file) const {
|
|||||||
return pathname.get_timestamp();
|
return pathname.get_timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountSystem::get_system_info
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Populates the FileSystemInfo structure with the data
|
||||||
|
// representing where the file actually resides on disk,
|
||||||
|
// if this is knowable. Returns true if the file might
|
||||||
|
// reside on disk, and the info is populated, or false
|
||||||
|
// if it does not (or it is not known where the file
|
||||||
|
// resides), in which case the info is meaningless.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountSystem::
|
||||||
|
get_system_info(const Filename &file, FileSystemInfo &info) {
|
||||||
|
Filename pathname(_physical_filename, file);
|
||||||
|
info = FileSystemInfo(pathname.to_os_specific(), 0, pathname.get_file_size());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: VirtualFileMountSystem::scan_directory
|
// Function: VirtualFileMountSystem::scan_directory
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -39,6 +39,7 @@ public:
|
|||||||
virtual off_t get_file_size(const Filename &file, istream *stream) const;
|
virtual off_t get_file_size(const Filename &file, istream *stream) const;
|
||||||
virtual off_t get_file_size(const Filename &file) const;
|
virtual off_t get_file_size(const Filename &file) const;
|
||||||
virtual time_t get_timestamp(const Filename &file) const;
|
virtual time_t get_timestamp(const Filename &file) const;
|
||||||
|
virtual bool get_system_info(const Filename &file, FileSystemInfo &info);
|
||||||
|
|
||||||
virtual bool scan_directory(vector_string &contents,
|
virtual bool scan_directory(vector_string &contents,
|
||||||
const Filename &dir) const;
|
const Filename &dir) const;
|
||||||
|
@ -160,6 +160,21 @@ get_timestamp() const {
|
|||||||
return _mount->get_timestamp(_local_filename);
|
return _mount->get_timestamp(_local_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSimple::get_system_info
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Populates the FileSystemInfo structure with the data
|
||||||
|
// representing where the file actually resides on disk,
|
||||||
|
// if this is knowable. Returns true if the file might
|
||||||
|
// reside on disk, and the info is populated, or false
|
||||||
|
// if it does not (or it is not known where the file
|
||||||
|
// resides), in which case the info is meaningless.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileSimple::
|
||||||
|
get_system_info(FileSystemInfo &info) {
|
||||||
|
return _mount->get_system_info(_local_filename, info);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: VirtualFileSimple::read_file
|
// Function: VirtualFileSimple::read_file
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -46,6 +46,7 @@ PUBLISHED:
|
|||||||
virtual off_t get_file_size(istream *stream) const;
|
virtual off_t get_file_size(istream *stream) const;
|
||||||
virtual off_t get_file_size() const;
|
virtual off_t get_file_size() const;
|
||||||
virtual time_t get_timestamp() const;
|
virtual time_t get_timestamp() const;
|
||||||
|
virtual bool get_system_info(FileSystemInfo &info);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool read_file(pvector<unsigned char> &result, bool auto_unwrap) const;
|
virtual bool read_file(pvector<unsigned char> &result, bool auto_unwrap) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user