1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/module.cpp
3 // Purpose: Modules initialization/destruction
4 // Author: Wolfram Gloger/adapted by Guilhem Lavaux
7 // Copyright: (c) Wolfram Gloger and Guilhem Lavaux
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
18 #include "wx/module.h"
26 #include "wx/listimpl.cpp"
28 #define TRACE_MODULE wxT("module")
30 WX_DEFINE_LIST(wxModuleList
)
32 wxIMPLEMENT_ABSTRACT_CLASS(wxModule
, wxObject
)
34 wxModuleList
wxModule::m_modules
;
36 void wxModule::RegisterModule(wxModule
* module)
38 module->m_state
= State_Registered
;
39 m_modules
.Append(module);
42 void wxModule::UnregisterModule(wxModule
* module)
44 m_modules
.DeleteObject(module);
48 // Collect up all module-derived classes, create an instance of each,
50 void wxModule::RegisterModules()
52 for (wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo(),
53 end
= wxClassInfo::end_classinfo();
56 const wxClassInfo
* classInfo
= *it
;
58 if ( classInfo
->IsKindOf(wxCLASSINFO(wxModule
)) &&
59 (classInfo
!= (& (wxModule::ms_classInfo
))) )
61 wxLogTrace(TRACE_MODULE
, wxT("Registering module %s"),
62 classInfo
->GetClassName());
63 wxModule
* module = (wxModule
*)classInfo
->CreateObject();
64 wxModule::RegisterModule(module);
69 bool wxModule::DoInitializeModule(wxModule
*module,
70 wxModuleList
&initializedModules
)
72 if ( module->m_state
== State_Initializing
)
74 wxLogError(_("Circular dependency involving module \"%s\" detected."),
75 module->GetClassInfo()->GetClassName());
79 module->m_state
= State_Initializing
;
81 // translate named dependencies to the normal ones first
82 if ( !module->ResolveNamedDependencies() )
85 const wxArrayClassInfo
& dependencies
= module->m_dependencies
;
87 // satisfy module dependencies by loading them before the current module
88 for ( unsigned int i
= 0; i
< dependencies
.size(); ++i
)
90 wxClassInfo
* cinfo
= dependencies
[i
];
92 // Check if the module is already initialized
93 wxModuleList::compatibility_iterator node
;
94 for ( node
= initializedModules
.GetFirst(); node
; node
= node
->GetNext() )
96 if ( node
->GetData()->GetClassInfo() == cinfo
)
102 // this dependency is already initialized, nothing to do
106 // find the module in the registered modules list
107 for ( node
= m_modules
.GetFirst(); node
; node
= node
->GetNext() )
109 wxModule
*moduleDep
= node
->GetData();
110 if ( moduleDep
->GetClassInfo() == cinfo
)
112 if ( !DoInitializeModule(moduleDep
, initializedModules
) )
114 // failed to initialize a dependency, so fail this one too
124 wxLogError(_("Dependency \"%s\" of module \"%s\" doesn't exist."),
125 cinfo
->GetClassName(),
126 module->GetClassInfo()->GetClassName());
131 if ( !module->Init() )
133 wxLogError(_("Module \"%s\" initialization failed"),
134 module->GetClassInfo()->GetClassName());
138 wxLogTrace(TRACE_MODULE
, wxT("Module \"%s\" initialized"),
139 module->GetClassInfo()->GetClassName());
141 module->m_state
= State_Initialized
;
142 initializedModules
.Append(module);
147 // Initialize user-defined modules
148 bool wxModule::InitializeModules()
150 wxModuleList initializedModules
;
152 for ( wxModuleList::compatibility_iterator node
= m_modules
.GetFirst();
154 node
= node
->GetNext() )
156 wxModule
*module = node
->GetData();
158 // the module could have been already initialized as dependency of
160 if ( module->m_state
== State_Registered
)
162 if ( !DoInitializeModule( module, initializedModules
) )
164 // failed to initialize all modules, so clean up the already
166 DoCleanUpModules(initializedModules
);
173 // remember the real initialisation order
174 m_modules
= initializedModules
;
179 // Clean up all currently initialized modules
180 void wxModule::DoCleanUpModules(const wxModuleList
& modules
)
182 // cleanup user-defined modules in the reverse order compared to their
183 // initialization -- this ensures that dependencies are respected
184 for ( wxModuleList::compatibility_iterator node
= modules
.GetLast();
186 node
= node
->GetPrevious() )
188 wxLogTrace(TRACE_MODULE
, wxT("Cleanup module %s"),
189 node
->GetData()->GetClassInfo()->GetClassName());
191 wxModule
* module = node
->GetData();
193 wxASSERT_MSG( module->m_state
== State_Initialized
,
194 wxT("not initialized module being cleaned up") );
197 module->m_state
= State_Registered
;
200 // clear all modules, even the non-initialized ones
201 WX_CLEAR_LIST(wxModuleList
, m_modules
);
204 bool wxModule::ResolveNamedDependencies()
206 // first resolve required dependencies
207 for ( size_t i
= 0; i
< m_namedDependencies
.size(); ++i
)
209 wxClassInfo
*info
= wxClassInfo::FindClass(m_namedDependencies
[i
]);
213 // required dependency not found
217 // add it even if it is not derived from wxModule because
218 // DoInitializeModule() will make sure a module with the same class
219 // info exists and fail if it doesn't
220 m_dependencies
.Add(info
);