CmModule.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #pragma once
  2. #include "CmPrerequisitesUtil.h"
  3. #include "CmException.h"
  4. namespace CamelotFramework
  5. {
  6. /**
  7. * @brief Represents one engine module. Essentially it is a specialized type of singleton.
  8. * Module must be manually started up and shut down before and after use.
  9. *
  10. * TODO Low priority - Use variadic templates to automatically pass parameters so I may construct the object instance internally.
  11. * Right now I expect the caller to allocate the object using general memory allocator.
  12. */
  13. template <class T>
  14. class Module
  15. {
  16. public:
  17. /**
  18. * @brief Returns a reference to the module instance. Module has to have been started up
  19. * first otherwise an exception will be thrown.
  20. */
  21. static T& instance()
  22. {
  23. if(isShutDown)
  24. {
  25. CM_EXCEPT(InternalErrorException,
  26. "Trying to access a module but it hasn't been started up yet.");
  27. }
  28. if(isDestroyed)
  29. {
  30. CM_EXCEPT(InternalErrorException,
  31. "Trying to access a destroyed module.");
  32. }
  33. return *_instance;
  34. }
  35. /**
  36. * @brief Returns a pointer to the module instance. Module has to have been started up
  37. * first otherwise an exception will be thrown.
  38. */
  39. static T* instancePtr()
  40. {
  41. if(isShutDown)
  42. {
  43. CM_EXCEPT(InternalErrorException,
  44. "Trying to access a module but it hasn't been started up yet.");
  45. }
  46. if(isDestroyed)
  47. {
  48. CM_EXCEPT(InternalErrorException,
  49. "Trying to access a destroyed module.");
  50. }
  51. return _instance;
  52. }
  53. /**
  54. * @brief Starts up the module. You must provide an initialized instance of the module,
  55. * allocated using the general memory allocator.
  56. */
  57. static void startUp(T* inst)
  58. {
  59. if(!isShutDown)
  60. CM_EXCEPT(InternalErrorException, "Trying to start an already started module.");
  61. _instance = inst;
  62. isShutDown = false;
  63. ((Module*)_instance)->onStartUp();
  64. }
  65. /**
  66. * @brief Shuts down this module and frees any resources it is using.
  67. */
  68. static void shutDown()
  69. {
  70. if(isShutDown)
  71. {
  72. CM_EXCEPT(InternalErrorException,
  73. "Trying to shut down an already shut down module.");
  74. }
  75. ((Module*)_instance)->onShutDown();
  76. cm_delete(_instance);
  77. isShutDown = true;
  78. }
  79. /**
  80. * @brief Query if the module has been started.
  81. */
  82. static bool isStarted()
  83. {
  84. return !isShutDown && !isDestroyed;
  85. }
  86. protected:
  87. Module()
  88. {
  89. }
  90. virtual ~Module()
  91. {
  92. _instance = nullptr;
  93. isDestroyed = true;
  94. }
  95. Module(const Module&) { }
  96. Module& operator=(const Module&) { return *this; }
  97. /**
  98. * @brief Override if you want your module to be notified once it has been constructed and started.
  99. *
  100. * @note Useful when your module is polymorphic and you cannot perform
  101. * some implementation specific initialization in constructor itself.
  102. */
  103. virtual void onStartUp() {}
  104. /**
  105. * @brief Override if you want your module to be notified just before it is deleted.
  106. *
  107. * @note Useful when your module is polymorphic and you might want to perform some
  108. * kind of clean up perhaps overriding that of a base class.
  109. */
  110. virtual void onShutDown() {}
  111. static T* _instance;
  112. static bool isShutDown;
  113. static bool isDestroyed;
  114. };
  115. template <class T>
  116. T* Module<T>::_instance = nullptr;
  117. template <class T>
  118. bool Module<T>::isShutDown = true;
  119. template <class T>
  120. bool Module<T>::isDestroyed = false;
  121. }