From ed04ddaaa59dcc42e375ec492dbda77f693530e9 Mon Sep 17 00:00:00 2001 From: Charles McGarvey Date: Tue, 22 Jun 2010 14:34:45 -0600 Subject: [PATCH] fixed some resource management bugs --- src/Animation.cc | 11 ++-- src/GameLayer.cc | 10 ++-- src/Main.cc | 17 ++----- src/Scene.cc | 4 +- src/moof/backend.cc | 3 +- src/moof/image.cc | 4 +- src/moof/resource.cc | 116 +++++++++++++++++++++++++++++-------------- src/moof/resource.hh | 75 ++++++++++++++++++++++------ src/moof/sound.cc | 48 ++++-------------- src/moof/sound.hh | 6 +-- src/moof/sprite.cc | 14 +++--- src/moof/sprite.hh | 4 +- 12 files changed, 178 insertions(+), 134 deletions(-) diff --git a/src/Animation.cc b/src/Animation.cc index 503f77a..fead5ca 100644 --- a/src/Animation.cc +++ b/src/Animation.cc @@ -137,12 +137,12 @@ public: void init(const std::string& name) { moof::script script; - std::string path(name); + std::string path = moof::resource::find_file("animations/"+name, "lua"); - if (!resource::find(path)) - { - throw std::runtime_error("cannot find resource " + name); - } + //if (!resource::find(path)) + //{ + //throw std::runtime_error("cannot find resource " + name); + //} script.import_base_library(); moof::log::import(script); @@ -214,7 +214,6 @@ public: std::map::iterator it; it = mData->mSequences.find(name); - if (it != mData->mSequences.end()) { mCurrentSequence = &(*it).second; diff --git a/src/GameLayer.cc b/src/GameLayer.cc index 86b8710..54e4068 100644 --- a/src/GameLayer.cc +++ b/src/GameLayer.cc @@ -27,8 +27,8 @@ void GameLayer::loadSceneLoader() state_.script.import_standard_libraries(); moof::log::import(state_.script); - std::string path("loader"); - if (!moof::resource::find(path)) + std::string path = moof::resource::find_file("scenes/loader.lua"); + if (path.empty()) { throw std::runtime_error("cannot find scene loader script"); } @@ -80,9 +80,9 @@ void GameLayer::advanceScene(moof::settings& settings) GameLayer::GameLayer() { moof::log_info("about to load sound resource..."); - music_.sample("NightFusionIntro.ogg"); + music_.sample("sounds/NightFusionIntro.ogg"); music_.loop(true); - music_.enqueue("NightFusionLoop.ogg"); + music_.enqueue("sounds/NightFusionLoop.ogg"); music_.position(moof::vector3(10.0, 5.0, 0.0)); mThinkTimer.init(boost::bind(&GameLayer::thinkTimer, this), @@ -99,7 +99,7 @@ void GameLayer::did_add_to_view() { bool isMute = false; settings().get("nomusic", isMute); - if (!isMute) music_.stream(); + music_.stream(); loadSceneLoader(); advanceScene(settings()); // load the first scene diff --git a/src/Main.cc b/src/Main.cc index 046c7bc..3b05e68 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -272,20 +272,9 @@ void goodbye() } -#include -#include -#include - - int main(int argc, char* argv[]) { - //moof::backend backend; - //moof::resource::add_search_paths(Main::getSearchPath()); - - //moof::image hey("textures/AlienWarrior.png"); - - //return 0; - + moof::backend backend; // FIXME: This is temporary. moof::timer reloadTimer(boost::bind(&moof::resource::reload_as_needed), @@ -324,8 +313,10 @@ int main(int argc, char* argv[]) //iconPath = moof::resource::find_file(iconPath); //moof::image icon(iconPath); //icon.set_as_icon(); - moof::image_handle icon(PACKAGE".png"); + moof::image_handle icon(PACKAGE, "png"); if (icon) icon->set_as_icon(); + else moof::log_error("no icon loaded"); + icon.unload(); class moof::video::attributes attributes(settings); moof::video video(PACKAGE_STRING, attributes); diff --git a/src/Scene.cc b/src/Scene.cc index c756ec8..a1218f2 100644 --- a/src/Scene.cc +++ b/src/Scene.cc @@ -177,8 +177,8 @@ struct Scene::impl : public moof::manager moof::script::status load(moof::settings& settings, moof::script& script) { - std::string path(name()); - if (!resource::find(path)) + std::string path = moof::resource::find_file("scenes/"+name(), "lua"); + if (path.empty()) { script.push("the scene file could not be found"); return moof::script::file_error; diff --git a/src/moof/backend.cc b/src/moof/backend.cc index 6dacfa1..2dd199d 100644 --- a/src/moof/backend.cc +++ b/src/moof/backend.cc @@ -48,7 +48,7 @@ backend::backend() char name[128]; SDL_VideoDriverName(name, sizeof(name)); log_info << "initialized SDL; using video driver `" - << name << "'" << std::endl; + << name << "'" << std::endl; } if (FE_Init() != 0) @@ -75,6 +75,7 @@ backend::~backend() { if (--impl::retain_count == 0) { + log_info("shutting down SDL..."); FE_Quit(); SDL_Quit(); diff --git a/src/moof/image.cc b/src/moof/image.cc index abe1677..b5100d5 100644 --- a/src/moof/image.cc +++ b/src/moof/image.cc @@ -51,7 +51,7 @@ image::image(const std::string& path) : tile_width_(1), tile_height_(1) { - FILE* fp = resource::open_file(path); + FILE* fp = fopen(path.c_str(), "rb"); if (!fp) throw std::runtime_error("image not found at " + path); png_byte signature[8]; @@ -348,7 +348,7 @@ public: image_resource_loader() { - resource::register_type("png"); + resource::register_type("png", "textures"); } ~image_resource_loader() diff --git a/src/moof/resource.cc b/src/moof/resource.cc index 053fc0b..c57b527 100644 --- a/src/moof/resource.cc +++ b/src/moof/resource.cc @@ -33,24 +33,32 @@ namespace moof { -void resource::print_types() -{ -} -void resource::manage_loader(const std::string& extension, loader_ptr& loader, bool set) +bool resource::call_registry(const std::string& extension, + loader_ptr& loader, + registry_action action) { - static type_lookup lookup; + static type_lookup table; - if (loader || set) + switch (action) { - lookup[extension] = loader; - } - else - { - std::map::iterator it; - it = lookup.find(extension); - if (it != lookup.end()) loader = (*it).second; + case set: + { + if (loader) table[extension] = loader; + else table.erase(extension); + break; + } + + case lookup: + { + std::map::iterator it; + it = table.find(extension); + if (it != table.end()) loader = (*it).second; + break; + } } + + return loader; } static std::string search_paths_; @@ -58,9 +66,7 @@ static std::string search_paths_; typedef boost::weak_ptr resource_weakptr; static hash resource_table_; -// static member -//resource::type_lookup_ptr resource::type_lookup_; -//resource::type_lookup resource::type_lookup_; +static hash prefix_table_; #ifdef USE_HOTLOADING @@ -123,19 +129,24 @@ resource::~resource() } -resource_ptr resource::load(const std::string& path) +resource_ptr resource::load(const std::string& name, + const std::string& ext) { - std::string extension = stlplus::extension_part(path); + return load_with_path(find_file(name, ext)); +} - std::string path1 = path; - if (!find(path1)) - { - log_error("trying to load missing resource:", path1); - return resource_ptr(); - } +resource_ptr resource::load(const std::string& name) +{ + return load_with_path(find_file(name)); +} + + +resource_ptr resource::load_with_path(const std::string& path) +{ + std::string extension = stlplus::extension_part(path); hash::iterator it; - it = resource_table_.find(path1); + it = resource_table_.find(path); if (it != resource_table_.end()) { resource_weakptr rsrc = (*it).second; @@ -144,23 +155,24 @@ resource_ptr resource::load(const std::string& path) } loader_ptr loader; - manage_loader(extension, loader); + call_registry(extension, loader, lookup); if (loader) { - resource_ptr rsrc(loader->load(path1)); - rsrc->set_loader(path1, loader); - resource_table_[path1] = rsrc; + resource_ptr rsrc(loader->load(path)); + rsrc->set_loader(path, loader); + resource_table_[path] = rsrc; #ifdef USE_HOTLOADING - int wd = inotify_add_watch(monitor_fd_, path1.c_str(), IN_MODIFY); + int wd = inotify_add_watch(monitor_fd_, path.c_str(), IN_MODIFY); rsrc->set_watch_descriptor(wd); - monitor_lookup_[wd] = path1; + monitor_lookup_[wd] = path; #endif log_info("loaded", rsrc.get()); return rsrc; } + log_warning("cannot load resource of unknown type:", path); return resource_ptr(); } @@ -218,26 +230,54 @@ bool resource::find(const std::string& path) return find_file(path) != ""; } + std::string resource::find_file(const std::string& name) { - //log_info("looking for", name, "in", search_paths_); - //return stlplus::lookup(name, search_paths_, ":"); - std::vector paths; boost::split(paths, search_paths_, boost::is_any_of(":")); + std::string ext = stlplus::extension_part(name); + std::string prefix("hi"); + + loader_ptr loader; + call_registry(ext, loader, lookup); + if (loader) prefix = loader->prefix(); + + log_info("find_file:", ext, prefix); + std::vector::iterator it; for (it = paths.begin(); it != paths.end(); ++it) { - *it += "/"; - *it += name; - log_info("looking for", name, "in", *it); - if (stlplus::file_exists(*it)) return *it; + std::string path = stlplus::create_filespec(*it, name); + log_info("looking for", name, "at", path); + if (stlplus::file_exists(path)) return path; + + // try it with the prefix added + if (!prefix.empty()) + { + *it = stlplus::create_filespec(*it, prefix); + path = stlplus::create_filespec(*it, name); + log_info("looking for", name, "at", path); + if (stlplus::file_exists(path)) return path; + } } + + log_error("cannot find resource file:", name); return std::string(); } +std::string resource::find_file(const std::string& name, + const std::string& ext) +{ + std::string actual_ext = stlplus::extension_part(name); + if (actual_ext != ext) + { + return find_file(stlplus::create_filename(name, ext)); + } + return find_file(name); +} + FILE* resource::open_file(const std::string& path, const std::string& mode) { return fopen(find_file(path).c_str(), mode.c_str()); diff --git a/src/moof/resource.hh b/src/moof/resource.hh index 5f1a71a..eba4b3f 100644 --- a/src/moof/resource.hh +++ b/src/moof/resource.hh @@ -46,7 +46,7 @@ class resource { public: - // FIXME: this won't be necessary once the existing code is modified to + // XXX: this won't be necessary once the existing code is modified to // use the resource handles resource() {} @@ -62,11 +62,15 @@ public: * \param path The name of the resource to find. Upon successful * return, this is changed to an absolute path to the resource. * \return True if a path to a resource was found, false otherwise. + * XXX this is legacy */ static bool find(const std::string& file); static std::string find_file(const std::string& name); + static std::string find_file(const std::string& name, + const std::string& ext); + /** * Get the path to a resource of a given name and open it if a resource * was found. @@ -74,6 +78,7 @@ public: * return, this is changed to an absolute path to the resource. * \param mode The open mode. * \return The FILE* if the resource was found, 0 otherwise. + * XXX deprecated */ static FILE* open_file(const std::string& path, const std::string& mode = "rb"); @@ -86,13 +91,12 @@ public: * \param extension The file extension. */ template - static void register_type(const std::string& extension) + static void register_type(const std::string& extension, + const std::string& prefix = "") { - //if (!type_lookup_) type_lookup_ = type_lookup_ptr(new type_lookup); - loader_ptr loader(new specific_loader); - //(*type_lookup_)[extension] = loader; - //type_lookup_[extension] = loader; - manage_loader(extension, loader, true); + loader_ptr loader(new specific_loader(prefix)); + printf("registered type with prefix %s", loader->prefix().c_str()); + call_registry(extension, loader, set); } /** @@ -103,14 +107,14 @@ public: */ static void unregister_type(const std::string& extension) { - //type_lookup_.erase(extension); - //type_lookup_->erase(extension); loader_ptr loader; - manage_loader(extension, loader, true); + call_registry(extension, loader, set); } - static resource_ptr load(const std::string& path); + static resource_ptr load(const std::string& name); + static resource_ptr load(const std::string& name, + const std::string& ext); static resource_ptr reload(std::string& path); @@ -169,21 +173,35 @@ public: */ static int reload_as_needed(); - static void print_types(); - private: + static resource_ptr load_with_path(const std::string& path); + class loader { public: + //loader() {} + loader(const std::string& prefix) : + prefix_(prefix) {} + virtual ~loader() {} virtual resource* load(const std::string& path) { return 0; } + + const std::string& prefix() const + { + return prefix_; + } + + + private: + + std::string prefix_; }; typedef boost::shared_ptr loader_ptr; @@ -193,6 +211,10 @@ private: { public: + //specific_loader() {} + specific_loader(const std::string& prefix) : + loader(prefix) {} + virtual resource* load(const std::string& path) { log_info("loading resource of type ", typeid(T).name()); @@ -249,8 +271,16 @@ private: //typedef boost::shared_ptr type_lookup_ptr; //static type_lookup_ptr type_lookup_; //static type_lookup type_lookup_; + + enum registry_action + { + lookup, + set + }; - static void manage_loader(const std::string& extension, loader_ptr& loader, bool set = false); + static bool call_registry(const std::string& extension, + loader_ptr& loader, + registry_action action); #ifdef USE_HOTLOADING int wd_; @@ -285,8 +315,12 @@ public: resource_handle(resource_ptr ptr) : resource_(ptr) {} - explicit resource_handle(const std::string& path) : - resource_(resource::load(path)) {} + explicit resource_handle(const std::string& name) : + resource_(resource::load(name)) {} + + resource_handle(const std::string& name, const std::string& ext) : + resource_(resource::load(name, ext)) {} + /** @@ -345,6 +379,15 @@ public: } + /** + * Unload the resource associated with this handle. + */ + void unload() + { + resource_ = resource_ptr(); + } + + private: resource_ptr resource_; diff --git a/src/moof/sound.cc b/src/moof/sound.cc index a6fbf03..0714698 100644 --- a/src/moof/sound.cc +++ b/src/moof/sound.cc @@ -35,7 +35,7 @@ #define BUF_SIZE (4096) #endif -#define NUM_BUFFERS (16) +#define NUM_BUFFERS (8) namespace moof { @@ -87,7 +87,6 @@ public: alcMakeContextCurrent(0); alcDestroyContext(al_context); alcCloseDevice(al_device); - log_info("unloaded sound device ALSA"); } } @@ -112,7 +111,7 @@ public: sound_resource_loader() { - resource::register_type("ogg"); + resource::register_type("ogg", "sounds"); } ~sound_resource_loader() @@ -146,7 +145,6 @@ public: alBufferData(buffer_, format, data, size, freq); retain_counts_[buffer_] = 1; - log_warning("ctor buffer:", buffer_); } buffer(const buffer& buf) @@ -174,7 +172,6 @@ public: { alSourceQueueBuffers(source, 1, &buffer_); retain(); - log_warning("queued buffer:", buffer_); } } @@ -182,13 +179,11 @@ public: { ALuint buf = (ALuint)-1; alSourceUnqueueBuffers(source, 1, &buf); - log_warning("unqueued buffer:", buf); return buffer(buf); } void set(ALuint source) const { - log_warning("set buffer:", buffer_); if (*this) alSourcei(source, AL_BUFFER, buffer_); } @@ -217,7 +212,6 @@ private: { alDeleteBuffers(1, &buffer_); retain_counts_.erase(it); - log_warning("kill buffer:", buffer_); } } @@ -240,7 +234,6 @@ public: sound_resource(const std::string& path) { - log_info("audio path is", path); if (ov_fopen((char*)path.c_str(), &file_) < 0) { throw std::runtime_error("problem reading audio: " + path); @@ -284,14 +277,10 @@ public: } else if (result == 0 && size > 0) { - log_info("loaded", size, "bytes from vorbis"); vorbis_info* info = ov_info(&file_, section); buffer_ = buffer(data, size, get_audio_format(info), info->rate); buf = buffer_; - log_info("this section is", section); - log_info("audio format is", get_audio_format(info)); - log_info("audio freq is", info->rate); return true; } else @@ -320,14 +309,9 @@ public: if (result > 0) { - log_info("loaded", result, "bytes from vorbis"); vorbis_info* info = ov_info(&file_, section); buf = buffer(data, result, get_audio_format(info), info->rate); sample = ov_pcm_tell(&file_); - log_info("this section is", section); - log_info("next sample is", sample); - log_info("audio format is", get_audio_format(info)); - log_info("audio freq is", info->rate); return true; } @@ -360,11 +344,10 @@ public: init(); } - impl(const std::string& path) + impl(const std::string& name) { - log_info("sound::impl constructor"); init(); - enqueue(path); + enqueue(name); } void init() @@ -375,14 +358,12 @@ public: sample_ = 0; alGenSources(1, &source_); - log_error("alGenSources:", alGetError()); ALfloat zero[] = {0.0f, 0.0f, 0.0f}; alSourcef(source_, AL_PITCH, 1.0f); alSourcef(source_, AL_GAIN, 1.0f); alSourcefv(source_, AL_POSITION, zero); alSourcefv(source_, AL_VELOCITY, zero); - log_error("init:", alGetError()); } ~impl() @@ -401,7 +382,6 @@ public: if (handle->read(buf)) { - log_info("playing source..."); buf.set(source_); alSourcei(source_, AL_LOOPING, is_looping_); alSourcePlay(source_); @@ -415,7 +395,6 @@ public: if (!is_playing_) { alSourcei(source_, AL_LOOPING, false); - log_error("set not looping:", alGetError()); sound_handle handle = queue_.front(); @@ -434,7 +413,6 @@ public: ALint queued = 0; alGetSourcei(source_, AL_BUFFERS_QUEUED, &queued); - log_info("buffers queued:", queued); } } @@ -444,9 +422,7 @@ public: 0.01, timer::repeat); } - log_info("streaming source..."); alSourcePlay(source_); - log_error("playing:", alGetError()); is_playing_ = true; } @@ -487,13 +463,10 @@ public: // begin the next buffer in the queue handle->read(buf, sample_); buf.queue(source_); - log_info("loading new buffer"); } else if (is_looping_) { // reload the same buffer - log_info("looping same buffer"); - queue_.push_back(handle); handle->read(buf, sample_); buf.queue(source_); @@ -544,19 +517,19 @@ public: } - void sample(const std::string& path) + void sample(const std::string& name) { stop(); alSourcei(source_, AL_BUFFER, AL_NONE); queue_.clear(); - enqueue(path); + enqueue(name); } - void enqueue(const std::string& path) + void enqueue(const std::string& name) { - sound_handle handle = resource::load(path); + sound_handle handle = resource::load(name, "ogg"); queue_.push_back(handle); } @@ -613,10 +586,7 @@ sound::sound() : sound::sound(const std::string& path) : // pass through - impl_(new sound::impl(path)) -{ - log_info("sound constructor"); -} + impl_(new sound::impl(path)) {} void sound::sample(const std::string& path) diff --git a/src/moof/sound.hh b/src/moof/sound.hh index 7fdfd09..e9d4bcf 100644 --- a/src/moof/sound.hh +++ b/src/moof/sound.hh @@ -32,10 +32,10 @@ class sound public: sound(); - explicit sound(const std::string& path); + explicit sound(const std::string& name); - void sample(const std::string& path); - void enqueue(const std::string& path); + void sample(const std::string& name); + void enqueue(const std::string& name); void play(); void stream(); diff --git a/src/moof/sprite.cc b/src/moof/sprite.cc index 7548ab0..ee5db1d 100644 --- a/src/moof/sprite.cc +++ b/src/moof/sprite.cc @@ -15,6 +15,7 @@ #include #include +#include #include "dispatcher.hh" #include "log.hh" @@ -25,16 +26,16 @@ namespace moof { -sprite::sprite(const std::string& path, int tile) +sprite::sprite(const std::string& name, int tile) { - image_ = resource::load(path); - image_->tile_coordinates(tile, tile_); + image(name); + sprite::tile(tile); } sprite::sprite(const image_handle& image, int tile) : image_(image) { - image_->tile_coordinates(tile, tile_); + sprite::tile(tile); } sprite::sprite(const sprite& sprite, int tile) @@ -44,10 +45,9 @@ sprite::sprite(const sprite& sprite, int tile) } -void sprite::image(const std::string& path) +void sprite::image(const std::string& name) { - image_ = resource::load(path); - // FIXME what about tiles? + image_ = resource::load(name, "png"); } void sprite::tile(int tile) diff --git a/src/moof/sprite.hh b/src/moof/sprite.hh index 3cee872..3e3d179 100644 --- a/src/moof/sprite.hh +++ b/src/moof/sprite.hh @@ -31,11 +31,11 @@ class sprite public: sprite() {} - explicit sprite(const std::string& path, int tile = image::no_tile); + explicit sprite(const std::string& name, int tile = image::no_tile); explicit sprite(const image_handle& image, int tile = image::no_tile); explicit sprite(const sprite& sprite, int tile = image::no_tile); - void image(const std::string& path); + void image(const std::string& name); void tile(int tile); void bind() const; -- 2.45.2