module.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _MODULE_H_
  23. #define _MODULE_H_
  24. #ifndef _TSINGLETON_H_
  25. #include "core/util/tSingleton.h"
  26. #endif
  27. #ifndef _TVECTOR_H_
  28. #include "core/util/tVector.h"
  29. #endif
  30. /// @file
  31. /// A system for keeping initialization and shutdown modular while
  32. /// avoiding non-trivial global constructors/destructors.
  33. /// An engine component that requires initialization and/or cleanup.
  34. class Module
  35. {
  36. public:
  37. typedef void Parent;
  38. friend struct EngineModuleManager;
  39. protected:
  40. struct Dependency;
  41. friend struct Dependency;
  42. enum Mode
  43. {
  44. ModeInitialize,
  45. ModeShutdown
  46. };
  47. /// Direction of a dependency edge.
  48. enum DependencyType
  49. {
  50. DependencyBefore,
  51. DependencyAfter
  52. };
  53. /// Entry in the list of dependencies.
  54. struct Dependency
  55. {
  56. /// Direction of dependence. A "before" dependence goes the reverse direction.
  57. DependencyType mType;
  58. /// Name of the module that this module depends on.
  59. const char* mModuleName;
  60. /// Pointer to module. Filled by init code.
  61. Module* mModule;
  62. /// Next dependency or NULL.
  63. Dependency* mNext;
  64. Dependency( Mode mode, DependencyType type, Module* parentModule, const char* moduleName )
  65. : mType( type ),
  66. mModuleName( moduleName ),
  67. mModule( NULL ),
  68. mNext( mode == ModeInitialize ? parentModule->mInitDependencies : parentModule->mShutdownDependencies )
  69. {
  70. if( mode == ModeInitialize )
  71. parentModule->mInitDependencies = this;
  72. else
  73. parentModule->mShutdownDependencies = this;
  74. }
  75. };
  76. /// Record for module that this module overrides.
  77. struct Override
  78. {
  79. /// Name of module being overridden.
  80. const char* mModuleName;
  81. /// Next override or NULL.
  82. Override* mNext;
  83. Override( Module* parentModule, const char* moduleName )
  84. : mModuleName( moduleName ),
  85. mNext( parentModule->mOverrides )
  86. {
  87. parentModule->mOverrides = this;
  88. }
  89. };
  90. /// Flag to make sure we don't shutdown modules that have not been initialized.
  91. bool mIsInitialized;
  92. /// Next module in the global module list.
  93. Module* mNext;
  94. /// List of modules to which the initialization of this module has dependency relations.
  95. Dependency* mInitDependencies;
  96. /// List of modules to which the shutdown of this module has dependency relations.
  97. Dependency* mShutdownDependencies;
  98. /// List of modules being overriden by this module.
  99. Override* mOverrides;
  100. /// Global list of modules.
  101. static Module* smFirst;
  102. /// Return true if this module is constrained to precede "module" in the given "mode".
  103. bool _constrainedToComeBefore( Module* module, Mode mode );
  104. /// Return true if this module is constrained to follow "module" in the given "mode".
  105. bool _constrainedToComeAfter( Module* module, Mode mode );
  106. ///
  107. Dependency* _getDependencies( Mode mode )
  108. {
  109. if( mode == ModeInitialize )
  110. return mInitDependencies;
  111. else
  112. return mShutdownDependencies;
  113. }
  114. Module()
  115. : mIsInitialized( false ),
  116. mNext( smFirst ),
  117. mInitDependencies( NULL ),
  118. mShutdownDependencies( NULL ),
  119. mOverrides( NULL )
  120. {
  121. smFirst = this;
  122. }
  123. public:
  124. /// Return the module name.
  125. virtual const char* getName() const = 0;
  126. /// Initialize the module. This is only called after all modules that this
  127. /// module depends on have been initialized.
  128. virtual void initialize() {}
  129. /// Shut down the module. This is called before any module that this module
  130. /// depends on have been shut down.
  131. virtual void shutdown() {}
  132. };
  133. /// Begin a module definition.
  134. ///
  135. /// @code
  136. /// MODULE_BEGIN( MyModule )
  137. ///
  138. /// MODULE_INIT_AFTER( Sim )
  139. /// MODULE_INIT_BEFORE( 3D )
  140. /// MODULE_SHUTDOWN_BEFORE( Sim )
  141. ///
  142. /// MODULE_INIT
  143. /// {
  144. /// // Init code...
  145. /// }
  146. ///
  147. /// MODULE_SHUTDOWN
  148. /// {
  149. /// // Cleanup code...
  150. /// }
  151. ///
  152. /// MODULE_END;
  153. /// @endcode
  154. #define MODULE_BEGIN( name ) \
  155. namespace { namespace _ ## name { \
  156. class _ModuleInst : public ::Module { \
  157. public: \
  158. typedef ::Module Parent; \
  159. static _ModuleInst smInstance; \
  160. virtual const char* getName() const { return #name; }
  161. /// Make sure this module is initialized before the module called "name".
  162. ///
  163. /// @code
  164. /// MODULE_BEGIN( MyModule )
  165. /// MODULE_INIT_BEFORE( MyOtherModule )
  166. /// MODULE_END;
  167. /// @endcode
  168. #define MODULE_INIT_BEFORE( name ) \
  169. struct _DepInitBefore ## name : public Parent::Dependency \
  170. { \
  171. _DepInitBefore ## name() \
  172. : Parent::Dependency( ModeInitialize, DependencyBefore, &smInstance, #name ) {} \
  173. } mDepInitBefore ## name;
  174. /// Make sure this module is initialized after the module called "name".
  175. ///
  176. /// @code
  177. /// MODULE_BEGIN( MyModule )
  178. /// MODULE_INIT_AFTER( MyOtherModule )
  179. /// MODULE_END;
  180. /// @endcode
  181. #define MODULE_INIT_AFTER( name ) \
  182. struct _DepInitAfter ## name : public Parent::Dependency \
  183. { \
  184. _DepInitAfter ## name() \
  185. : Parent::Dependency( ModeInitialize, DependencyAfter, &smInstance, #name ) {} \
  186. } mDepInitAfter ## name;
  187. /// Make sure this module is initialized before the module called "name".
  188. ///
  189. /// @code
  190. /// MODULE_BEGIN( MyModule )
  191. /// MODULE_SHUTDOWN_BEFORE( MyOtherModule )
  192. /// MODULE_END;
  193. /// @endcode
  194. #define MODULE_SHUTDOWN_BEFORE( name ) \
  195. struct _DepShutdownBefore ## name : public Parent::Dependency \
  196. { \
  197. _DepShutdownBefore ## name() \
  198. : Parent::Dependency( ModeShutdown, DependencyBefore, &smInstance, #name ) {} \
  199. } mDepShutdownBefore ## name;
  200. /// Make sure this module is initialized after the module called "name".
  201. ///
  202. /// @code
  203. /// MODULE_BEGIN( MyModule )
  204. /// MODULE_SHUTDOWN_AFTER( MyOtherModule )
  205. /// MODULE_END;
  206. /// @endcode
  207. #define MODULE_SHUTDOWN_AFTER( name ) \
  208. struct _DepShutdownAfter ## name : public Parent::Dependency \
  209. { \
  210. _DepShutdownAfter ## name() \
  211. : Parent::Dependency( ModeShutdown, DependencyAfter, &smInstance, #name ) {} \
  212. } mDepShutdownAfter ## name;
  213. /// Replace the given module in both the init and the shutdown sequence.
  214. ///
  215. /// @code
  216. /// MODULE_BEGIN( MyMoveManager )
  217. /// MODULE_OVERRIDE( MoveManager )
  218. /// MODULE_END;
  219. /// @endcode
  220. #define MODULE_OVERRIDE( name ) \
  221. struct _Override ## name : public Parent::Override \
  222. { \
  223. _Override ## name() \
  224. : Parent::Override( &smInstance, #name ) {} \
  225. } mOverride ## name;
  226. /// Define initialization code for the module.
  227. ///
  228. /// @code
  229. /// MODULE_BEGIN( MyModule )
  230. /// MODULE_INIT
  231. /// {
  232. /// // Init code goes here.
  233. /// }
  234. /// MODULE_END;
  235. /// @endcode
  236. #define MODULE_INIT \
  237. virtual void initialize()
  238. /// Define cleanup code for the module.
  239. ///
  240. /// @code
  241. /// MODULE_BEGIN( MyModule )
  242. /// MODULE_SHUTDOWN
  243. /// {
  244. /// // Cleanup code goes here.
  245. /// }
  246. /// MODULE_END;
  247. /// @endcode
  248. #define MODULE_SHUTDOWN \
  249. virtual void shutdown()
  250. /// Terminate a module definition.
  251. ///
  252. /// @code
  253. /// MODULE_BEGIN( MyModule )
  254. /// MODULE_END;
  255. /// @endcode
  256. #define MODULE_END \
  257. }; \
  258. _ModuleInst _ModuleInst::smInstance; \
  259. } }
  260. /// Used to define a function which will be called right
  261. /// after the named module is initialized.
  262. ///
  263. /// @code
  264. /// AFTER_MODULE_INIT( Sim )
  265. /// {
  266. /// Con::addVariable( "$myBool", TypeBool, &smMyBool );
  267. /// }
  268. /// @endcode
  269. ///
  270. #define AFTER_MODULE_INIT( name ) \
  271. namespace { \
  272. class _AfterModuleInit : public ::Module { \
  273. public: \
  274. typedef ::Module Parent; \
  275. static _AfterModuleInit smInstance; \
  276. virtual const char* getName() const { return "AFTER_MODULE_INIT( " #name " ) in " __FILE__; } \
  277. struct _DepInitAfter : public Parent::Dependency \
  278. { \
  279. _DepInitAfter() \
  280. : Parent::Dependency( ModeInitialize, DependencyAfter, &smInstance, #name ) {} \
  281. } mDepInitAfter; \
  282. virtual void initialize(); \
  283. }; \
  284. _AfterModuleInit _AfterModuleInit::smInstance; \
  285. } \
  286. void _AfterModuleInit::initialize()
  287. struct EngineModuleManager
  288. {
  289. /// Initialize all modules registered with the system.
  290. static void initializeSystem();
  291. /// Shutdown all modules registered with the system.
  292. static void shutdownSystem();
  293. /// Return the instance of the module called "name" or NULL if no such module is defined.
  294. static Module* findModule( const char* name );
  295. private:
  296. static Module* _findOverrideFor( Module* module );
  297. static String _moduleListToString( Vector< Module* >& moduleList );
  298. static void _printModuleList( Vector< Module* >& moduleList );
  299. static void _insertIntoModuleList( Module::Mode mode, Vector< Module* >& moduleList, Module* module );
  300. static S32 _getIndexOfModuleInList( Vector< Module* >& moduleList, Module* module );
  301. static S32 _getIndexOfModuleInList( Vector< Module* >& moduleList, const char* moduleName );
  302. static void _createModuleList( Module::Mode mode, Vector< Module* >& moduleList );
  303. };
  304. #endif // !_MODULE_H_