Advertisement
Guest User

Untitled

a guest
Nov 16th, 2019
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.42 KB | None | 0 0
  1. #pragma once
  2.  
  3. #define NUM_ENT_ENTRY_BITS (11 + 2)
  4. #define NUM_ENT_ENTRIES (1 << NUM_ENT_ENTRY_BITS)
  5. #define INVALID_EHANDLE_INDEX 0xFFFFFFFF
  6. #define NUM_SERIAL_NUM_BITS 16 // (32 - NUM_ENT_ENTRY_BITS)
  7. #define NUM_SERIAL_NUM_SHIFT_BITS (32 - NUM_SERIAL_NUM_BITS)
  8. #define ENT_ENTRY_MASK (( 1 << NUM_SERIAL_NUM_BITS) - 1)
  9.  
  10. using CBaseHandle = uint32_t;
  11.  
  12. class IHandleEntity
  13. {
  14. public:
  15. virtual ~IHandleEntity() {}
  16. virtual void SetRefEHandle(const CBaseHandle &handle) = 0;
  17. virtual const CBaseHandle& GetRefEHandle() const = 0;
  18.  
  19. };
  20.  
  21. template< class T >
  22. class CHandle
  23. {
  24. public:
  25.  
  26. CHandle();
  27. CHandle(int iEntry, int iSerialNumber);
  28. CHandle(const CBaseHandle &handle);
  29. CHandle(T *pVal);
  30.  
  31. static CHandle<T> FromIndex(int index);
  32.  
  33. T* Get() const;
  34. void Set(const T* pVal);
  35.  
  36. operator T*();
  37. operator T*() const;
  38.  
  39. bool operator !() const;
  40. bool operator==(T *val) const;
  41. bool operator!=(T *val) const;
  42. const CBaseHandle& operator=(const T *val);
  43.  
  44. T* operator->() const;
  45. };
  46.  
  47. template<class T>
  48. CHandle<T>::CHandle()
  49. {
  50. }
  51.  
  52. template<class T>
  53. CHandle<T>::CHandle(int iEntry, int iSerialNumber)
  54. {
  55. Init(iEntry, iSerialNumber);
  56. }
  57.  
  58. //template<class T>
  59. //CHandle<T>::CHandle(const CBaseHandle &handle)
  60. // : CBaseHandle(handle)
  61. //{
  62. //
  63. template<class T>
  64. CHandle<T>::CHandle(T *pObj)
  65. {
  66. Term();
  67. Set(pObj);
  68. }
  69.  
  70. template<class T>
  71. inline CHandle<T> CHandle<T>::FromIndex(int index)
  72. {
  73. CHandle<T> ret;
  74. ret.m_Index = index;
  75. return ret;
  76. }
  77.  
  78. template<class T>
  79. inline T* CHandle<T>::Get() const
  80. {
  81. return (T*)CBaseHandle::Get();
  82. }
  83.  
  84. template<class T>
  85. inline CHandle<T>::operator T *()
  86. {
  87. return Get();
  88. }
  89.  
  90. template<class T>
  91. inline CHandle<T>::operator T *() const
  92. {
  93. return Get();
  94. }
  95.  
  96. template<class T>
  97. inline bool CHandle<T>::operator !() const
  98. {
  99. return !Get();
  100. }
  101.  
  102. template<class T>
  103. inline bool CHandle<T>::operator==(T *val) const
  104. {
  105. return Get() == val;
  106. }
  107.  
  108. template<class T>
  109. inline bool CHandle<T>::operator!=(T *val) const
  110. {
  111. return Get() != val;
  112. }
  113.  
  114. template<class T>
  115. void CHandle<T>::Set(const T* pVal)
  116. {
  117. CBaseHandle::Set(reinterpret_cast<const IHandleEntity*>(pVal));
  118. }
  119.  
  120. template<class T>
  121. inline const CBaseHandle& CHandle<T>::operator=(const T *val)
  122. {
  123. Set(val);
  124. return *this;
  125. }
  126.  
  127. template<class T>
  128. T* CHandle<T>::operator -> () const
  129. {
  130. return Get();
  131. }
  132. /*
  133. inline CBaseHandle::CBaseHandle()
  134. {
  135. m_Index = INVALID_EHANDLE_INDEX;
  136. }
  137.  
  138. inline CBaseHandle::CBaseHandle(const CBaseHandle &other)
  139. {
  140. m_Index = other.m_Index;
  141. }
  142.  
  143. inline CBaseHandle::CBaseHandle(unsigned long value)
  144. {
  145. m_Index = value;
  146. }
  147.  
  148. inline CBaseHandle::CBaseHandle(int iEntry, int iSerialNumber)
  149. {
  150. Init(iEntry, iSerialNumber);
  151. }
  152.  
  153. inline void CBaseHandle::Init(int iEntry, int iSerialNumber)
  154. {
  155. m_Index = (unsigned long)(iEntry | (iSerialNumber << NUM_SERIAL_NUM_SHIFT_BITS));
  156. }
  157.  
  158. inline void CBaseHandle::Term()
  159. {
  160. m_Index = INVALID_EHANDLE_INDEX;
  161. }
  162.  
  163. inline bool CBaseHandle::IsValid() const
  164. {
  165. return m_Index != INVALID_EHANDLE_INDEX;
  166. }
  167.  
  168. inline int CBaseHandle::GetEntryIndex() const
  169. {
  170. // There is a hack here: due to a bug in the original implementation of the
  171. // entity handle system, an attempt to look up an invalid entity index in
  172. // certain cirumstances might fall through to the the mask operation below.
  173. // This would mask an invalid index to be in fact a lookup of entity number
  174. // NUM_ENT_ENTRIES, so invalid ent indexes end up actually looking up the
  175. // last slot in the entities array. Since this slot is always empty, the
  176. // lookup returns NULL and the expected behavior occurs through this unexpected
  177. // route.
  178. // A lot of code actually depends on this behavior, and the bug was only exposed
  179. // after a change to NUM_SERIAL_NUM_BITS increased the number of allowable
  180. // static props in the world. So the if-stanza below detects this case and
  181. // retains the prior (bug-submarining) behavior.
  182. if (!IsValid())
  183. return NUM_ENT_ENTRIES - 1;
  184. return m_Index & ENT_ENTRY_MASK;
  185. }
  186.  
  187. inline int CBaseHandle::GetSerialNumber() const
  188. {
  189. return m_Index >> NUM_SERIAL_NUM_SHIFT_BITS;
  190. }
  191.  
  192. inline int CBaseHandle::ToInt() const
  193. {
  194. return (int)m_Index;
  195. }
  196.  
  197. inline bool CBaseHandle::operator !=(const CBaseHandle &other) const
  198. {
  199. return m_Index != other.m_Index;
  200. }
  201.  
  202. inline bool CBaseHandle::operator ==(const CBaseHandle &other) const
  203. {
  204. return m_Index == other.m_Index;
  205. }
  206.  
  207. inline bool CBaseHandle::operator ==(const IHandleEntity* pEnt) const
  208. {
  209. return Get() == pEnt;
  210. }
  211.  
  212. inline bool CBaseHandle::operator !=(const IHandleEntity* pEnt) const
  213. {
  214. return Get() != pEnt;
  215. }
  216.  
  217. inline bool CBaseHandle::operator <(const CBaseHandle &other) const
  218. {
  219. return m_Index < other.m_Index;
  220. }
  221.  
  222. inline bool CBaseHandle::operator <(const IHandleEntity *pEntity) const
  223. {
  224. unsigned long otherIndex = (pEntity) ? pEntity->GetRefEHandle().m_Index : INVALID_EHANDLE_INDEX;
  225. return m_Index < otherIndex;
  226. }
  227.  
  228. inline const CBaseHandle& CBaseHandle::operator=(const IHandleEntity *pEntity)
  229. {
  230. return Set(pEntity);
  231. }
  232.  
  233. inline const CBaseHandle& CBaseHandle::Set(const IHandleEntity *pEntity)
  234. {
  235. if (pEntity)
  236. *this = pEntity->GetRefEHandle();
  237. else
  238. m_Index = INVALID_EHANDLE_INDEX;
  239.  
  240. return *this;
  241. }*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement