pointergrid.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. #include "pointergrid.h"
  2. /** Allocates a new, uninitialized PointerGrid. */
  3. PointerGrid * pointergrid_alloc(void) {
  4. return mem_alloc(sizeof(PointerGrid));
  5. }
  6. /** Nulls out all the data in pointergrid. If memdestructor is not NULL,
  7. * it will be called with the old value in the cell before NULL is set.
  8. */
  9. int pointergrid_nullall(PointerGrid * self, MemDestructor * destroy) {
  10. int w, h, x, y;
  11. if (!self) return -1;
  12. if (!self->data) return -1;
  13. w = pointergrid_w(self);
  14. h = pointergrid_h(self);
  15. for(y = 0; y < h ; y++) {
  16. for(x = 0; x < w ; x++) {
  17. void * cell = pointergrid_getraw(self, x, y);
  18. if (destroy && cell) {
  19. destroy(cell);
  20. }
  21. pointergrid_putraw(self, x, y, NULL);
  22. }
  23. }
  24. return 0;
  25. }
  26. /** Cleans up and deinitializes the PointerGrid self,
  27. using the destructor if needed */
  28. PointerGrid * pointergrid_done(PointerGrid * self, MemDestructor * destroy) {
  29. int index;
  30. if(!self) return NULL;
  31. if(!self->data) return self;
  32. for (index = 0; index < self->h; index ++) {
  33. if(self->data[index]) {
  34. /* Clean up elements if needed. */
  35. if(destroy) {
  36. pointergrid_nullall(self, destroy);
  37. }
  38. mem_free(self->data[index]);
  39. }
  40. self->data[index] = NULL;
  41. }
  42. self->w = -1;
  43. self->h = -1;
  44. mem_free(self->data);
  45. return self;
  46. }
  47. /** Calls PointerGrid_done, and then frees the PointerGrid self. Returns NULL. */
  48. PointerGrid * pointergrid_free(PointerGrid * self) {
  49. pointergrid_done(self, NULL);
  50. mem_free(self);
  51. return NULL;
  52. }
  53. /** Returns the width of the PointerGrid. Returns -1 is self isn't propery
  54. * initialized.
  55. */
  56. int pointergrid_w(PointerGrid * self) {
  57. if(!self) return -1;
  58. return self->w;
  59. }
  60. /** Returns the height of the PointerGrid.
  61. * Returns -1 is self isn't propery initialized. */
  62. int pointergrid_h(PointerGrid * self) {
  63. if(!self) return -1;
  64. return self->h;
  65. }
  66. /** Initializes a PointerGrid to be of the given width and height.
  67. * Returns NULL on error, or if h or w are less than 1.
  68. * Returns self on sucess.
  69. */
  70. PointerGrid * pointergrid_init(PointerGrid * self, int w, int h) {
  71. int index;
  72. if(!self) return NULL;
  73. self->w = w;
  74. self->h = h;
  75. self->data = NULL;
  76. if ((self->h <= 0) || (self->w <= 0)) { return NULL; }
  77. // Allocate y dimension
  78. self->data = (intptr_t **) mem_alloc(sizeof(intptr_t *) * self->h);
  79. if(!self->data) return NULL;
  80. // Now allocate the x dimensions.
  81. for (index = 0; index < self->h; index ++) {
  82. self->data[index] = (intptr_t *) mem_alloc(sizeof(intptr_t) * self->w);
  83. if(!self->data[index]) return pointergrid_free(self);
  84. }
  85. return self;
  86. }
  87. /** Allocates a new grid and initializes it. */
  88. PointerGrid * pointergrid_new(int w, int h) {
  89. PointerGrid * self = pointergrid_alloc();
  90. return pointergrid_init(self, w, h);
  91. }
  92. /**
  93. * Return true if the arguments x and or y are out of range, or
  94. * if self itself isn't properly initialized. Return false if OK.
  95. */
  96. int pointergrid_outofrange(PointerGrid * self, int x, int y) {
  97. if(!self) return TRUE;
  98. if(!self->data) return TRUE;
  99. if ((x < 0) || (y < 0)) { return TRUE; }
  100. if ((y >= self->h) || (x >= self->w)) { return TRUE; }
  101. return FALSE;
  102. }
  103. /** Gets an element from the grid. Does no checking whatsoever.
  104. * Use only where the inputs are guaranteed to be valid, where speed is
  105. * of the essence.
  106. */
  107. void * pointergrid_getraw(PointerGrid * self, int x, int y) {
  108. return (void *)self->data[y][x];
  109. }
  110. /** Gets a row of elements from the grid. Does no checking whatsoever.
  111. * Use only where the inputs are guaranteed to be valid, where speed is
  112. * of the essence.
  113. */
  114. void * * pointergrid_rowraw(PointerGrid * self, int y) {
  115. return (void **) self->data[y];
  116. }
  117. /** Gets an element from the grid self.
  118. * If all goes well, this function returns 0, and sets the value to
  119. * (*result).
  120. * If w and h are out of range, or the grid isn't correctly initialized,
  121. * does nothing and returns -1 in stead.
  122. */
  123. int pointergrid_get(PointerGrid * self, int x, int y, void * * result) {
  124. void * * aid;
  125. if(pointergrid_outofrange(self,x,y)) { return -1; }
  126. (*result) = pointergrid_getraw(self,x,y);
  127. return 0;
  128. }
  129. /** Puts an element in the grid self. Does no checking whatsoever.
  130. * Use only where the inputs are guaranteed to be valid, where speed is
  131. * of the essence.
  132. */
  133. void pointergrid_putraw(PointerGrid * self, int x, int y, void * el) {
  134. self->data[y][x] = (intptr_t)el;
  135. }
  136. /** Puts and element into the grid self.
  137. * If all goes well, this function returns 0.
  138. * If w and h are out of range, or the grid isn't correctly initialized,
  139. * does nothing and returns -1 in stead.
  140. */
  141. int pointergrid_put(PointerGrid * self, int x, int y, void * el) {
  142. if(pointergrid_outofrange(self,x,y)) { return -1; }
  143. pointergrid_putraw(self,x,y,el);
  144. return 0;
  145. }
  146. /** Sets and element into the grid self.
  147. * If all goes well, this function returns el.
  148. * If w and h are out of range, or the grid isn't correctly initialized,
  149. * does nothing and returns NULL in stead.
  150. */
  151. void * pointergrid_store(PointerGrid * self, int x, int y, void * el) {
  152. if(pointergrid_outofrange(self,x,y)) { return NULL; }
  153. pointergrid_putraw(self,x,y,el);
  154. return el;
  155. }
  156. /** Fetched an element from the grid self.
  157. * If all goes well, this returns the result.
  158. * If w and h are out of range, or the grid isn't correctly initialized,
  159. * returns NULL.
  160. */
  161. void * pointergrid_fetch(PointerGrid * self, int x, int y) {
  162. if (pointergrid_outofrange(self,x,y)) { return NULL; }
  163. return pointergrid_getraw(self,x,y);
  164. }
  165. /** Copies the data from one grid to the other.
  166. * If the grides are of unequal size, copies the smallest of both
  167. * heights and widths.
  168. * Returns 0 on succes, -1 on error.
  169. */
  170. int pointergrid_copy(PointerGrid * self, PointerGrid * other) {
  171. int ws, hs, wo, ho, w, h, x, y;
  172. if ((!self) || (!other)) return -1;
  173. if ((!self->data) || (!other->data)) return -1;
  174. ws = pointergrid_w(self);
  175. hs = pointergrid_h(self);
  176. wo = pointergrid_w(other);
  177. ho = pointergrid_h(other);
  178. // Copy only smallest of width and height.
  179. w = (ws < wo ? ws : wo);
  180. h = (hs < ho ? hs : ho);
  181. for(y = 0; y < h ; y++) {
  182. for(x = 0; x < w ; x++) {
  183. self->data[y][x] = other->data[y][x];
  184. }
  185. }
  186. return 0;
  187. }
  188. /** Gets an element from the grid. Does no checking whatsoever.
  189. * Use only where the inputs are guaranteed to be valid, where speed is
  190. * of the essence.
  191. */
  192. intptr_t pointergrid_get_raw_int(PointerGrid * self, int x, int y) {
  193. return self->data[y][x];
  194. }
  195. /** Gets a row of elements from the grid. Does no checking whatsoever.
  196. * Use only where the inputs are guaranteed to be valid, where speed is
  197. * of the essence.
  198. */
  199. intptr_t * pointergrid_row_raw_int(PointerGrid * self, int y) {
  200. return self->data[y];
  201. }
  202. /** Gets an integer value from the grid self.
  203. * If all goes well, this function returns 0, and sets the value to
  204. * (*result).
  205. * If w and h are out of range, or the grid isn't correctly initialized,
  206. * does nothing and returns -1 in stead.
  207. */
  208. int pointergrid_get_int(PointerGrid * self, int x, int y, int * result) {
  209. if(pointergrid_outofrange(self,x,y)) { return -1; }
  210. (*result) = (int) pointergrid_get_raw_int(self, x, y);
  211. return 0;
  212. }
  213. /** Puts an integer in the grid self. Does no checking whatsoever.
  214. * Use only where the inputs are guaranteed to be valid, where speed is
  215. * of the essence.
  216. */
  217. void pointergrid_put_raw_int(PointerGrid * self, int x, int y, int el) {
  218. self->data[y][x] = (intptr_t)el;
  219. }
  220. /** Puts an integer into the grid self.
  221. * If all goes well, this function returns 0.
  222. * If w and h are out of range, or the grid isn't correctly initialized,
  223. * does nothing and returns -1 in stead.
  224. */
  225. int pointergrid_put_int(PointerGrid * self, int x, int y, int el) {
  226. if(pointergrid_outofrange(self,x,y)) { return -1; }
  227. pointergrid_put_raw_int(self,x,y,el);
  228. return 0;
  229. }
  230. /** Sets and element into the grid self.
  231. * If all goes well, this function returns el.
  232. * If w and h are out of range, or the grid isn't correctly initialized,
  233. * does nothing and returns 0 in stead.
  234. */
  235. int pointergrid_store_int(PointerGrid * self, int x, int y, int el) {
  236. if(pointergrid_outofrange(self, x, y)) { return 0; }
  237. pointergrid_put_raw_int(self, x, y, el);
  238. return el;
  239. }
  240. /** Fetched an element from the grid self.
  241. * If all goes well, this returns the result.
  242. * If w and h are out of range, or the grid isn't correctly initialized,
  243. * returns 0.
  244. */
  245. int pointergrid_fetch_int(PointerGrid * self, int x, int y) {
  246. if (pointergrid_outofrange(self,x,y)) { return 0; }
  247. return (int) pointergrid_get_raw_int(self,x,y);
  248. }
  249. /** Sets all the pointer grid to a 0 integer. Do NOT do this
  250. * if the pointergrid is intent to store pointer, only if it stores integers.
  251. */
  252. int pointergrid_zero_all(PointerGrid * self) {
  253. int w, h, x, y;
  254. if (!self) return -1;
  255. if (!self->data) return -1;
  256. w = pointergrid_w(self);
  257. h = pointergrid_h(self);
  258. for(y = 0; y < h ; y++) {
  259. for(x = 0; x < w ; x++) {
  260. pointergrid_put_raw_int(self, x, y, 0);
  261. }
  262. }
  263. return 0;
  264. }