COM原理与实现之二: 聚合

前端之家收集整理的这篇文章主要介绍了COM原理与实现之二: 聚合前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

COM原理与实现之二: 聚合


C++没有同聚合等价的特性。聚合实际上是继承性的一种动态形式。而C++的继承总是静态的,是实现继承。COM是接口继承,通过聚合接口,可以做成动态配置。

研究COM,主要是利用接口继承的灵活性构筑强大的系统:可配置、可插拔、可脚本化。本文不讲太多理论,详细原理参考[COM技术内幕]这本书。关于[COM技术内幕],很多内容过时了,比如注册表,类厂之类的。我更关心COM思想所蕴含的哲学。我实现了跨平台COM,支持聚合。


GameStencil这个组件聚合了SystemMngmt这个组件。最初采用IGameStencil::getSystemMngmt()这样的形式返回一个ISystemMngmt接口指针,显然这不是聚合。通过A对象的方法得到B对象,显然A仅仅是B的一种类厂。于是我下决心解决组件聚合问题。就有了本文。


core目录下面就3个文件,是我的跨平台COM的基础。

1) Platform.h

  1. /**
  2. * Platform.h
  3. *
  4. *
  5. * Init Created: 2016-06-10
  6. * Last Updated: 2016-06-10
  7. */
  8. #ifndef PLATFORM_H
  9. #define PLATFORM_H
  10.  
  11. #if defined _MSC_VER || WIN32
  12. #ifndef OS_PLATFORM_WIN
  13. #define OS_PLATFORM_WIN
  14. #endif
  15. #endif
  16.  
  17. #ifdef OS_PLATFORM_WIN
  18. #include <windows.h>
  19. #include <process.h>
  20. #else
  21. #include <pthread.h>
  22. #include <unistd.h>
  23. #endif
  24.  
  25. #ifndef interface
  26. #define interface struct
  27. #endif
  28.  
  29.  
  30. /**
  31. * interface iid
  32. */
  33. typedef unsigned int iid_t;
  34.  
  35.  
  36. /**
  37. * long result
  38. */
  39. typedef long lresult_t;
  40.  
  41. #define lres_success 0
  42. #define lres_error (-1)
  43. #define lres_e_initdata (-2)
  44. #define lres_e_outmemory (-4)
  45. #define lres_e_nointerface (-11)
  46. #define lres_e_noaggregation (-12)
  47.  
  48. /**
  49. * thread_ctx
  50. */
  51. #define thread_ctx_single 0
  52. #define thread_ctx_multiple 1
  53.  
  54.  
  55. /**
  56. * ref count type
  57. */
  58. #ifdef OS_PLATFORM_WIN
  59. typedef volatile unsigned long refcount_t;
  60. #define __interlock_inc(add) InterlockedIncrement(add)
  61. #define __interlock_dec(sub) InterlockedDecrement(sub)
  62. #else
  63. typedef volatile size_t refcount_t;
  64. #define __interlock_inc(add) __sync_add_and_fetch(add,1)
  65. #define __interlock_dec(sub) __sync_sub_and_fetch(sub,1)
  66. #endif
  67.  
  68.  
  69. #endif /* PLATFORM_H */

2) Universal.h

  1. /**
  2. * Universal.h
  3. *
  4. * Refer:
  5. * <<Inside COM>>
  6. *
  7. * Init Created: 2016-06-10
  8. * Last Updated: 2016-06-13
  9. */
  10. #ifndef UNIVERSAL_H
  11. #define UNIVERSAL_H
  12.  
  13. #include "Platform.h"
  14.  
  15.  
  16. // IUniversal is a variant from IUnknown
  17. //
  18. interface IUniversal
  19. {
  20. static const iid_t IID = ((iid_t) (0));
  21.  
  22. virtual lresult_t query(iid_t iid,void **ppvOut) = 0;
  23. virtual unsigned long retain(void) = 0;
  24. virtual unsigned long release(void) = 0;
  25. };
  26.  
  27. #define iid_IUniversal (IUniversal::IID)
  28.  
  29.  
  30. // Nondelegating IUniversal interface
  31. // - Nondelegating version of IUniversal
  32. //
  33. interface INondelegatingUniversal
  34. {
  35. static const iid_t IID = ((iid_t) (-1));
  36.  
  37. virtual lresult_t NondelegatingQuery(iid_t iid,void **ppvOut) = 0;
  38. virtual unsigned long NondelegatingRetain(void) = 0;
  39. virtual unsigned long NondelegatingRelease(void) = 0;
  40. };
  41.  
  42. #define iid_INondelegatingUniversal (INondelegatingUniversal::IID)
  43.  
  44.  
  45. class UniversalImpl
  46. {
  47. private:
  48. unsigned thread_ctx;
  49. refcount_t ref_count;
  50.  
  51. public:
  52. UniversalImpl() :
  53. ref_count(1),thread_ctx(thread_ctx_multiple) {
  54. printf("UniversalImpl\n");
  55. }
  56.  
  57. virtual ~UniversalImpl() {
  58. printf("~UniversalImpl\n");
  59. }
  60.  
  61.  
  62. void init(unsigned threadctx) {
  63. thread_ctx = threadctx;
  64. }
  65.  
  66.  
  67. // Notification to derived classes that we are releasing
  68. void finalRelease() {
  69. // Increment reference count for final release
  70. ref_count = 1;
  71. }
  72.  
  73.  
  74. unsigned getThreadCtx() const {
  75. return thread_ctx;
  76. }
  77.  
  78.  
  79. // IUniversal
  80. //
  81. virtual lresult_t query(iid_t iid,void **ppv) = 0;
  82.  
  83.  
  84. virtual unsigned long retain(void) {
  85. if (thread_ctx == thread_ctx_multiple) {
  86. return __interlock_inc(&ref_count);
  87. } else {
  88. return ++ref_count;
  89. }
  90. }
  91.  
  92.  
  93. virtual unsigned long release(void) {
  94. if (thread_ctx == thread_ctx_multiple) {
  95. if (__interlock_dec(&ref_count) == 0) {
  96. delete this;
  97. return 0;
  98. }
  99. } else {
  100. if (--ref_count == 0) {
  101. delete this;
  102. return 0;
  103. }
  104. }
  105. return ref_count;
  106. }
  107. };
  108.  
  109.  
  110. // Declaration of NondelegatingUniversalImpl
  111. // - Base class for implementing INondelegatingUniversal
  112. //
  113. class NondelegatingUniversalImpl : public INondelegatingUniversal
  114. {
  115. public:
  116.  
  117. virtual lresult_t NondelegatingQuery(iid_t iid,void **ppv) = 0;
  118.  
  119.  
  120. virtual unsigned long NondelegatingRetain(void) {
  121. if (thread_ctx == thread_ctx_multiple) {
  122. return __interlock_inc(&ref_count);
  123. } else {
  124. return ++ref_count;
  125. }
  126. }
  127.  
  128. virtual unsigned long NondelegatingRelease(void) {
  129. if (thread_ctx == thread_ctx_multiple) {
  130. if (__interlock_dec(&ref_count) == 0) {
  131. delete this;
  132. return 0;
  133. }
  134. } else {
  135. if (--ref_count == 0) {
  136. delete this;
  137. return 0;
  138. }
  139. }
  140. return ref_count;
  141. }
  142.  
  143.  
  144. // Constructor
  145. NondelegatingUniversalImpl(IUniversal* pUniversalOuter) :
  146. ref_count(1) {
  147. // Set outer_universal pointer
  148. if (! pUniversalOuter) {
  149. // Not aggregating; delegate to nondelegating IUniversal
  150. m_pUniversalOuter = reinterpret_cast<IUniversal*>
  151. (static_cast<INondelegatingUniversal*>
  152. (this));
  153. } else {
  154. // Aggregating; delegate to outer IUniversal
  155. m_pUniversalOuter = pUniversalOuter;
  156. }
  157. }
  158.  
  159.  
  160. // Destructor
  161. virtual ~NondelegatingUniversalImpl() {
  162. }
  163.  
  164.  
  165. // Initialization (especially for aggregates)
  166. void init(unsigned threadctx) {
  167. thread_ctx = threadctx;
  168. }
  169.  
  170.  
  171. // Notification to derived classes that we are releasing
  172. virtual void finalRelease() {
  173. // Increment reference count for final release
  174. ref_count = 1;
  175. }
  176.  
  177. protected:
  178. // Support for delegation
  179. IUniversal* getUniversalOuter() const {
  180. return m_pUniversalOuter;
  181. }
  182.  
  183.  
  184. private:
  185. // thread context
  186. unsigned thread_ctx;
  187.  
  188. // Reference count for this object
  189. refcount_t ref_count;
  190.  
  191. // Pointer to (external) outer IUniversal
  192. IUniversal* m_pUniversalOuter;
  193. };
  194.  
  195.  
  196. ///////////////////////////////////////////////////////////
  197. //
  198. // Delegating IUniversal
  199. // - Delegates to the nondelegating IUniversal,or to the
  200. // outer IUniversal if the component is aggregated.
  201. //
  202. #define DECLARE_UNIVERSAL_INTERFACE \
  203. virtual lresult_t query(iid_t iid,void **ppv) { \
  204. return getUniversalOuter()->query(iid,ppv); \
  205. } \
  206. virtual unsigned long retain(void) { \
  207. return getUniversalOuter()->retain(); \
  208. } \
  209. virtual unsigned long release(void) { \
  210. return getUniversalOuter()->release(); \
  211. }
  212.  
  213.  
  214. #define CREATE_INSTANCE_NO_AGGREGATION(className) \
  215. static lresult_t createInstance(\
  216. unsigned threadctx,\
  217. IUniversal *pUniversalOuter,\
  218. iid_t iid,\
  219. void **ppv) {\
  220. /* cannot be aggregated */ \
  221. if (pUniversalOuter) {\
  222. return lres_e_noaggregation; \
  223. } \
  224. className * p = new className();\
  225. if ( ! p) {\
  226. return lres_e_outmemory;\
  227. }\
  228. lresult_t hr = p->init(threadctx);\
  229. if (hr != lres_success) {\
  230. p->NondelegatingRelease();\
  231. return hr;\
  232. }\
  233. hr = p->NondelegatingQuery(iid,ppv);\
  234. p->NondelegatingRelease();\
  235. return hr;\
  236. }
  237.  
  238.  
  239. #define CREATE_INSTANCE_WITH_AGGREGATION(className) \
  240. static lresult_t createInstance(\
  241. unsigned threadctx,\
  242. IUniversal* pUniversalOuter,\
  243. void **ppv) {\
  244. className * p = new className(pUniversalOuter);\
  245. if ( ! p) {\
  246. return lres_e_outmemory;\
  247. }\
  248. lresult_t hr = p->init(threadctx);\
  249. if (hr != lres_success) {\
  250. p->release();\
  251. return hr;\
  252. }\
  253. hr = p->NondelegatingQuery(iid,ppv);\
  254. p->NondelegatingRelease();\
  255. return hr;\
  256. }
  257.  
  258.  
  259. #endif /* UNIVERSAL_H */

3)SIPtr.h

  1. /**
  2. * SIPtr.h
  3. * Smart Interface Pointer
  4. *
  5. * Use: SIPtr<IX> spIX;
  6. * Do not use with IUniversal; SIPtr<IUniversal>
  7. * will not compile. Instead,use IUniversalPtr.
  8. *
  9. * Refer:
  10. * <<Inside COM>>
  11. *
  12. * Init Created: 2016-06-10
  13. * Last Updated: 2016-06-10
  14. */
  15. #ifndef SIPTR_H
  16. #define SIPTR_H
  17.  
  18. #include "Universal.h"
  19.  
  20. #include <assert.h>
  21.  
  22.  
  23. template <class T> class SIPtr
  24. {
  25. public:
  26.  
  27. // Constructors
  28. SIPtr() {
  29. m_pI = 0;
  30. }
  31.  
  32.  
  33. SIPtr(T* lp) {
  34. m_pI = lp;
  35. if ( m_pI ) {
  36. m_pI->retain();
  37. }
  38. }
  39.  
  40.  
  41. SIPtr(IUniversal* pI) {
  42. m_pI = 0;
  43. if ( pI ) {
  44. pI->query(T::IID,(void **) & m_pI);
  45. }
  46. }
  47.  
  48.  
  49. // Destructor
  50. ~SIPtr() {
  51. release();
  52. }
  53.  
  54.  
  55. // Reset
  56. void release() {
  57. if ( m_pI ) {
  58. T* pOld = m_pI;
  59. m_pI = 0;
  60. pOld->release();
  61. }
  62. }
  63.  
  64.  
  65. // Attach to an existing interface (does not retain)
  66. void attach(T * pI) {
  67. if (m_pI != pI) {
  68. IUniversal* pOld = m_pI;
  69.  
  70. m_pI = pI;
  71.  
  72. if (pOld) {
  73. // Release the old interface
  74. pOld->release();
  75. }
  76. }
  77. }
  78.  
  79.  
  80. // Detach the interface (does not release)
  81. T* detach() {
  82. T* pOld = m_pI;
  83. m_pI = 0;
  84. return pOld;
  85. }
  86.  
  87. T* get() {
  88. return m_pI;
  89. }
  90.  
  91. // Conversion
  92. operator T*() {
  93. return m_pI;
  94. }
  95.  
  96.  
  97. // Pointer operations
  98. T& operator*() {
  99. assert(m_pI);
  100. return * m_pI;
  101. }
  102.  
  103.  
  104. T** operator&() {
  105. assert(!m_pI);
  106. return &m_pI;
  107. }
  108.  
  109.  
  110. T* operator->() {
  111. assert(m_pI);
  112. return m_pI;
  113. }
  114.  
  115.  
  116. // Assignment from the same interface
  117. T* operator=(T* pI) {
  118. if (m_pI != pI) {
  119. // Save current value
  120. IUniversal* pOld = (IUniversal *) m_pI;
  121.  
  122. // Assign new value
  123. m_pI = pI;
  124.  
  125. if (m_pI) {
  126. m_pI->retain();
  127. }
  128.  
  129. if (pOld) {
  130. // Release the old interface
  131. pOld->release();
  132. }
  133. }
  134. return m_pI;
  135. }
  136.  
  137.  
  138. // Assignment from another interface
  139. T* operator=(IUniversal* pI) {
  140. // Save current value
  141. IUniversal* pOld = m_pI;
  142. m_pI = 0;
  143.  
  144. // Query for correct interface
  145. if ( pI ) {
  146. lresult_t hr = pI->query(T::iid_interface,(void**) & m_pI);
  147. assert(hr == lres_success && m_pI);
  148. }
  149.  
  150. if ( pOld ) {
  151. // Release old pointer
  152. pOld->release();
  153. }
  154. return m_pI ;
  155. }
  156.  
  157. // bool functions
  158. bool operator!() {
  159. return m_pI ? false : true;
  160. }
  161.  
  162.  
  163. // Requires a compiler that supports BOOL
  164. operator bool() const {
  165. return m_pI ? true : false;
  166. }
  167.  
  168.  
  169. // Interface ID
  170. iid_t iid() {
  171. return T::IID;
  172. }
  173.  
  174.  
  175. private:
  176. // Pointer variable
  177. T* m_pI;
  178. };
  179.  
  180.  
  181. /**
  182. * IUniversalPtr is a smart interface for IUniversal
  183. */
  184. class IUniversalPtr
  185. {
  186. public:
  187. // Constructors
  188. IUniversalPtr() {
  189. m_pI = 0;
  190. }
  191.  
  192.  
  193. IUniversalPtr(IUniversal* lp) {
  194. m_pI = lp;
  195. if ( m_pI ) {
  196. m_pI->retain();
  197. }
  198. }
  199.  
  200.  
  201. // Destructor
  202. ~IUniversalPtr() {
  203. release();
  204. }
  205.  
  206.  
  207. // Reset
  208. void release() {
  209. if (m_pI) {
  210. IUniversal* pOld = m_pI;
  211. m_pI = 0;
  212. pOld->release();
  213. }
  214. }
  215.  
  216.  
  217. // Conversion
  218. operator IUniversal*() {
  219. return (IUniversal*) m_pI;
  220. }
  221.  
  222.  
  223. // Pointer operations
  224. IUniversal& operator*() {
  225. assert(m_pI);
  226. return *m_pI;
  227. }
  228.  
  229.  
  230. IUniversal** operator&() {
  231. assert(!m_pI);
  232. return &m_pI;
  233. }
  234.  
  235.  
  236. IUniversal* operator->() {
  237. assert(m_pI);
  238. return m_pI;
  239. }
  240.  
  241.  
  242. // Assignment
  243. IUniversal* operator=(IUniversal* pI) {
  244. if (m_pI != pI) {
  245. // Save current value
  246. IUniversal* pOld = m_pI;
  247.  
  248. // Assign new value
  249. m_pI = pI;
  250.  
  251. if ( m_pI ) {
  252. m_pI->retain();
  253. }
  254.  
  255. if ( pOld ) {
  256. // Release the old interface
  257. pOld->release();
  258. }
  259. }
  260. return m_pI;
  261. }
  262.  
  263.  
  264. // Boolean functions
  265. bool operator!() {
  266. return m_pI ? false : true;
  267. }
  268.  
  269.  
  270. operator bool() const {
  271. return m_pI ? true : false;
  272. }
  273.  
  274.  
  275. private:
  276. // Pointer variable
  277. IUniversal* m_pI;
  278. };
  279.  
  280. #endif /* SIPTR_H */

组件 GameStencil的代码

  1. /**
  2. * IGameStencil.h
  3. *
  4. * Author: master@pepstack.com
  5. *
  6. * Refer:
  7. * http://www.richardlord.net/blog/what-is-an-entity-framework
  8. * http://blog.csdn.net/i_dovelemon/article/details/30250049
  9. * http://blog.csdn.net/zhao_92221/article/details/46629553
  10. * http://blog.csdn.net/ubuntu64fan/article/details/8839778
  11. *
  12. * Init Created: 2016-06-13
  13. * Last Updated: 2016-06-13
  14. */
  15. #ifndef IGAME_STENCIL_H
  16. #define IGAME_STENCIL_H
  17.  
  18.  
  19. #include "core/SIPtr.h"
  20.  
  21.  
  22. namespace ecs {
  23.  
  24. interface IGameStencil : IUniversal {
  25. static const iid_t IID = ((iid_t) 0x00F000);
  26.  
  27. virtual void update(float dt) = 0;
  28. };
  29.  
  30. }; /* namespace ecs */
  31.  
  32. #endif /* IGAME_STENCIL_H */

  1. /**
  2. * GameStencil.h
  3. * The GameStencil class is the central point for creating
  4. * and managing your game state.
  5. *
  6. * Refer:
  7. * http://www.richardlord.net/blog/what-is-an-entity-framework
  8. * http://blog.csdn.net/i_dovelemon/article/details/30250049
  9. * http://blog.csdn.net/zhao_92221/article/details/46629553
  10. * http://blog.csdn.net/ubuntu64fan/article/details/8839778
  11. *
  12. * Init Created: 2016-06-12
  13. * Last Updated: 2016-06-12
  14. */
  15. #ifndef GAME_STENCIL_H
  16. #define GAME_STENCIL_H
  17.  
  18. #include "IGameStencil.h"
  19.  
  20. #include "SystemMngmt.h"
  21.  
  22. #include <memory>
  23. #include <vector>
  24. using namespace std;
  25.  
  26.  
  27. namespace ecs {
  28.  
  29.  
  30. class GameStencil :
  31. public IGameStencil,public NondelegatingUniversalImpl
  32. {
  33. public:
  34. // Creation
  35. //
  36. CREATE_INSTANCE_NO_AGGREGATION(GameStencil)
  37.  
  38.  
  39. private:
  40.  
  41. // Constructor
  42. GameStencil() :
  43. NondelegatingUniversalImpl(0),updating(false),m_pUniversalInner(0) {
  44.  
  45. printf("GameStencil\n");
  46.  
  47. m_pISystemMngmt = 0;
  48. }
  49.  
  50.  
  51. // Destructor
  52. virtual ~GameStencil() {
  53. finalRelease();
  54.  
  55. printf("~GameStencil\n");
  56. }
  57.  
  58.  
  59. // Initialization
  60. //
  61. virtual lresult_t init(unsigned threadctx) {
  62. NondelegatingUniversalImpl::init(threadctx);
  63.  
  64. IUniversal * pUniversalOuter = this;
  65.  
  66. lresult_t hr = SystemMngmt::createInstance(threadctx,pUniversalOuter,IUniversal::IID,(void**) &m_pUniversalInner);
  67.  
  68. if (hr != lres_success) {
  69. return lres_error;
  70. }
  71.  
  72. hr = m_pUniversalInner->query(ISystemMngmt::IID,(void**) &m_pISystemMngmt);
  73.  
  74. if (hr != lres_success) {
  75. m_pUniversalInner->release();
  76. return lres_error;
  77. }
  78.  
  79. pUniversalOuter->release();
  80. return lres_success;
  81. }
  82.  
  83.  
  84. virtual void finalRelease() {
  85. NondelegatingUniversalImpl::finalRelease();
  86.  
  87. getUniversalOuter()->retain();
  88.  
  89. m_pISystemMngmt->release();
  90.  
  91. if (m_pUniversalInner) {
  92. m_pUniversalInner->release();
  93. }
  94. }
  95.  
  96.  
  97. // IUniversal
  98. //
  99. DECLARE_UNIVERSAL_INTERFACE
  100.  
  101.  
  102. // INondelegatingUniversal
  103. //
  104. virtual lresult_t NondelegatingQuery(iid_t iid,void** ppv) {
  105. if (iid == IUniversal::IID) {
  106. *ppv = static_cast<IGameStencil*> (this);
  107. } else if (iid == IGameStencil::IID) {
  108. *ppv = static_cast<IGameStencil*> (this);
  109. } else if (iid == ISystemMngmt::IID) {
  110. // contained component
  111. *ppv = m_pISystemMngmt;
  112. } else {
  113. *ppv = 0;
  114. return lres_e_nointerface;
  115. }
  116.  
  117. reinterpret_cast<IUniversal*> (*ppv)->retain();
  118. return lres_success;
  119. }
  120. // IGameStencil
  121. //
  122. virtual void update(float dt) {
  123. updating = true;
  124.  
  125. // TODO:
  126.  
  127. updating = false;
  128. }
  129.  
  130.  
  131. private:
  132. bool updating;
  133.  
  134. IUniversal * m_pUniversalInner;
  135.  
  136. ISystemMngmt * m_pISystemMngmt;
  137. };
  138.  
  139. }; /* namespace ecs */
  140.  
  141. #endif /* GAME_STENCIL_H */


被聚合的组件 SystemMngmt的代码

  1. /**
  2. * ISystemMngmt.h
  3. *
  4. * Author: master@pepstack.com
  5. *
  6. * Refer:
  7. * http://www.richardlord.net/blog/what-is-an-entity-framework
  8. * http://blog.csdn.net/i_dovelemon/article/details/30250049
  9. * http://blog.csdn.net/zhao_92221/article/details/46629553
  10. * http://blog.csdn.net/ubuntu64fan/article/details/8839778
  11. *
  12. * Init Created: 2016-06-10
  13. * Last Updated: 2016-06-12
  14. */
  15. #ifndef ISYSTEM_MNGMT_H
  16. #define ISYSTEM_MNGMT_H
  17.  
  18.  
  19. #include "core/SIPtr.h"
  20.  
  21.  
  22. namespace ecs {
  23.  
  24. interface ISystemMngmt : IUniversal
  25. {
  26. static const iid_t IID = ((iid_t) 0x10F001);
  27.  
  28. virtual void update(float dt) = 0;
  29. virtual void pause() = 0;
  30. virtual void resume() = 0;
  31. };
  32.  
  33. }; /* namespace ecs */
  34.  
  35. #endif /* ISYSTEM_MNGMT_H */

  1. /**
  2. * SystemMngmt.h
  3. *
  4. * Refer:
  5. * http://www.richardlord.net/blog/what-is-an-entity-framework
  6. * http://blog.csdn.net/i_dovelemon/article/details/30250049
  7. * http://blog.csdn.net/zhao_92221/article/details/46629553
  8. * http://blog.csdn.net/ubuntu64fan/article/details/8839778
  9. *
  10. * Init Created: 2016-06-13
  11. * Last Updated: 2016-06-13
  12. */
  13. #ifndef SYSTEM_MNGMT_H
  14. #define SYSTEM_MNGMT_H
  15.  
  16. #include "ISystemMngmt.h"
  17.  
  18.  
  19. #include <memory>
  20. #include <vector>
  21. using namespace std;
  22.  
  23.  
  24. namespace ecs {
  25.  
  26.  
  27. class SystemMngmt :
  28. public ISystemMngmt,public NondelegatingUniversalImpl
  29. {
  30. public:
  31. // Creation
  32. //
  33. CREATE_INSTANCE_WITH_AGGREGATION(SystemMngmt)
  34.  
  35.  
  36. private:
  37.  
  38. // Constructor
  39. SystemMngmt(IUniversal * pUniversalOuter) :
  40. NondelegatingUniversalImpl(pUniversalOuter) {
  41. paused = false;
  42. printf("SystemMngmt\n");
  43. }
  44.  
  45.  
  46. // Destructor
  47. virtual ~SystemMngmt() {
  48. finalRelease();
  49. printf("~SystemMngmt\n");
  50. }
  51.  
  52.  
  53. virtual lresult_t init(unsigned threadctx) {
  54. NondelegatingUniversalImpl::init(threadctx);
  55. return lres_success;
  56. }
  57.  
  58. public:
  59.  
  60. // IUniversal
  61. //
  62. DECLARE_UNIVERSAL_INTERFACE
  63.  
  64.  
  65. // INondelegatingUniversal
  66. //
  67. virtual lresult_t NondelegatingQuery(iid_t iid,void** ppv) {
  68. if (iid == IUniversal::IID) {
  69. *ppv = static_cast<INondelegatingUniversal*> (this);
  70. } else if (iid == ISystemMngmt::IID) {
  71. *ppv = static_cast<ISystemMngmt*> (this);
  72. } else {
  73. *ppv = 0;
  74. return lres_e_nointerface;
  75. }
  76. reinterpret_cast<IUniversal*> (*ppv)->retain();
  77. return lres_success;
  78. }
  79. // ISystemMngmt
  80. //
  81.  
  82. // Update all the system
  83. void update(float dt) {
  84.  
  85. }
  86.  
  87. // Pause all the systems
  88. void pause() {
  89. paused = true;
  90. }
  91.  
  92.  
  93. // Resume all the systems
  94. void resume() {
  95. paused = false;
  96. }
  97.  
  98. private:
  99.  
  100. bool paused;
  101. };
  102.  
  103. }; /* namespace ecs */
  104.  
  105. #endif /* SYSTEM_MNGMT_H */

最后是测试代码

  1. //
  2. // main.cpp
  3. //
  4. #ifdef WIN32
  5. // Refer:
  6. // http ://www.cnblogs.com/skynet/archive/2011/02/20/1959162.html
  7. #define _CRTDBG_MAP_ALLOC
  8. #include <stdlib.h>
  9. #include <crtdbg.h>
  10. #else
  11. #include <stdlib.h>
  12. #endif
  13.  
  14. #include <assert.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17.  
  18. #include "model/GameStencil.h"
  19.  
  20. using namespace ecs;
  21.  
  22. void usage()
  23. {
  24. SIPtr<IGameStencil> spGame;
  25. GameStencil::createInstance(thread_ctx_single,spGame.iid(),(void**) &spGame);
  26.  
  27. SIPtr<ISystemMngmt> spSysMngmt;
  28. spGame->query(spSysMngmt.iid(),(void**) &spSysMngmt);
  29.  
  30. SIPtr<IGameStencil> spGame2;
  31. spSysMngmt->query(spGame2.iid(),(void**) &spGame2);
  32.  
  33. assert(spGame2.get() == spGame.get());
  34.  
  35. spSysMngmt->update(0.1f);
  36. }
  37.  
  38.  
  39. int main()
  40. {
  41. #ifdef _CRTDBG_MAP_ALLOC
  42. _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
  43. #endif
  44.  
  45. printf("main.cpp start\n");
  46.  
  47. usage();
  48.  
  49. printf("main.cpp exit.\n");
  50. return 0;
  51. }
没有内存泄露。OK!

猜你在找的设计模式相关文章