Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Map.h 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : Freyja
  5. * Author : Mongoose
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : Map
  9. * License : No use w/o permission (C) 2000-2002 Mongoose
  10. * Comments: mtk Template list
  11. *
  12. * This file was generated using Mongoose's C++
  13. * template generator script. <stu7440@westga.edu>
  14. *
  15. *-- History ------------------------------------------------
  16. *
  17. * 2002.02.19:
  18. * Mongoose - Using RBTree and list overlay for faster access
  19. *
  20. * Access: O(1)/O(n)/O(logn) ?
  21. * Insert: O(nlogn) ?
  22. * Remove: O(nlogn) ?
  23. *
  24. * 2002.02.16:
  25. * Mongoose - Binary tree overlay started... at 0300 /_\ Zzzz
  26. *
  27. * 2002.02.01:
  28. * Mongoose - Dug out of cobwebs and fixed up
  29. * Yes, I believe in code reuse! =)
  30. *
  31. * 2000.10.26:
  32. * Mongoose - Created
  33. ================================================================*/
  34. #ifndef _MAP_H_
  35. #define _MAP_H_
  36. #include <stdlib.h>
  37. #include <stdio.h>
  38. #include <Tree.h>
  39. #ifdef DEBUG_MEMORY
  40. #include <memory_test.h>
  41. #endif
  42. template <class K, class D> class MapNode
  43. {
  44. public:
  45. MapNode(K key, D data)
  46. {
  47. _data = data;
  48. _key = key;
  49. _next = NULL;
  50. }
  51. ~MapNode()
  52. {
  53. }
  54. void Key(K key)
  55. {
  56. _key = key;
  57. }
  58. K Key()
  59. {
  60. return _key;
  61. }
  62. void Data(D data)
  63. {
  64. _data = data;
  65. }
  66. D Data()
  67. {
  68. return _data;
  69. }
  70. MapNode<K, D> *Next()
  71. {
  72. return _next;
  73. }
  74. void Next(MapNode<K, D> *next)
  75. {
  76. _next = next;
  77. }
  78. private:
  79. MapNode<K, D> *_next;
  80. K _key;
  81. D _data;
  82. };
  83. template <class K, class D> class Map
  84. {
  85. public:
  86. Map()
  87. {
  88. UnSetError();
  89. _num_items = 0;
  90. _head = NULL;
  91. _current = NULL;
  92. _cache = NULL;
  93. }
  94. ~Map()
  95. {
  96. Clear();
  97. }
  98. void Clear()
  99. {
  100. UnSetError();
  101. _num_items = 0;
  102. _cache = NULL;
  103. while (_head)
  104. {
  105. _current = _head;
  106. _head = _head->Next();
  107. delete _current;
  108. }
  109. _tree.Clear();
  110. }
  111. void SetError()
  112. {
  113. _error = true;
  114. }
  115. void UnSetError()
  116. {
  117. _error = false;
  118. }
  119. bool GetError()
  120. {
  121. return _error;
  122. }
  123. D FindDataByKey(K key)
  124. {
  125. MapNode<K, D> *current = NULL;
  126. MapNode<K, D> *next = NULL;
  127. if (_head)
  128. {
  129. UnSetError();
  130. if (_cache)
  131. {
  132. next = _cache->Next();
  133. }
  134. // Mongoose 2002.02.19, Optimize for sequential searches
  135. if (next && key == next->Key())
  136. {
  137. current = next;
  138. }
  139. else // Mongoose 2002.02.19, Use search algorithm otherwise
  140. {
  141. current = _tree.SearchByKey(key, &_error);
  142. if (_error)
  143. return false;
  144. }
  145. if (current)
  146. {
  147. _cache = _current = current;
  148. return current->Data();
  149. }
  150. }
  151. SetError();
  152. return 0;
  153. }
  154. D operator [] (K key)
  155. {
  156. return FindDataByKey(key);
  157. }
  158. K FindKeyByData(D data)
  159. {
  160. MapNode<K, D> *current = _head;
  161. MapNode<K, D> *last = NULL;
  162. UnSetError();
  163. while (current)
  164. {
  165. // Found
  166. if (current->Data() == data)
  167. {
  168. _cache = current;
  169. return current->Key();
  170. }
  171. last = current;
  172. current = current->Next();
  173. }
  174. SetError();
  175. return 0;
  176. }
  177. D getCache()
  178. {
  179. if (_cache == 0x0)
  180. {
  181. printf("Map::getCache> Bad request - should segfault\n");
  182. }
  183. return _cache->Data();
  184. }
  185. bool findKey(K key)
  186. {
  187. MapNode<K, D> *current = NULL;
  188. MapNode<K, D> *next = NULL;
  189. if (_head)
  190. {
  191. UnSetError();
  192. if (_cache)
  193. {
  194. if (_cache->Key() == key)
  195. {
  196. return true;
  197. }
  198. next = _cache->Next();
  199. }
  200. // Mongoose 2002.02.19, Optimize for sequential searches
  201. if (next && key == next->Key())
  202. {
  203. current = next;
  204. }
  205. else // Mongoose 2002.02.19, Use search algorithm otherwise
  206. {
  207. current = _tree.SearchByKey(key, &_error);
  208. }
  209. if (current)
  210. {
  211. _cache = _current = current;
  212. //curData = current->Data();
  213. return true;
  214. }
  215. }
  216. SetError();
  217. return false;
  218. }
  219. bool Add(K key, D data)
  220. {
  221. MapNode<K, D> *node;
  222. UnSetError();
  223. node = new MapNode<K, D>(key, data);
  224. _num_items++;
  225. return Add(node);
  226. }
  227. bool Add(MapNode<K, D> *node)
  228. {
  229. MapNode<K, D> *current = _head;
  230. MapNode<K, D> *last = NULL;
  231. if (!node)
  232. return false;
  233. UnSetError();
  234. if (_head)
  235. {
  236. current = _head;
  237. last = NULL;
  238. while (current)
  239. {
  240. // Prepend
  241. if (current->Key() > node->Key())
  242. {
  243. node->Next(current);
  244. if (current == _head)
  245. {
  246. _head = node;
  247. }
  248. else if (last)
  249. {
  250. last->Next(node);
  251. }
  252. _tree.Insert(node->Key(), node);
  253. return true;
  254. }
  255. last = current;
  256. current = current->Next();
  257. }
  258. // Append
  259. last->Next(node);
  260. }
  261. else
  262. {
  263. _head = node;
  264. }
  265. _tree.Insert(node->Key(), node);
  266. return true;
  267. }
  268. void RemoveByKey(K key)
  269. {
  270. MapNode<K, D> *current = _head;
  271. MapNode<K, D> *last = NULL;
  272. UnSetError();
  273. _cache = NULL;
  274. while (current)
  275. {
  276. // Remove
  277. if (current->Key() == key)
  278. {
  279. if (current == _head)
  280. {
  281. _head = current->Next();
  282. }
  283. else
  284. {
  285. last->Next(current->Next());
  286. }
  287. if (_current == current)
  288. {
  289. _current = NULL;
  290. }
  291. _tree.RemoveByKey(current->Key());
  292. delete current;
  293. _num_items--;
  294. return;
  295. }
  296. last = current;
  297. current = current->Next();
  298. }
  299. SetError();
  300. }
  301. void RemoveByData(D data)
  302. {
  303. MapNode<K, D> *current = _head;
  304. MapNode<K, D> *last = NULL;
  305. UnSetError();
  306. _cache = NULL;
  307. while (current)
  308. {
  309. // Remove
  310. if (current->Data() == data)
  311. {
  312. if (current == _head)
  313. {
  314. _head = current->Next();
  315. }
  316. else
  317. {
  318. last->Next(current->Next());
  319. }
  320. if (_current == current)
  321. {
  322. _current = NULL;
  323. }
  324. _tree.RemoveByKey(current->Key());
  325. delete current;
  326. _num_items--;
  327. return;
  328. }
  329. last = current;
  330. current = current->Next();
  331. }
  332. SetError();
  333. }
  334. bool Empty()
  335. {
  336. return (_head == NULL);
  337. }
  338. unsigned int count()
  339. {
  340. return _num_items;
  341. }
  342. unsigned int NumItems()
  343. {
  344. return _num_items;
  345. }
  346. void Print(void (*print_key_func)(K), void (*print_data_func)(D))
  347. {
  348. MapNode<K, D> *current = _head;
  349. UnSetError();
  350. if (!print_key_func || !print_data_func)
  351. {
  352. SetError();
  353. return;
  354. }
  355. printf(" [%i] {\n", _num_items);
  356. while (current)
  357. {
  358. printf("(");
  359. (*print_key_func)(current->Key());
  360. printf(", ");
  361. (*print_data_func)(current->Data());
  362. printf("), ");
  363. current = current->Next();
  364. fflush(stdout);
  365. }
  366. printf(" }\n");
  367. }
  368. void Reset()
  369. {
  370. _current = _head;
  371. _cache = _head;
  372. }
  373. bool operator ++ (int)
  374. {
  375. return Next();
  376. }
  377. bool operator ++ ()
  378. {
  379. return Next();
  380. }
  381. bool Next()
  382. {
  383. if (_current)
  384. {
  385. _current = _current->Next();
  386. }
  387. return (_current != NULL);
  388. }
  389. bool CurrentExists()
  390. {
  391. return (_current != 0);
  392. }
  393. K CurrentKey()
  394. {
  395. UnSetError();
  396. if (!_current)
  397. {
  398. SetError();
  399. return 0;
  400. }
  401. return _current->Key();
  402. }
  403. D Current()
  404. {
  405. UnSetError();
  406. if (!_current)
  407. {
  408. SetError();
  409. return 0;
  410. }
  411. return _current->Data();
  412. }
  413. private:
  414. unsigned int _num_items;
  415. bool _error;
  416. Tree<K, MapNode<K, D> *> _tree;
  417. MapNode<K, D> *_head;
  418. MapNode<K, D> *_current;
  419. MapNode<K, D> *_cache;
  420. };
  421. #endif