1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/module.cpp
3 // Purpose: Modules initialization/destruction
4 // Author: Wolfram Gloger/adapted by Guilhem Lavaux
8 // Copyright: (c) Wolfram Gloger and Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
19 #include "wx/module.h"
27 #include "wx/listimpl.cpp"
29 #define TRACE_MODULE _T("module")
31 WX_DEFINE_LIST(wxModuleList
)
33 IMPLEMENT_CLASS(wxModule
, wxObject
)
35 wxModuleList
wxModule::m_modules
;
37 void wxModule::RegisterModule(wxModule
* module)
39 module->m_state
= State_Registered
;
40 m_modules
.Append(module);
43 void wxModule::UnregisterModule(wxModule
* module)
45 m_modules
.DeleteObject(module);
49 // Collect up all module-derived classes, create an instance of each,
51 void wxModule::RegisterModules()
53 for (wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo(),
54 end
= wxClassInfo::end_classinfo();
57 const wxClassInfo
* classInfo
= *it
;
59 if ( classInfo
->IsKindOf(CLASSINFO(wxModule
)) &&
60 (classInfo
!= (& (wxModule::ms_classInfo
))) )
62 wxLogTrace(TRACE_MODULE
, wxT("Registering module %s"),
63 classInfo
->GetClassName());
64 wxModule
* module = (wxModule
*)classInfo
->CreateObject();
65 wxModule::RegisterModule(module);
70 bool wxModule::DoInitializeModule(wxModule
*module,
71 wxModuleList
&initializedModules
)
73 if ( module->m_state
== State_Initializing
)
75 wxLogError(_("Circular dependency involving module \"%s\" detected."),
76 module->GetClassInfo()->GetClassName());
80 module->m_state
= State_Initializing
;
82 const wxArrayClassInfo
& dependencies
= module->m_dependencies
;
84 // satisfy module dependencies by loading them before the current module
85 for ( unsigned int i
= 0; i
< dependencies
.size(); ++i
)
87 wxClassInfo
* cinfo
= dependencies
[i
];
89 // Check if the module is already initialized
90 wxModuleList::compatibility_iterator node
;
91 for ( node
= initializedModules
.GetFirst(); node
; node
= node
->GetNext() )
93 if ( node
->GetData()->GetClassInfo() == cinfo
)
99 // this dependency is already initialized, nothing to do
103 // find the module in the registered modules list
104 for ( node
= m_modules
.GetFirst(); node
; node
= node
->GetNext() )
106 wxModule
*moduleDep
= node
->GetData();
107 if ( moduleDep
->GetClassInfo() == cinfo
)
109 if ( !DoInitializeModule(moduleDep
, initializedModules
) )
111 // failed to initialize a dependency, so fail this one too
121 wxLogError(_("Dependency \"%s\" of module \"%s\" doesn't exist."),
122 cinfo
->GetClassName(),
123 module->GetClassInfo()->GetClassName());
128 if ( !module->Init() )
130 wxLogError(_("Module \"%s\" initialization failed"),
131 module->GetClassInfo()->GetClassName());
135 wxLogTrace(TRACE_MODULE
, wxT("Module \"%s\" initialized"),
136 module->GetClassInfo()->GetClassName());
138 module->m_state
= State_Initialized
;
139 initializedModules
.Append(module);
144 // Initialize user-defined modules
145 bool wxModule::InitializeModules()
147 wxModuleList initializedModules
;
149 for ( wxModuleList::compatibility_iterator node
= m_modules
.GetFirst();
151 node
= node
->GetNext() )
153 wxModule
*module = node
->GetData();
155 // the module could have been already initialized as dependency of
157 if ( module->m_state
== State_Registered
)
159 if ( !DoInitializeModule( module, initializedModules
) )
161 // failed to initialize all modules, so clean up the already
163 DoCleanUpModules(initializedModules
);
170 // remember the real initialisation order
171 m_modules
= initializedModules
;
176 // Clean up all currently initialized modules
177 void wxModule::DoCleanUpModules(const wxModuleList
& modules
)
179 // cleanup user-defined modules in the reverse order compared to their
180 // initialization -- this ensures that dependencies are respected
181 for ( wxModuleList::compatibility_iterator node
= modules
.GetLast();
183 node
= node
->GetPrevious() )
185 wxLogTrace(TRACE_MODULE
, wxT("Cleanup module %s"),
186 node
->GetData()->GetClassInfo()->GetClassName());
188 wxModule
* module = node
->GetData();
190 wxASSERT_MSG( module->m_state
== State_Initialized
,
191 _T("not initialized module being cleaned up") );
194 module->m_state
= State_Registered
;
197 // clear all modules, even the non-initialized ones
198 WX_CLEAR_LIST(wxModuleList
, m_modules
);