singletonmodule.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(INCLUDED_MODULESYSTEM_SINGLETONMODULE_H)
00023 #define INCLUDED_MODULESYSTEM_SINGLETONMODULE_H
00024
00025 #include "modulesystem.h"
00026 #include <cstddef>
00027 #include "debugging/debugging.h"
00028 #include "modulesystem/moduleregistry.h"
00029 #include "generic/reference.h"
00030
00031 template<typename API, typename Dependencies>
00032 class DefaultAPIConstructor
00033 {
00034 public:
00035 const char* getName ()
00036 {
00037 return typename API::Name();
00038 }
00039
00040 API* constructAPI (Dependencies& dependencies)
00041 {
00042 return new API;
00043 }
00044 void destroyAPI (API* api)
00045 {
00046 delete api;
00047 }
00048 };
00049
00050 template<typename API, typename Dependencies>
00051 class DependenciesAPIConstructor
00052 {
00053 public:
00054 const char* getName ()
00055 {
00056 return typename API::Name();
00057 }
00058
00059 API* constructAPI (Dependencies& dependencies)
00060 {
00061 return new API(dependencies);
00062 }
00063 void destroyAPI (API* api)
00064 {
00065 delete api;
00066 }
00067 };
00068
00069 class NullDependencies
00070 {
00071 };
00072
00073 template<typename API, typename Dependencies = NullDependencies, typename APIConstructor = DefaultAPIConstructor<API,
00074 Dependencies> >
00075 class SingletonModule: public APIConstructor, public Module, public ModuleRegisterable
00076 {
00077 Dependencies* m_dependencies;
00078 API* m_api;
00079 std::size_t m_refcount;
00080 bool m_dependencyCheck;
00081 bool m_cycleCheck;
00082 public:
00083 typedef typename API::Type Type;
00084
00085 SingletonModule () :
00086 m_dependencies(0), m_api(0), m_refcount(0), m_dependencyCheck(false), m_cycleCheck(false)
00087 {
00088 }
00089 explicit SingletonModule (const APIConstructor& constructor) :
00090 APIConstructor(constructor), m_dependencies(0), m_api(0), m_refcount(0), m_dependencyCheck(false),
00091 m_cycleCheck(false)
00092 {
00093 }
00094 virtual ~SingletonModule ()
00095 {
00096 ASSERT_MESSAGE(m_refcount == 0, "module still referenced at shutdown");
00097 }
00098
00099 void selfRegister ()
00100 {
00101 globalModuleServer().registerModule(typename Type::Name(), typename Type::Version(),
00102 APIConstructor::getName(), *this);
00103 }
00104
00105 Dependencies& getDependencies ()
00106 {
00107 return *m_dependencies;
00108 }
00109 void* getTable ()
00110 {
00111 if (m_api != 0) {
00112 return m_api->getTable();
00113 }
00114 return 0;
00115 }
00116 void capture ()
00117 {
00118 if (++m_refcount == 1) {
00119 globalOutputStream() << "Module Initialising: '" << typename Type::Name() << "' '"
00120 << APIConstructor::getName() << "'\n";
00121 m_dependencies = new Dependencies();
00122 m_dependencyCheck = !globalModuleServer().getError();
00123 if (m_dependencyCheck) {
00124 m_api = APIConstructor::constructAPI(*m_dependencies);
00125 globalOutputStream() << "Module Ready: '" << typename Type::Name() << "' '"
00126 << APIConstructor::getName() << "'\n";
00127 } else {
00128 globalOutputStream() << "Module Dependencies Failed: '" << typename Type::Name() << "' '"
00129 << APIConstructor::getName() << "'\n";
00130 }
00131 m_cycleCheck = true;
00132 }
00133
00134 ASSERT_MESSAGE(m_cycleCheck, "cyclic dependency detected");
00135 }
00136 void release ()
00137 {
00138 if (--m_refcount == 0) {
00139 if (m_dependencyCheck) {
00140 APIConstructor::destroyAPI(m_api);
00141 }
00142 delete m_dependencies;
00143 }
00144 }
00145 };
00146
00147 #endif