00001 #ifndef H_SDLPP_COMMON
00002 #define H_SDLPP_COMMON
00003
00004 #include <iostream>
00005 #include <fstream>
00006 #include <vector>
00007 #include <map>
00008 #include <list>
00009 #include <memory>
00010 #include <set>
00011 #include <iterator>
00012 #include <algorithm>
00013 #include <deque>
00014 #include <sstream>
00015
00016 #include "vec2d.h"
00017
00018 #include <SDL.h>
00019
00020 namespace SDLPP {
00021
00022 const double infinity = 1e300;
00023 typedef std::vector<int> int_vec;
00024 typedef std::vector<char> char_vec;
00025 typedef std::vector<xstring> str_vec;
00026 typedef std::map<int,int> int_map;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 template<class T>
00039 inline xstring str(T t)
00040 {
00041 return xstring(t);
00042 }
00043
00044 template<>
00045 inline xstring str(const char* s)
00046 {
00047 if (!s) return "";
00048 return s;
00049 }
00050
00051 template<class T>
00052 inline T udiff(const T& a, const T& b)
00053 {
00054 return (a>b?a-b:b-a);
00055 }
00056
00057 inline bool is_zero(double value, double eps=0.001)
00058 {
00059 return udiff(value,0.0)<eps;
00060 }
00061
00062 inline int irand(int limit)
00063 {
00064 return (rand() % limit);
00065 }
00066
00067 inline double frand(double limit)
00068 {
00069 return (rand() * limit) / RAND_MAX;
00070 }
00071
00072 template<class T>
00073 class ObjectCreator
00074 {
00075 public:
00076 ObjectCreator(int n) { for(int i=0;i<n;++i) new T; }
00077 };
00078
00079 class Singleton;
00080
00081 class SingletonManager
00082 {
00083 public:
00084 static SingletonManager* instance()
00085 {
00086 static std::auto_ptr<SingletonManager> ptr(new SingletonManager);
00087 return ptr.get();
00088 }
00089
00090 void register_singleton(Singleton* b)
00091 {
00092 m_Singletons.push_back(b);
00093 }
00094
00095 void shutdown();
00096 private:
00097 friend class std::auto_ptr<SingletonManager>;
00098 SingletonManager() {}
00099 ~SingletonManager() { shutdown(); }
00100 SingletonManager(const SingletonManager&) {}
00101
00102 std::list<Singleton*> m_Singletons;
00103 };
00104
00105 class Singleton
00106 {
00107 public:
00108 Singleton() { SingletonManager::instance()->register_singleton(this); }
00109 virtual ~Singleton() {}
00110 virtual void shutdown() = 0;
00111 };
00112
00113 class RefCount
00114 {
00115 int* m_Counter;
00116 public:
00117 RefCount() : m_Counter(new int(1)) {}
00118 RefCount(const RefCount& rhs) : m_Counter(rhs.m_Counter) { addref(); }
00119 RefCount& operator= (const RefCount& rhs)
00120 {
00121 subref();
00122 m_Counter=rhs.m_Counter;
00123 addref();
00124 return *this;
00125 }
00126 virtual ~RefCount() { subref(true); }
00127
00128 protected:
00129 virtual void destroy() = 0;
00130 bool is_last_copy() const { return getref()==1; }
00131 int getref() const { return *m_Counter; }
00132 void addref()
00133 {
00134 ++*m_Counter;
00135 }
00136 void subref(bool final=false)
00137 {
00138 if (--*m_Counter == 0)
00139 {
00140 if (!final) destroy();
00141 delete m_Counter;
00142 m_Counter=0;
00143 }
00144 }
00145 };
00146
00147 class ResourceFile;
00148
00149 template<class T>
00150 class Loader
00151 {
00152 public:
00153 virtual ~Loader() {}
00154 virtual void load(T&,const xstring& name, ResourceFile* rf) = 0;
00155 };
00156
00162 template<class T>
00163 class Cache : public Singleton
00164 {
00165 Loader<T>& m_Loader;
00166 public:
00167 Cache(Loader<T>& ldr) : m_Loader(ldr) {}
00168 virtual ~Cache() {}
00169
00170 virtual void shutdown()
00171 {
00172 clear();
00173 }
00174
00175 T& get(const xstring& name, ResourceFile* rf=0)
00176 {
00177 iterator it=m_Objects.find(name);
00178 if (it==m_Objects.end())
00179 {
00180 T& obj=m_Objects[name];
00181 m_Loader.load(obj,name,rf);
00182 return obj;
00183 }
00184 return it->second;
00185 }
00186
00187 T& insert(const xstring& name, const T& obj)
00188 {
00189 return m_Objects[name]=obj;
00190 }
00191
00192 void unload(const xstring& name)
00193 {
00194 m_Objects.erase(name);
00195 }
00196
00197 void clear()
00198 {
00199 m_Objects.clear();
00200 }
00201 private:
00202 typedef std::map<xstring,T> obj_map;
00203 obj_map m_Objects;
00204 typedef typename obj_map::iterator iterator;
00205 };
00206
00207 template<class T>
00208 class Accumulator
00209 {
00210 typedef std::vector<T> Seq;
00211 Seq m_Data;
00212 int m_Valid;
00213 int m_Position;
00214 public:
00215 typedef typename Seq::const_iterator const_iterator;
00216 const_iterator begin() const { return m_Data.begin(); }
00217 const_iterator end() const { return m_Data.ends(); }
00218
00219 Accumulator(int size) : m_Data(size), m_Valid(0), m_Position(0) {}
00220
00221 void reset()
00222 {
00223 m_Valid=0;
00224 m_Position=0;
00225 }
00226
00227 void flush()
00228 {
00229 if (m_Valid<size())
00230 {
00231 typename Seq::iterator it=m_Data.begin();
00232 std::advance(it,m_Valid);
00233 std::fill(it,m_Data.end(),0);
00234 }
00235 }
00236
00237 void start_sequence()
00238 {
00239 m_Position=0;
00240 }
00241
00242 template<class II>
00243 int acc_data(II b, II e)
00244 {
00245 typename Seq::iterator oi=m_Data.begin();
00246 std::advance(oi,m_Position);
00247 int n=0;
00248 for(;b!=e && m_Position<m_Valid;++b,++m_Position,++oi,++n)
00249 *oi += *b;
00250 for(;b!=e && m_Valid<size();++b,++m_Position,++m_Valid,++oi,++n)
00251 *oi=*b;
00252 return n;
00253 }
00254
00255 int size() const { return m_Data.size(); }
00256 void resize(int new_size) { m_Data.resize(new_size); }
00257 };
00258
00259 template<class T>
00260 class BufferReader : public std::iterator<std::random_access_iterator_tag,T>
00261 {
00262 typedef BufferReader<T> self;
00263
00264 T* m_Buffer;
00265 int m_Length;
00266 int m_Position;
00267 bool m_Loop;
00268 public:
00269 BufferReader(T* buffer, int length, int pos, bool loop)
00270 : m_Buffer(buffer), m_Length(length), m_Position(pos), m_Loop(loop) {}
00271
00272 const T& operator* () { return m_Buffer[m_Position]; }
00273 self& operator++ () { ++m_Position; if (m_Position==m_Length && m_Loop) m_Position=0; return *this; }
00274 self operator++(int) { self br(m_Buffer,m_Length,m_Position,m_Loop); ++*this; return br; }
00275 bool operator==(const self& rhs) const { return m_Buffer==rhs.m_Buffer && m_Length==rhs.m_Length && m_Position==rhs.m_Position && m_Loop==rhs.m_Loop; }
00276 bool operator!=(const self& rhs) const { return !(*this==rhs); }
00277
00278 self begin() const { return self(m_Buffer,m_Length,0,m_Loop); }
00279 self current() const { return self(m_Buffer,m_Length,m_Position,m_Loop); }
00280 self end() const { return self(m_Buffer,m_Length,m_Loop?m_Length+1:m_Length,m_Loop); }
00281
00282 void advance(int n)
00283 {
00284 m_Position+=n;
00285 while (m_Position>=m_Length && m_Loop) m_Position-=m_Length;
00286 }
00287
00288 template<class OI>
00289 int copy(OI o, int n)
00290 {
00291 if (!m_Loop)
00292 {
00293 int act=Min(m_Length-m_Position,n);
00294 std::copy(m_Buffer+m_Position,m_Buffer+m_Position+act,o);
00295 m_Position+=act;
00296 return act;
00297 }
00298 else
00299 {
00300 int total=0;
00301 while (total<n)
00302 {
00303 int act=Min(m_Length-m_Position,n-total);
00304 std::copy(m_Buffer+m_Position,m_Buffer+m_Position+act,o);
00305 std::advance(o,act);
00306 m_Position+=act;
00307 total+=act;
00308 if (m_Position>=m_Length) m_Position=0;
00309 }
00310 return n;
00311 }
00312 }
00313
00314 int get_position() const { return m_Position; }
00315 };
00316
00317 class PropertyBag
00318 {
00319 typedef std::map<xstring,xstring> properties_map;
00320 typedef properties_map::iterator iterator;
00321 typedef properties_map::const_iterator const_iterator;
00322
00323 properties_map m_Properties;
00324 xstring m_Empty;
00325 public:
00326 virtual ~PropertyBag() {}
00327
00328 xstring& operator[] (const xstring& name)
00329 {
00330 return m_Properties[name];
00331 }
00332
00333 template<class T>
00334 void set(const xstring& name, const T& value)
00335 {
00336 std::ostringstream os;
00337 os << value;
00338 m_Properties[name]=os.str();
00339 }
00340
00341 const xstring& get(const xstring& name) const
00342 {
00343 const_iterator it=m_Properties.find(name);
00344 if (it==m_Properties.end()) return m_Empty;
00345 return it->second;
00346 }
00347
00348 int iget(const xstring& name) const
00349 {
00350 return atoi(get(name).c_str());
00351 }
00352
00353 double dget(const xstring& name) const
00354 {
00355 return atof(get(name).c_str());
00356 }
00357 };
00358
00359 class GameView
00360 {
00361 iRect2 m_ScreenView;
00362 iVec2 m_Offset;
00363 public:
00364 GameView(int w=0, int h=0)
00365 : m_ScreenView(iVec2(0,0),iVec2(w,h)),
00366 m_Offset(0,0)
00367 {
00368 }
00369
00370 void set_screen_view(const iRect2& r) { m_ScreenView=r; }
00371 void set_offset(const iVec2& v) { m_Offset=v; }
00372 void delta_offset(const iVec2& delta) { m_Offset+=delta; }
00373
00374 const iVec2& get_2D_offset() const
00375 {
00376 return m_Offset;
00377 }
00378
00379 const iRect2& get_2D_view() const
00380 {
00381
00382
00383 return m_ScreenView;
00384 }
00385 };
00386
00387 class GameObject
00388 {
00389 public:
00390 virtual ~GameObject() {}
00391 virtual bool is_volatile() const { return false; }
00392
00397 virtual bool advance(int dt) = 0;
00398 virtual void render(GameView& view) = 0;
00399 };
00400
00401 #define THROW(x) { std::ostringstream os; os << __FILE__ << ":" << __LINE__ << " - " << x; throw os.str(); }
00402
00403 }
00404
00405 #endif // H_SDLPP_COMMON
00406
00407