Added TexturePtr
authorIngo Ruhnke <grumbel@gmx.de>
Mon, 14 Dec 2009 10:26:09 +0000 (10:26 +0000)
committerIngo Ruhnke <grumbel@gmx.de>
Mon, 14 Dec 2009 10:26:09 +0000 (10:26 +0000)
SVN-Revision: 6217

13 files changed:
src/video/gl/gl_lightmap.cpp
src/video/gl/gl_lightmap.hpp
src/video/gl/gl_renderer.cpp
src/video/sdl/sdl_lightmap.cpp
src/video/sdl/sdl_renderer.cpp
src/video/surface.cpp
src/video/surface.hpp
src/video/texture.hpp
src/video/texture_manager.cpp
src/video/texture_manager.hpp
src/video/texture_ptr.hpp [new file with mode: 0644]
src/video/video_systems.cpp
src/video/video_systems.hpp

index 08cfa99..57b9730 100644 (file)
@@ -142,19 +142,15 @@ GLLightmap::GLLightmap() :
   unsigned int width = next_po2(lightmap_width);
   unsigned int height = next_po2(lightmap_height);
 
-  lightmap = new GLTexture(width, height);
+  lightmap.reset(new GLTexture(width, height));
 
   lightmap_uv_right = static_cast<float>(lightmap_width) / static_cast<float>(width);
   lightmap_uv_bottom = static_cast<float>(lightmap_height) / static_cast<float>(height);
-  texture_manager->register_texture(lightmap);
+  texture_manager->register_texture(lightmap.get());
 }
 
 GLLightmap::~GLLightmap()
 {
-  if(texture_manager){
-    texture_manager->remove_texture(lightmap);
-  }
-  delete lightmap;
 }
 
 void
@@ -199,12 +195,10 @@ GLLightmap::end_draw()
 void
 GLLightmap::do_draw()
 {
-  const GLTexture* texture = lightmap;
-
   // multiple the lightmap with the framebuffer
   glBlendFunc(GL_DST_COLOR, GL_ZERO);
 
-  glBindTexture(GL_TEXTURE_2D, texture->get_handle());
+  glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
 
   float vertices[] = {
     0, 0,
@@ -231,7 +225,7 @@ void
 GLLightmap::draw_surface(const DrawingRequest& request)
 {
   const Surface* surface = (const Surface*) request.request_data;
-  GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+  boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
   GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
 
   glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
@@ -255,7 +249,7 @@ GLLightmap::draw_surface_part(const DrawingRequest& request)
   const SurfacePartRequest* surfacepartrequest
     = (SurfacePartRequest*) request.request_data;
   const Surface* surface = surfacepartrequest->surface;
-  GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+  boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
   GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
 
   float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
index f6af11d..10ee546 100644 (file)
@@ -43,7 +43,7 @@ private:
   static const int LIGHTMAP_DIV = 5;
 
   SDL_Surface* screen;
-  GLTexture* lightmap;
+  boost::shared_ptr<GLTexture> lightmap;
   int lightmap_width;
   int lightmap_height;
   float lightmap_uv_right;
index 9c88cd3..5b62d2d 100644 (file)
@@ -192,7 +192,7 @@ void
 GLRenderer::draw_surface(const DrawingRequest& request)
 {
   const Surface* surface = (const Surface*) request.request_data;
-  GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+  boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
   GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
 
   glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
@@ -216,7 +216,7 @@ GLRenderer::draw_surface_part(const DrawingRequest& request)
   const SurfacePartRequest* surfacepartrequest
     = (SurfacePartRequest*) request.request_data;
   const Surface* surface = surfacepartrequest->surface;
-  GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+  boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
   GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
 
   float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
index 4c6234d..b523fbc 100644 (file)
@@ -451,7 +451,7 @@ SDLLightmap::draw_surface(const DrawingRequest& request)
   //FIXME: support parameters request.alpha, request.angle, request.blend
  
   const Surface* surface = (const Surface*) request.request_data;
-  SDLTexture *sdltexture = dynamic_cast<SDLTexture *>(surface->get_texture());
+  boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
   SDLSurfaceData *surface_data = reinterpret_cast<SDLSurfaceData *>(surface->get_surface_data());
 
   DrawingEffect effect = request.drawing_effect;
@@ -478,7 +478,7 @@ SDLLightmap::draw_surface_part(const DrawingRequest& request)
     = (SurfacePartRequest*) request.request_data;
 
   const Surface* surface = surfacepartrequest->surface;
-  SDLTexture *sdltexture = dynamic_cast<SDLTexture *>(surface->get_texture());
+  boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
 
   DrawingEffect effect = request.drawing_effect;
   if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
index dc4b738..d769dc5 100644 (file)
@@ -169,7 +169,7 @@ SDLRenderer::draw_surface(const DrawingRequest& request)
 {
   //FIXME: support parameters request.alpha, request.angle, request.blend
   const Surface* surface = (const Surface*) request.request_data;
-  SDLTexture *sdltexture = dynamic_cast<SDLTexture *>(surface->get_texture());
+  boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
   SDLSurfaceData *surface_data = reinterpret_cast<SDLSurfaceData *>(surface->get_surface_data());
 
   DrawingEffect effect = request.drawing_effect;
@@ -238,7 +238,7 @@ SDLRenderer::draw_surface_part(const DrawingRequest& request)
     = (SurfacePartRequest*) request.request_data;
 
   const Surface* surface = surfacepartrequest->surface;
-  SDLTexture *sdltexture = dynamic_cast<SDLTexture*>(surface->get_texture());
+  boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
 
   DrawingEffect effect = request.drawing_effect;
   if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
index 98bd868..f9eb560 100644 (file)
@@ -43,7 +43,6 @@ Surface::Surface(const std::string& file) :
            texture->get_image_height())),
   flipx(false)
 {
-  texture->ref();
   surface_data = VideoSystem::new_surface_data(*this);
 }
 
@@ -53,7 +52,6 @@ Surface::Surface(const std::string& file, const Rect& rect_) :
   rect(0, 0, Size(rect_.get_width(), rect_.get_height())),
   flipx(false)
 {
-  texture->ref();
   surface_data = VideoSystem::new_surface_data(*this);
 }
 
@@ -63,14 +61,12 @@ Surface::Surface(const Surface& rhs) :
   rect(rhs.rect),
   flipx(false)
 {
-  texture->ref();
   surface_data = VideoSystem::new_surface_data(*this);
 }
 
 Surface::~Surface()
 {
   VideoSystem::free_surface_data(surface_data);
-  texture->unref();
 }
 
 SurfacePtr
@@ -91,7 +87,7 @@ bool Surface::get_flipx() const
   return flipx;
 }
 
-Texture
+TexturePtr
 Surface::get_texture() const
 {
   return texture;
index 9523efd..0728081 100644 (file)
@@ -23,8 +23,8 @@
 #include "math/vector.hpp"
 #include "math/rect.hpp"
 #include "video/surface_ptr.hpp"
+#include "video/texture_ptr.hpp"
 
-class Texture;
 class SurfaceData;
 
 /** A rectangular image.  The class basically holds a reference to a
@@ -37,7 +37,7 @@ public:
   static SurfacePtr create(const std::string& file, const Rect& rect);
 
 private:
-  Texture* texture;
+  TexturePtr texture;
   SurfaceData* surface_data;
   Rect rect;
   bool flipx;
@@ -56,7 +56,7 @@ public:
   void hflip();
   bool get_flipx() const;
 
-  Texture *get_texture() const;
+  TexturePtr get_texture() const;
   SurfaceData* get_surface_data() const;
   int get_x() const;
   int get_y() const;
index 74710bd..a4beb86 100644 (file)
@@ -44,12 +44,15 @@ enum DrawingEffect {
 class Texture
 {
 protected:
-  int refcount;
   std::string filename;
 
 public:
-  Texture() : refcount(0), filename() {}
-  virtual ~Texture() {}
+  Texture() : filename() {}
+  virtual ~Texture() 
+  {
+    if (texture_manager)
+      texture_manager->release(this);
+  }
 
   virtual unsigned int get_texture_width() const = 0;
   virtual unsigned int get_texture_height() const = 0;
@@ -66,25 +69,6 @@ public:
     this->filename = filename;
   }
 
-  void ref()
-  {
-    refcount++;
-  }
-
-  void unref()
-  {
-    assert(refcount > 0);
-    refcount--;
-    if(refcount == 0)
-      release();
-  }
-
-private:
-  void release()
-  {
-    texture_manager->release(this);
-  }
-
 private:
   Texture(const Texture&);
   Texture& operator=(const Texture&);
index 3831132..a7c32e4 100644 (file)
@@ -39,26 +39,27 @@ TextureManager::TextureManager() :
 
 TextureManager::~TextureManager()
 {
-  for(ImageTextures::iterator i = image_textures.begin();
-      i != image_textures.end(); ++i) {
-    if(i->second == NULL)
-      continue;
-    log_warning << "Texture '" << i->first << "' not freed" << std::endl;
-    delete i->second;
+  for(ImageTextures::iterator i = image_textures.begin(); i != image_textures.end(); ++i)
+  {
+    if(i->second.lock())
+    {
+      log_warning << "Texture '" << i->first << "' not freed" << std::endl;
+    }
   }
+  image_textures.clear();
 }
 
-Texture*
+TexturePtr
 TextureManager::get(const std::string& _filename)
 {
   std::string filename = FileSystem::normalize(_filename);
   ImageTextures::iterator i = image_textures.find(filename);
 
-  Texture* texture = NULL;
+  TexturePtr texture;
   if(i != image_textures.end())
-    texture = i->second;
+    texture = i->second.lock();
 
-  if(texture == NULL) {
+  if(!texture) {
     texture = create_image_texture(filename);
     image_textures[filename] = texture;
   }
@@ -66,7 +67,7 @@ TextureManager::get(const std::string& _filename)
   return texture;
 }
 
-Texture*
+TexturePtr
 TextureManager::get(const std::string& filename, const Rect& rect)
 {
   // FIXME: implement caching
@@ -77,7 +78,6 @@ void
 TextureManager::release(Texture* texture)
 {
   image_textures.erase(texture->get_filename());
-  delete texture;
 }
 
 #ifdef HAVE_OPENGL
@@ -94,7 +94,7 @@ TextureManager::remove_texture(GLTexture* texture)
 }
 #endif
 
-Texture*
+TexturePtr
 TextureManager::create_image_texture(const std::string& filename, const Rect& rect)
 {
   try 
@@ -104,12 +104,12 @@ TextureManager::create_image_texture(const std::string& filename, const Rect& re
   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();
+    TexturePtr texture = create_dummy_texture();
     return texture;
   }
 }
 
-Texture*
+TexturePtr
 TextureManager::create_image_texture_raw(const std::string& filename, const Rect& rect)
 {
   SDLSurfacePtr image(IMG_Load_RW(get_physfs_SDLRWops(filename), 1));
@@ -143,14 +143,14 @@ TextureManager::create_image_texture_raw(const std::string& filename, const Rect
         SDL_SetColors(subimage.get(), image->format->palette->colors, 0, image->format->palette->ncolors);
       }
 
-      Texture* result = VideoSystem::new_texture(subimage.get());
+      TexturePtr result = VideoSystem::new_texture(subimage.get());
       result->set_filename(filename);
       return result;
     }
   }
 }
 
-Texture*
+TexturePtr
 TextureManager::create_image_texture(const std::string& filename)
 {
   try 
@@ -160,12 +160,12 @@ TextureManager::create_image_texture(const std::string& 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();
+    TexturePtr texture = create_dummy_texture();
     return texture;
   }
 }
 
-Texture*
+TexturePtr
 TextureManager::create_image_texture_raw(const std::string& filename)
 {
   SDLSurfacePtr image(IMG_Load_RW(get_physfs_SDLRWops(filename), 1));
@@ -177,13 +177,13 @@ TextureManager::create_image_texture_raw(const std::string& filename)
   }
   else
   {
-    Texture* result = VideoSystem::new_texture(image.get());
+    TexturePtr result = VideoSystem::new_texture(image.get());
     result->set_filename(filename);
     return result;
   }
 }
 
-Texture*
+TexturePtr
 TextureManager::create_dummy_texture()
 {
   const std::string dummy_texture_fname = "images/engine/missing.png";
@@ -191,7 +191,7 @@ TextureManager::create_dummy_texture()
   // on error, try loading placeholder file
   try 
   {
-    Texture* tex = create_image_texture_raw(dummy_texture_fname);
+    TexturePtr tex = create_image_texture_raw(dummy_texture_fname);
     return tex;
   }
   catch (const std::exception& err) 
@@ -205,7 +205,7 @@ TextureManager::create_dummy_texture()
     }
     else
     {
-      Texture* result = VideoSystem::new_texture(image.get());
+      TexturePtr 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;
@@ -232,7 +232,7 @@ TextureManager::save_textures()
   }
   for(ImageTextures::iterator i = image_textures.begin();
       i != image_textures.end(); ++i) {
-    save_texture(dynamic_cast<GLTexture *>(i->second));
+    save_texture(dynamic_cast<GLTexture*>(i->second.lock().get()));
   }
 }
 
index cf7f940..e88223d 100644 (file)
 #include <set>
 #include <string>
 #include <vector>
+#include <boost/weak_ptr.hpp>
 
 #include "video/glutil.hpp"
+#include "video/texture_ptr.hpp"
 
 class Texture;
 class GLTexture;
@@ -36,8 +38,8 @@ public:
   TextureManager();
   ~TextureManager();
 
-  Texture* get(const std::string& filename);
-  Texture* get(const std::string& filename, const Rect& rect);
+  TexturePtr get(const std::string& filename);
+  TexturePtr get(const std::string& filename, const Rect& rect);
 
 #ifdef HAVE_OPENGL
   void register_texture(GLTexture* texture);
@@ -51,19 +53,19 @@ private:
   friend class Texture;
   void release(Texture* texture);
 
-  typedef std::map<std::string, Texture*> ImageTextures;
+  typedef std::map<std::string, boost::weak_ptr<Texture> > ImageTextures;
   ImageTextures image_textures;
 
-  Texture* create_image_texture(const std::string& filename, const Rect& rect);
+  TexturePtr 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);
+  TexturePtr create_image_texture(const std::string& filename);
 
   /** throw an exception on error */
-  Texture* create_image_texture_raw(const std::string& filename);
-  Texture* create_image_texture_raw(const std::string& filename, const Rect& rect);
+  TexturePtr create_image_texture_raw(const std::string& filename);
+  TexturePtr create_image_texture_raw(const std::string& filename, const Rect& rect);
 
-  Texture* create_dummy_texture();
+  TexturePtr create_dummy_texture();
   
 #ifdef HAVE_OPENGL
   typedef std::set<GLTexture*> Textures;
diff --git a/src/video/texture_ptr.hpp b/src/video/texture_ptr.hpp
new file mode 100644 (file)
index 0000000..e590449
--- /dev/null
@@ -0,0 +1,27 @@
+//  SuperTux
+//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
+//
+//  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 <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_TEXTURE_PTR_HPP
+#define HEADER_SUPERTUX_VIDEO_TEXTURE_PTR_HPP
+
+#include <boost/shared_ptr.hpp>
+
+class Texture;
+typedef boost::shared_ptr<Texture> TexturePtr;
+
+#endif
+
+/* EOF */
index ca86eb1..b73996c 100644 (file)
@@ -90,29 +90,29 @@ VideoSystem::new_lightmap()
   }
 }
 
-Texture*
+TexturePtr
 VideoSystem::new_texture(SDL_Surface *image)
 {
   switch(g_config->video)
   {
     case AUTO_VIDEO:
 #ifdef HAVE_OPENGL
-      return new GLTexture(image);
+      return TexturePtr(new GLTexture(image));
 #else
-      return new SDLTexture(image);
+      return TexturePtr(new SDLTexture(image));
 #endif
 #ifdef HAVE_OPENGL
     case OPENGL:
-      return new GLTexture(image);
+      return TexturePtr(new GLTexture(image));
 #endif
     case PURE_SDL:
-      return new SDLTexture(image);
+      return TexturePtr(new SDLTexture(image));
     default:
       assert(0 && "invalid video system in config");
 #ifdef HAVE_OPENGL
-      return new GLTexture(image);
+      return TexturePtr(new GLTexture(image));
 #else
-      return new SDLTexture(image);
+      return TexturePtr(new SDLTexture(image));
 #endif
   }
 }
index a09cd76..e82ceda 100644 (file)
 #include <SDL.h>
 #include <string>
 
+#include "video/texture_ptr.hpp"
+
 class Renderer;
 class Lightmap;
-class Texture;
 class Surface;
 class SurfaceData;
 
@@ -41,7 +42,7 @@ public:
 public:
   static Renderer* new_renderer();
   static Lightmap* new_lightmap();
-  static Texture*  new_texture(SDL_Surface *image);
+  static TexturePtr   new_texture(SDL_Surface *image);
   static SurfaceData* new_surface_data(const Surface &surface);
   static void      free_surface_data(SurfaceData* surface_data);