templates.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #pragma once
  2. //========================================================================
  3. // Templates.h : Some useful templates
  4. //
  5. // Part of the GameCode4 Application
  6. //
  7. // GameCode4 is the sample application that encapsulates much of the source code
  8. // discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
  9. // "Rez" Graham, published by Charles River Media.
  10. // ISBN-10: 1133776574 | ISBN-13: 978-1133776574
  11. //
  12. // If this source code has found it's way to you, and you think it has helped you
  13. // in any way, do the authors a favor and buy a new copy of the book - there are
  14. // detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
  15. // by clicking here:
  16. // http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
  17. //
  18. // There's a companion web site at http://www.mcshaffry.com/GameCode/
  19. //
  20. // The source code is managed and maintained through Google Code:
  21. // http://code.google.com/p/gamecode4/
  22. //
  23. // (c) Copyright 2012 Michael L. McShaffry and David Graham
  24. //
  25. // This program is free software; you can redistribute it and/or
  26. // modify it under the terms of the GNU Lesser GPL v3
  27. // as published by the Free Software Foundation.
  28. //
  29. // This program is distributed in the hope that it will be useful,
  30. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  31. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  32. // http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
  33. //
  34. // You should have received a copy of the GNU Lesser GPL v3
  35. // along with this program; if not, write to the Free Software
  36. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  37. //
  38. //========================================================================
  39. //========================================================================
  40. //
  41. // Original Code written at Compulsive Development
  42. //
  43. //========================================================================
  44. //========================================================================
  45. // Content References in Game Coding Complete 3rd Edition
  46. //
  47. // class singleton - Chapter 3
  48. // class optional - Chapter 3
  49. //
  50. //========================================================================
  51. #include <memory>
  52. //---------------------------------------------------------------------------------------------------------------------
  53. // singleton template manages setting/resettting global variables.
  54. //---------------------------------------------------------------------------------------------------------------------
  55. // template <class T>
  56. // class singleton
  57. // {
  58. // T m_OldValue;
  59. // T* m_pGlobalValue;
  60. // public:
  61. // singleton(T newValue, T* globalValue)
  62. // {
  63. // m_pGlobalValue = globalValue;
  64. // m_OldValue = *globalValue;
  65. // *m_pGlobalValue = newValue;
  66. // }
  67. // virtual ~singleton() { *m_pGlobalValue = m_OldValue; }
  68. // };
  69. //---------------------------------------------------------------------------------------------------------------------
  70. // [rez] Tr1 / Boost smart pointers make me sad. In order to dereference a weak_ptr, you have to cast it to a
  71. // shared_ptr first. You still have to check to see if the pointer is dead dead by calling expired() on the weak_ptr,
  72. // so why not just allow the weak_ptr to be dereferenceable? It doesn't buy anything to force this extra step because
  73. // you can still cast a dead weak_ptr to a shared_ptr and crash. Nice. Anyway, this function takes some of that
  74. // headache away.
  75. //---------------------------------------------------------------------------------------------------------------------
  76. template <class Type>
  77. std::shared_ptr<Type> MakeStrongPtr(std::weak_ptr<Type> pWeakPtr)
  78. {
  79. if (!pWeakPtr.expired())
  80. return std::shared_ptr<Type>(pWeakPtr);
  81. else
  82. return std::shared_ptr<Type>();
  83. }
  84. //////////////////////////////////////////////////////////////////////////////
  85. // optional.h
  86. //
  87. // An isolation point for optionality, provides a way to define
  88. // objects having to provide a special "null" state.
  89. //
  90. // In short:
  91. //
  92. // struct optional<T>
  93. // {
  94. // bool m_bValid;
  95. //
  96. // T m_data;
  97. // };
  98. //
  99. //
  100. // #include <new>
  101. // class optional_empty { };
  102. // template <unsigned long size>
  103. // class optional_base
  104. // {
  105. // public:
  106. // // Default - invalid.
  107. // optional_base() : m_bValid(false) { }
  108. // optional_base & operator = (optional_base const & t)
  109. // {
  110. // m_bValid = t.m_bValid;
  111. // return * this;
  112. // }
  113. // //Copy constructor
  114. // optional_base(optional_base const & other)
  115. // : m_bValid(other.m_bValid) { }
  116. // //utility functions
  117. // bool const valid() const { return m_bValid; }
  118. // bool const invalid() const { return !m_bValid; }
  119. // protected:
  120. // bool m_bValid;
  121. // char m_data[size]; // storage space for T
  122. // };
  123. // template <class T>
  124. // class optional : public optional_base<sizeof(T)>
  125. // {
  126. // public:
  127. // // Default - invalid.
  128. // optional() { }
  129. // optional(T const & t) { construct(t); m_bValid = (true); }
  130. // optional(optional_empty const &) { }
  131. // optional & operator = (T const & t)
  132. // {
  133. // if (m_bValid)
  134. // {
  135. // * GetT() = t;
  136. // }
  137. // else
  138. // {
  139. // construct(t);
  140. // m_bValid = true; // order important for exception safety.
  141. // }
  142. // return * this;
  143. // }
  144. // //Copy constructor
  145. // optional(optional const & other)
  146. // {
  147. // if (other.m_bValid)
  148. // {
  149. // construct(* other);
  150. // m_bValid = true; // order important for exception safety.
  151. // }
  152. // }
  153. // optional & operator = (optional const & other)
  154. // {
  155. // GCC_ASSERT(! (this == & other)); // don't copy over self!
  156. // if (m_bValid)
  157. // { // first, have to destroy our original.
  158. // m_bValid = false; // for exception safety if destroy() throws.
  159. // // (big trouble if destroy() throws, though)
  160. // destroy();
  161. // }
  162. // if (other.m_bValid)
  163. // {
  164. // construct(* other);
  165. // m_bValid = true; // order vital.
  166. // }
  167. // return * this;
  168. // }
  169. // bool const operator == (optional const & other) const
  170. // {
  171. // if ((! valid()) && (! other.valid())) { return true; }
  172. // if (valid() ^ other.valid()) { return false; }
  173. // return ((* * this) == (* other));
  174. // }
  175. // bool const operator < (optional const & other) const
  176. // {
  177. // // equally invalid - not smaller.
  178. // if ((! valid()) && (! other.valid())) { return false; }
  179. // // I'm not valid, other must be, smaller.
  180. // if (! valid()) { return true; }
  181. // // I'm valid, other is not valid, I'm larger
  182. // if (! other.valid()) { return false; }
  183. // return ((* * this) < (* other));
  184. // }
  185. // ~optional() { if (m_bValid) destroy(); }
  186. // // Accessors.
  187. // T const & operator * () const { GCC_ASSERT(m_bValid); return * GetT(); }
  188. // T & operator * () { GCC_ASSERT(m_bValid); return * GetT(); }
  189. // T const * const operator -> () const { GCC_ASSERT(m_bValid); return GetT(); }
  190. // T * const operator -> () { GCC_ASSERT(m_bValid); return GetT(); }
  191. // //This clears the value of this optional variable and makes it invalid once again.
  192. // void clear()
  193. // {
  194. // if (m_bValid)
  195. // {
  196. // m_bValid = false;
  197. // destroy();
  198. // }
  199. // }
  200. // //utility functions
  201. // bool const valid() const { return m_bValid; }
  202. // bool const invalid() const { return !m_bValid; }
  203. // private:
  204. // T const * const GetT() const { return reinterpret_cast<T const * const>(m_data); }
  205. // T * const GetT() { return reinterpret_cast<T * const>(m_data);}
  206. // void construct(T const & t) { new (GetT()) T(t); }
  207. // void destroy() { GetT()->~T(); }
  208. // };
  209. template <class BaseType, class SubType>
  210. BaseType* GenericObjectCreationFunction(void) { return new SubType; }
  211. template <class BaseClass, class IdType>
  212. class GenericObjectFactory
  213. {
  214. typedef BaseClass* (*ObjectCreationFunction)(void);
  215. std::map<IdType, ObjectCreationFunction> m_creationFunctions;
  216. public:
  217. template <class SubClass>
  218. bool Register(IdType id)
  219. {
  220. auto findIt = m_creationFunctions.find(id);
  221. if (findIt == m_creationFunctions.end())
  222. {
  223. m_creationFunctions[id] = &GenericObjectCreationFunction<BaseClass, SubClass>; // insert() is giving me compiler errors
  224. return true;
  225. }
  226. return false;
  227. }
  228. BaseClass* Create(IdType id)
  229. {
  230. auto findIt = m_creationFunctions.find(id);
  231. if (findIt != m_creationFunctions.end())
  232. {
  233. ObjectCreationFunction pFunc = findIt->second;
  234. return pFunc();
  235. }
  236. return NULL;
  237. }
  238. };