Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Grid.h
Go to the documentation of this file.
1 /* Copyright (C) 2013 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_GRID
19 #define INCLUDED_GRID
20 
21 #include <cstring>
22 
23 #ifdef NDEBUG
24 #define GRID_BOUNDS_DEBUG 0
25 #else
26 #define GRID_BOUNDS_DEBUG 1
27 #endif
28 
29 /**
30  * Basic 2D array, intended for storing tile data, plus support for lazy updates
31  * by ICmpObstructionManager.
32  * @c T must be a POD type that can be initialised with 0s.
33  */
34 template<typename T>
35 class Grid
36 {
37 public:
38  Grid() : m_W(0), m_H(0), m_Data(NULL), m_DirtyID(0)
39  {
40  }
41 
42  Grid(u16 w, u16 h) : m_W(w), m_H(h), m_Data(NULL), m_DirtyID(0)
43  {
44  if (m_W || m_H)
45  m_Data = new T[m_W * m_H];
46  reset();
47  }
48 
49  Grid(const Grid& g)
50  {
51  m_Data = NULL;
52  *this = g;
53  }
54 
55  Grid& operator=(const Grid& g)
56  {
57  if (this != &g)
58  {
59  m_W = g.m_W;
60  m_H = g.m_H;
61  m_DirtyID = g.m_DirtyID;
62  delete[] m_Data;
63  if (g.m_Data)
64  {
65  m_Data = new T[m_W * m_H];
66  memcpy(m_Data, g.m_Data, m_W*m_H*sizeof(T));
67  }
68  else
69  m_Data = NULL;
70  }
71  return *this;
72  }
73 
75  {
76  delete[] m_Data;
77  }
78 
79  void reset()
80  {
81  if (m_Data)
82  memset(m_Data, 0, m_W*m_H*sizeof(T));
83  }
84 
85  void set(int i, int j, const T& value)
86  {
87 #if GRID_BOUNDS_DEBUG
88  ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
89 #endif
90  m_Data[j*m_W + i] = value;
91  }
92 
93  T& get(int i, int j) const
94  {
95 #if GRID_BOUNDS_DEBUG
96  ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
97 #endif
98  return m_Data[j*m_W + i];
99  }
100 
103 
104  size_t m_DirtyID; // if this is < the id maintained by ICmpObstructionManager then it needs to be updated
105 };
106 
107 /**
108  * Similar to Grid, except optimised for sparse usage (the grid is subdivided into
109  * buckets whose contents are only initialised on demand, to save on memset cost).
110  */
111 template<typename T>
113 {
115 
116  enum { BucketBits = 4, BucketSize = 1 << BucketBits };
117 
118  T* GetBucket(int i, int j)
119  {
120  size_t b = (j >> BucketBits) * m_BW + (i >> BucketBits);
121  if (!m_Data[b])
122  {
123  m_Data[b] = new T[BucketSize*BucketSize];
124  memset(m_Data[b], 0, BucketSize*BucketSize*sizeof(T));
125  }
126  return m_Data[b];
127  }
128 
129 public:
130  SparseGrid(u16 w, u16 h) : m_W(w), m_H(h), m_DirtyID(0)
131  {
132  ENSURE(m_W && m_H);
133 
134  m_BW = (u16)((m_W + BucketSize-1) >> BucketBits);
135  m_BH = (u16)((m_H + BucketSize-1) >> BucketBits);
136 
137  m_Data = new T*[m_BW*m_BH];
138  memset(m_Data, 0, m_BW*m_BH*sizeof(T*));
139  }
140 
142  {
143  reset();
144  delete[] m_Data;
145  }
146 
147  void reset()
148  {
149  for (size_t i = 0; i < (size_t)(m_BW*m_BH); ++i)
150  delete[] m_Data[i];
151 
152  memset(m_Data, 0, m_BW*m_BH*sizeof(T*));
153  }
154 
155  void set(int i, int j, const T& value)
156  {
157 #if GRID_BOUNDS_DEBUG
158  ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
159 #endif
160  GetBucket(i, j)[(j % BucketSize)*BucketSize + (i % BucketSize)] = value;
161  }
162 
163  T& get(int i, int j)
164  {
165 #if GRID_BOUNDS_DEBUG
166  ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
167 #endif
168  return GetBucket(i, j)[(j % BucketSize)*BucketSize + (i % BucketSize)];
169  }
170 
174 
175  size_t m_DirtyID; // if this is < the id maintained by ICmpObstructionManager then it needs to be updated
176 };
177 
178 #endif // INCLUDED_GRID
Grid & operator=(const Grid &g)
Definition: Grid.h:55
Similar to Grid, except optimised for sparse usage (the grid is subdivided into buckets whose content...
Definition: Grid.h:112
Grid()
Definition: Grid.h:38
u16 m_BH
Definition: Grid.h:172
u16 m_H
Definition: Grid.h:101
Grid(u16 w, u16 h)
Definition: Grid.h:42
Basic 2D array, intended for storing tile data, plus support for lazy updates by ICmpObstructionManag...
size_t m_DirtyID
Definition: Grid.h:104
void reset()
Definition: Grid.h:147
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
SparseGrid(u16 w, u16 h)
Definition: Grid.h:130
void reset()
Definition: Grid.h:79
NONCOPYABLE(SparseGrid)
~Grid()
Definition: Grid.h:74
~SparseGrid()
Definition: Grid.h:141
#define T(string_literal)
Definition: secure_crt.cpp:70
u16 m_W
Definition: Grid.h:171
#define u16
Definition: types.h:40
T * m_Data
Definition: Grid.h:102
T ** m_Data
Definition: Grid.h:173
void set(int i, int j, const T &value)
Definition: Grid.h:155
u16 m_H
Definition: Grid.h:171
u16 m_W
Definition: Grid.h:101
size_t m_DirtyID
Definition: Grid.h:175
Grid(const Grid &g)
Definition: Grid.h:49
u16 m_BW
Definition: Grid.h:172
void set(int i, int j, const T &value)
Definition: Grid.h:85
T * GetBucket(int i, int j)
Definition: Grid.h:118