argh, clean out copy
[supertux.git] / src / unison / src / video / backend / Texture.cpp
1 //          Copyright Timothy Goya 2007.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5
6 #include <unison/video/backend/Texture.hpp>
7 #include <unison/video/Renderers.hpp>
8 #include <unison/video/backend/Renderer.hpp>
9
10 #include <assert.h>
11 #include <algorithm>
12
13 namespace Unison
14 {
15    namespace Video
16    {
17       namespace Backend
18       {
19          std::vector<Texture *> Texture::textures = std::vector<Texture *>();
20          std::map<std::string, TextureID> Texture::named_textures = std::map<std::string, TextureID>();
21
22          Texture::Texture(const Surface &surface) :
23             surface(surface),
24             size(surface.get_size()),
25             refcount(0)
26          {
27             assert(surface.get_size() != Area());
28          }
29
30          Texture::~Texture()
31          {
32          }
33
34          Area Texture::get_size()
35          {
36             return size;
37          }
38
39          void Texture::ref()
40          {
41             refcount++;
42          }
43
44          void Texture::unref()
45          {
46             assert(refcount > 0);
47             refcount--;
48             if(refcount == 0)
49             {
50                std::string name = get_name(get_texture_id(this));
51                *std::find(textures.begin(), textures.end(), this) = 0;
52                if(!name.empty())
53                {
54                   named_textures.erase(name);
55                }
56                delete this;
57             }
58          }
59
60          int Texture::get_refcount()
61          {
62             return refcount;
63          }
64
65          namespace
66          {
67             class TextureSaver
68             {
69                public:
70                   void operator () (Texture *texture)
71                   {
72                      if(texture)
73                      {
74                         texture->save();
75                         surfaces.push_back(texture->get_surface());
76                      }
77                      else
78                      {
79                         surfaces.push_back(Surface());
80                      }
81                      delete texture;
82                   }
83                   std::vector<Surface> surfaces;
84             };
85
86             class TextureLoader
87             {
88                public:
89                   void operator () (Surface surface)
90                   {
91                      if(surface.get_size() != Area())
92                      {
93                         textures.push_back(Renderers::get().get_renderer().create_texture(surface));
94                      }
95                      else
96                      {
97                         textures.push_back(0);
98                      }
99                   }
100                   std::vector<Texture *> textures;
101             };
102          }
103
104          std::vector<Surface> Texture::save_textures()
105          {
106             std::vector<Surface> surfaces = std::for_each(textures.begin(), textures.end(), TextureSaver()).surfaces;
107             textures.clear();
108             return surfaces;
109          }
110
111          void Texture::load_textures(const std::vector<Surface> &surfaces)
112          {
113             assert(textures.empty());
114             textures = std::for_each(surfaces.begin(), surfaces.end(), TextureLoader()).textures;
115          }
116
117          std::map<TextureID, TextureID> Texture::recover_texture_ids()
118          {
119             std::map<TextureID, TextureID> change_map;
120             std::vector<Texture *> new_textures;
121             bool null_texture_found = false;
122             for(std::vector<Texture *>::iterator iter = textures.begin(), end = textures.end();iter != end;++iter)
123             {
124                if(*iter)
125                {
126                   new_textures.push_back(*iter);
127                   if(null_texture_found)
128                   {
129                      change_map[iter - textures.begin()] = new_textures.size() -1;
130                   }
131                }
132                else
133                {
134                   null_texture_found = true;
135                }
136             }
137             textures = new_textures;
138             return change_map;
139          }
140
141          TextureID Texture::get_texture_id(const std::string &filename)
142          {
143             if(named_textures.find(filename) != named_textures.end())
144             {
145                return named_textures[filename];
146             }
147             textures.push_back(Renderers::get().get_renderer().create_texture(Surface(filename)));
148             named_textures[filename] = textures.size() - 1;
149             return textures.size() - 1;
150          }
151
152          TextureID Texture::get_texture_id(const std::string &filename, const Color&colorkey)
153          {
154             if(named_textures.find(filename) != named_textures.end())
155             {
156                return named_textures[filename];
157             }
158             textures.push_back(Renderers::get().get_renderer().create_texture(Surface(filename, colorkey)));
159             named_textures[filename] = textures.size() - 1;
160             return textures.size() - 1;
161          }
162
163          TextureID Texture::get_texture_id(const Surface &surface)
164          {
165             textures.push_back(Renderers::get().get_renderer().create_texture(surface));
166             return textures.size() - 1;
167          }
168
169          TextureID Texture::get_texture_id(Texture *texture)
170          {
171             std::vector<Texture *>::iterator found = std::find(textures.begin(), textures.end(), texture);
172             if(found != textures.end())
173             {
174                return found - textures.begin();
175             }
176             return INVALID_TEXTURE_ID;
177          }
178
179          Texture *Texture::get_texture(TextureID id)
180          {
181             assert(id < textures.size());
182             assert(textures[id]);
183             return textures[id];
184          }
185
186          namespace
187          {
188             bool match_id(std::pair<std::string, TextureID> pair, TextureID id)
189             {
190                return pair.second == id;
191             }
192          }
193
194          std::string Texture::get_name(TextureID id)
195          {
196             if(id == INVALID_TEXTURE_ID)
197             {
198                return std::string();
199             }
200             std::map<std::string, TextureID>::iterator found = std::find_if(named_textures.begin(), named_textures.end(), std::bind2nd(std::ptr_fun(match_id), id));
201             if(found == named_textures.end())
202             {
203                return std::string();
204             }
205             return found->first;
206          }
207       }
208    }
209 }