IdBank.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program 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 along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. // IdBank.cpp
  19. //
  20. // History:
  21. // 01/29/97 JMI Started.
  22. //
  23. // 01/30/97 JMI Removed the bug I put in Add() that access the Head of
  24. // the list to add to, whether or not it was a valid node.
  25. //
  26. // 01/30/97 JMI Fixed bug in Remove(). In rush for demo.
  27. //
  28. // 02/24/97 JMI Changed Add() to Insert() and created new Add() that
  29. // adds at the end.
  30. // Also, removed m_u16HeadUsedId. It wasn't useful.
  31. //
  32. // 03/05/97 JMI GetThingByID() now fails for IdNil without complaint.
  33. //
  34. //////////////////////////////////////////////////////////////////////////////
  35. //
  36. // See .H for details.
  37. //
  38. //////////////////////////////////////////////////////////////////////////////
  39. //////////////////////////////////////////////////////////////////////////////
  40. // C Headers -- Must be included before RSPiX.h b/c RSPiX utilizes SHMalloc.
  41. //////////////////////////////////////////////////////////////////////////////
  42. ///////////////////////////////////////////////////////////////////////////////
  43. // RSPiX Headers.
  44. // If PATHS_IN_INCLUDES macro is defined, we can utilize relative
  45. // paths to a header file. In this case we generally go off of our
  46. // RSPiX root directory. System.h MUST be included before this macro
  47. // is evaluated. System.h is the header that, based on the current
  48. // platform (or more so in this case on the compiler), defines
  49. // PATHS_IN_INCLUDES. Blue.h includes system.h so you can include that
  50. // instead.
  51. ///////////////////////////////////////////////////////////////////////////////
  52. #include "RSPiX.h"
  53. #ifdef PATHS_IN_INCLUDES
  54. #else
  55. #endif
  56. //////////////////////////////////////////////////////////////////////////////
  57. // Postal includes.
  58. //////////////////////////////////////////////////////////////////////////////
  59. #include "IdBank.h"
  60. //////////////////////////////////////////////////////////////////////////////
  61. // Module specific macros.
  62. //////////////////////////////////////////////////////////////////////////////
  63. //////////////////////////////////////////////////////////////////////////////
  64. // Module specific typedefs.
  65. //////////////////////////////////////////////////////////////////////////////
  66. //////////////////////////////////////////////////////////////////////////////
  67. // Exported (extern) variables.
  68. //////////////////////////////////////////////////////////////////////////////
  69. //////////////////////////////////////////////////////////////////////////////
  70. // Module specific (static) variables / Instantiate class statics.
  71. //////////////////////////////////////////////////////////////////////////////
  72. //////////////////////////////////////////////////////////////////////////////
  73. // Module specific (static) protos.
  74. //////////////////////////////////////////////////////////////////////////////
  75. //////////////////////////////////////////////////////////////////////////////
  76. // Functions.
  77. //////////////////////////////////////////////////////////////////////////////
  78. //////////////////////////////////////////////////////////////////////////////
  79. //
  80. // Helper to insert an ID into a particular list.
  81. //
  82. //////////////////////////////////////////////////////////////////////////////
  83. void CIdBank::Insert( // Returns nothing.
  84. U16 u16Id, // ID to insert.
  85. U16* pu16IdHead) // Head of list to add to.
  86. {
  87. // Point this node's next at the current head of the free list.
  88. m_aids[u16Id].u16IdNext = *pu16IdHead;
  89. // If there is a head . . .
  90. if (*pu16IdHead != IdNil)
  91. {
  92. // Point current head node's prev at this node.
  93. m_aids[*pu16IdHead].u16IdPrev = u16Id;
  94. }
  95. // Don't look back.
  96. m_aids[u16Id].u16IdPrev = IdNil;
  97. // Make this node the new head of the list.
  98. *pu16IdHead = u16Id;
  99. }
  100. //////////////////////////////////////////////////////////////////////////////
  101. //
  102. // Helper to add an ID to a particular list.
  103. //
  104. //////////////////////////////////////////////////////////////////////////////
  105. void CIdBank::Add( // Returns nothing.
  106. U16 u16Id, // ID to add.
  107. U16* pu16IdTail) // Tail of list to add to.
  108. {
  109. // Point this node's prev at the current tail of the free list.
  110. m_aids[u16Id].u16IdPrev = *pu16IdTail;
  111. // If there is a head . . .
  112. if (*pu16IdTail != IdNil)
  113. {
  114. // Point current tail node's next at this node.
  115. m_aids[*pu16IdTail].u16IdNext = u16Id;
  116. }
  117. // Don't look forward.
  118. m_aids[u16Id].u16IdNext = IdNil;
  119. // Make this node the new tail of the list.
  120. *pu16IdTail = u16Id;
  121. }
  122. //////////////////////////////////////////////////////////////////////////////
  123. //
  124. // Helper to remove an ID from a particular list.
  125. //
  126. //////////////////////////////////////////////////////////////////////////////
  127. void CIdBank::Remove( // Returns nothing.
  128. U16 u16Id, // ID to remove.
  129. U16* pu16IdHead, // Head of list to remove from.
  130. U16* pu16IdTail) // Tail of list to remove from.
  131. {
  132. // If this was the head . . .
  133. if (*pu16IdHead == u16Id)
  134. {
  135. // Make the head this node's next.
  136. *pu16IdHead = m_aids[u16Id].u16IdNext;
  137. // If not the end . . .
  138. if (*pu16IdHead != IdNil)
  139. {
  140. // Make the new head's prev NIL.
  141. m_aids[*pu16IdHead].u16IdPrev = IdNil;
  142. }
  143. }
  144. else
  145. {
  146. // Set prev's next to this ID's next.
  147. m_aids[m_aids[u16Id].u16IdPrev].u16IdNext = m_aids[u16Id].u16IdNext;
  148. }
  149. // If this was the tail . . .
  150. if (*pu16IdTail == u16Id)
  151. {
  152. // Make the tail this node's prev.
  153. *pu16IdTail = m_aids[u16Id].u16IdPrev;
  154. // If not the beginning . . .
  155. if (*pu16IdTail != IdNil)
  156. {
  157. // Make the new tail's next NIL.
  158. m_aids[*pu16IdTail].u16IdNext = IdNil;
  159. }
  160. }
  161. else
  162. {
  163. // Set next's prev to this ID's prev.
  164. m_aids[m_aids[u16Id].u16IdNext].u16IdPrev = m_aids[u16Id].u16IdPrev;
  165. }
  166. }
  167. //////////////////////////////////////////////////////////////////////////////
  168. //
  169. // Resets all IDs to free. This must be called before the first use of
  170. // any of the rest of these functions.
  171. //
  172. //////////////////////////////////////////////////////////////////////////////
  173. void CIdBank::Reset(void)
  174. {
  175. // Reset all IDs.
  176. // Initialize all IDs regardless of current contents.
  177. U16 u16Cur;
  178. U16 u16Prev;
  179. for (u16Cur = 0, u16Prev = IdNil; u16Cur < NumIds; u16Cur++, u16Prev++)
  180. {
  181. m_aids[u16Cur].u16IdPrev = u16Prev;
  182. m_aids[u16Cur].u16IdNext = u16Cur + 1;
  183. m_aids[u16Cur].pthing = NULL;
  184. }
  185. // Last item's next should indicate end.
  186. m_aids[u16Prev].u16IdNext = IdNil;
  187. // Start at beginning for Free List head.
  188. m_u16HeadFreeId = 0;
  189. // Start at end for Free List tail.
  190. m_u16TailFreeId = NumIds - 1;
  191. }
  192. //////////////////////////////////////////////////////////////////////////////
  193. //
  194. // Get a unique ID and associate it with a thing (CThing, that is).
  195. //
  196. //////////////////////////////////////////////////////////////////////////////
  197. short CIdBank::Get( // Returns 0 on success.
  198. CThing* pthing, // In: Thing that wants to get an ID and be put in
  199. // the ID table.
  200. U16* pu16ID) // Out: ID for this particular CThing.
  201. {
  202. short sRes = 0; // Assume success.
  203. // Make sure there's one left . . .
  204. if (m_u16HeadFreeId != IdNil)
  205. {
  206. // Get ID.
  207. *pu16ID = m_u16HeadFreeId;
  208. // Set IDs value.
  209. m_aids[*pu16ID].pthing = pthing;
  210. // Remove from free list and get next head.
  211. m_u16HeadFreeId = m_aids[*pu16ID].u16IdNext;
  212. }
  213. else
  214. {
  215. TRACE("GetUniqueID(): Out of IDs!\n");
  216. sRes = -1;
  217. }
  218. return sRes;
  219. }
  220. //////////////////////////////////////////////////////////////////////////////
  221. //
  222. // Take a unique ID and associate it with a thing (CThing).
  223. //
  224. //////////////////////////////////////////////////////////////////////////////
  225. short CIdBank::Take( // Returns 0 on success.
  226. CThing* pthing, // In: Thing that wants to take an ID and be put in
  227. // the ID table.
  228. U16 u16ID) // In: ID for this particular CThing.
  229. {
  230. short sRes = 0; // Assume success.
  231. // Range check.
  232. ASSERT(u16ID < NumIds);
  233. // Make sure the ID is available . . .
  234. if (m_aids[u16ID].pthing == NULL)
  235. {
  236. // Set IDs value.
  237. m_aids[u16ID].pthing = pthing;
  238. // Remove from free list.
  239. Remove(u16ID, &m_u16HeadFreeId, &m_u16TailFreeId);
  240. }
  241. else
  242. {
  243. TRACE("TakeUniqueID(): ID not available!\n");
  244. sRes = -1;
  245. }
  246. return sRes;
  247. }
  248. //////////////////////////////////////////////////////////////////////////////
  249. //
  250. // Release ID and unregister thing associated with it.
  251. //
  252. //////////////////////////////////////////////////////////////////////////////
  253. void CIdBank::Release( // Returns nothing.
  254. U16 u16ID) // ID to release.
  255. {
  256. // If a valid ID . . .
  257. if (u16ID != IdNil)
  258. {
  259. // Range check.
  260. ASSERT(u16ID < NumIds);
  261. // The ID should be in use. If not, something has hosened.
  262. ASSERT(m_aids[u16ID].pthing != NULL);
  263. // Clear ID.
  264. m_aids[u16ID].pthing = NULL;
  265. // Add to free list.
  266. Add(u16ID, &m_u16TailFreeId);
  267. }
  268. }
  269. //////////////////////////////////////////////////////////////////////////////
  270. //
  271. // Get a CThing via its ID.
  272. //
  273. //////////////////////////////////////////////////////////////////////////////
  274. short CIdBank::GetThingByID( // Returns 0 on success.
  275. CThing** ppthing, // Out: Ptr to CThing identified by u16ID.
  276. U16 u16ID) // In: ID of thing to get.
  277. {
  278. short sRes = 0; // Assume success.
  279. if (u16ID != IdNil)
  280. {
  281. // Range check.
  282. ASSERT(u16ID < NumIds);
  283. // Get thing.
  284. *ppthing = m_aids[u16ID].pthing;
  285. // This ID should be used.
  286. if (*ppthing != NULL)
  287. {
  288. // Success.
  289. }
  290. else
  291. {
  292. // TRACE("GetThingByID(): No such ID.\n");
  293. sRes = -2;
  294. }
  295. }
  296. else
  297. {
  298. *ppthing = NULL;
  299. sRes = -1;
  300. }
  301. return sRes;
  302. }
  303. ///////////////////////////////////////////////////////////////////////////////
  304. // EOF
  305. ///////////////////////////////////////////////////////////////////////////////