From: Ingo Ruhnke Date: Sun, 6 Dec 2009 12:09:24 +0000 (+0000) Subject: Splitted TextureManager::create_image_texture() into multiple functions X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=c8597ac89064c0ef1e428f9536fc46733579f7a0;p=supertux.git Splitted TextureManager::create_image_texture() into multiple functions Added SDLSurfacePtr class that handles the SDL_FreeSurface() call in an exception safe manner SVN-Revision: 6185 --- diff --git a/src/video/sdl_surface_ptr.hpp b/src/video/sdl_surface_ptr.hpp new file mode 100644 index 000000000..2fffc95fd --- /dev/null +++ b/src/video/sdl_surface_ptr.hpp @@ -0,0 +1,55 @@ +// SuperTux +// Copyright (C) 2009 Ingo Ruhnke +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef HEADER_SUPERTUX_VIDEO_SDL_SURFACE_PTR_HPP +#define HEADER_SUPERTUX_VIDEO_SDL_SURFACE_PTR_HPP + +#include + +/** Simple Wrapper class around SDL_Surface that provides execption + safety */ +class SDLSurfacePtr +{ +private: + SDL_Surface* m_surface; + +public: + SDLSurfacePtr(SDL_Surface* surface) : + m_surface(surface) + {} + + ~SDLSurfacePtr() + { + SDL_FreeSurface(m_surface); + } + + SDL_Surface* get() + { + return m_surface; + } + + operator void*() { + return m_surface; + } + +private: + SDLSurfacePtr(const SDLSurfacePtr&); + SDLSurfacePtr& operator=(const SDLSurfacePtr&); +}; + +#endif + +/* EOF */ diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp index 5cb962be5..40736397f 100644 --- a/src/video/texture_manager.cpp +++ b/src/video/texture_manager.cpp @@ -17,12 +17,14 @@ #include "video/texture_manager.hpp" #include +#include #include #include "physfs/physfs_sdl.hpp" #include "util/file_system.hpp" #include "util/log.hpp" #include "video/gl/gl_texture.hpp" +#include "video/sdl_surface_ptr.hpp" #include "video/video_systems.hpp" TextureManager::TextureManager() : @@ -63,6 +65,12 @@ TextureManager::get(const std::string& _filename) return texture; } +Texture* +TextureManager::get(const std::string& filename, const Rect& rect) +{ + return 0; +} + void TextureManager::release(Texture* texture) { @@ -85,69 +93,71 @@ TextureManager::remove_texture(GLTexture* texture) #endif Texture* -TextureManager::create_image_texture(const std::string& filename) +TextureManager::create_image_texture(const std::string& filename, const Rect& rect) { - try { - - SDL_Surface* image = IMG_Load_RW(get_physfs_SDLRWops(filename), 1); - if(image == 0) { - std::ostringstream msg; - msg << "Couldn't load image '" << filename << "' :" << SDL_GetError(); - throw std::runtime_error(msg.str()); - } + assert(!"not implemented"); + return 0; +} - Texture* result = 0; - try { - result = VideoSystem::new_texture(image); - result->set_filename(filename); - } catch(...) { - delete result; - SDL_FreeSurface(image); - throw; - } +Texture* +TextureManager::create_image_texture(const std::string& filename) +{ + try + { + return create_image_texture_raw(filename); + } + catch (const std::exception& err) + { + log_warning << "Couldn't load texture '" << filename << "' (now using dummy texture): " << err.what() << std::endl; + Texture* texture = create_dummy_texture(); + return texture; + } +} - SDL_FreeSurface(image); +Texture* +TextureManager::create_image_texture_raw(const std::string& filename) +{ + SDLSurfacePtr image(IMG_Load_RW(get_physfs_SDLRWops(filename), 1)); + if (!image) + { + std::ostringstream msg; + msg << "Couldn't load image '" << filename << "' :" << SDL_GetError(); + throw std::runtime_error(msg.str()); + } + else + { + Texture* result = VideoSystem::new_texture(image.get()); + result->set_filename(filename); return result; + } +} - } catch (const std::runtime_error& err) { - const std::string dummy_texture_fname = "images/engine/missing.png"; - if (filename == dummy_texture_fname) throw err; - - // on error, try loading placeholder file - try { - - Texture* tex = create_image_texture(dummy_texture_fname); - log_warning << "Couldn't load texture '" << filename << "' (now using dummy texture): " << err.what() << std::endl; - return tex; - - } catch (...) { - - // on error (when loading placeholder), try using empty surface - try { - - SDL_Surface* image = SDL_CreateRGBSurface(0, 1024, 1024, 8, 0, 0, 0, 0); - if(image == 0) { - throw err; - } - - Texture* result = 0; - try { - result = VideoSystem::new_texture(image); - result->set_filename("-dummy-texture-.png"); - } catch(...) { - delete result; - SDL_FreeSurface(image); - throw err; - } - - SDL_FreeSurface(image); - log_warning << "Couldn't load texture '" << filename << "' (now using empty one): " << err.what() << std::endl; - return result; - - // on error (when trying to use empty surface), give up - } catch (const std::runtime_error& err) { - throw err; - } +Texture* +TextureManager::create_dummy_texture() +{ + const std::string dummy_texture_fname = "images/engine/missing.png"; + + // on error, try loading placeholder file + try + { + Texture* tex = create_image_texture_raw(dummy_texture_fname); + return tex; + } + catch (const std::exception& err) + { + // on error (when loading placeholder), try using empty surface, + // when that fails to, just give up + SDLSurfacePtr image(SDL_CreateRGBSurface(0, 1024, 1024, 8, 0, 0, 0, 0)); + if (!image) + { + throw err; + } + else + { + Texture* result = VideoSystem::new_texture(image.get()); + result->set_filename("-dummy-texture-.png"); + log_warning << "Couldn't load texture '" << dummy_texture_fname << "' (now using empty one): " << err.what() << std::endl; + return result; } } } diff --git a/src/video/texture_manager.hpp b/src/video/texture_manager.hpp index 496c41543..a9a1fac3c 100644 --- a/src/video/texture_manager.hpp +++ b/src/video/texture_manager.hpp @@ -28,6 +28,7 @@ class Texture; class GLTexture; +class Rect; class TextureManager { @@ -36,6 +37,7 @@ public: ~TextureManager(); Texture* get(const std::string& filename); + Texture* get(const std::string& filename, const Rect& rect); #ifdef HAVE_OPENGL void register_texture(GLTexture* texture); @@ -52,8 +54,16 @@ private: typedef std::map ImageTextures; ImageTextures image_textures; + Texture* create_image_texture(const std::string& filename, const Rect& rect); + + /** on failure a dummy texture is returned and no exception is thrown */ Texture* create_image_texture(const std::string& filename); + /** throw an exception on error */ + Texture* create_image_texture_raw(const std::string& filename); + + Texture* create_dummy_texture(); + #ifdef HAVE_OPENGL typedef std::set Textures; Textures textures;