]> git.saurik.com Git - wxWidgets.git/blame - src/common/module.cpp
skip apple options
[wxWidgets.git] / src / common / module.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
32d4c30a 2// Name: src/common/module.cpp
c801d85f
KB
3// Purpose: Modules initialization/destruction
4// Author: Wolfram Gloger/adapted by Guilhem Lavaux
5// Modified by:
6// Created: 04/11/98
c801d85f 7// Copyright: (c) Wolfram Gloger and Guilhem Lavaux
65571936 8// Licence: wxWindows licence
c801d85f
KB
9/////////////////////////////////////////////////////////////////////////////
10
c801d85f
KB
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
32d4c30a
WS
15 #pragma hdrstop
16#endif
17
88a7a4e1
WS
18#include "wx/module.h"
19
32d4c30a
WS
20#ifndef WX_PRECOMP
21 #include "wx/hash.h"
88a7a4e1 22 #include "wx/intl.h"
e4db172a 23 #include "wx/log.h"
c801d85f
KB
24#endif
25
642c0eda 26#include "wx/listimpl.cpp"
8aa4edd2 27
9a83f860 28#define TRACE_MODULE wxT("module")
3b96fc2f 29
4115960d 30WX_DEFINE_LIST(wxModuleList)
c801d85f 31
e765d7ee 32wxIMPLEMENT_ABSTRACT_CLASS(wxModule, wxObject)
c801d85f 33
8aa4edd2 34wxModuleList wxModule::m_modules;
c801d85f
KB
35
36void wxModule::RegisterModule(wxModule* module)
37{
af266e5b 38 module->m_state = State_Registered;
8aa4edd2 39 m_modules.Append(module);
c801d85f
KB
40}
41
0b9ab0bd
RL
42void wxModule::UnregisterModule(wxModule* module)
43{
44 m_modules.DeleteObject(module);
df5168c4 45 delete module;
0b9ab0bd
RL
46}
47
c801d85f
KB
48// Collect up all module-derived classes, create an instance of each,
49// and register them.
8aa4edd2 50void wxModule::RegisterModules()
c801d85f 51{
644cb537
MB
52 for (wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo(),
53 end = wxClassInfo::end_classinfo();
54 it != end; ++it)
c801d85f 55 {
644cb537
MB
56 const wxClassInfo* classInfo = *it;
57
80a46597 58 if ( classInfo->IsKindOf(wxCLASSINFO(wxModule)) &&
644cb537 59 (classInfo != (& (wxModule::ms_classInfo))) )
c801d85f 60 {
3b96fc2f
MB
61 wxLogTrace(TRACE_MODULE, wxT("Registering module %s"),
62 classInfo->GetClassName());
8aa4edd2 63 wxModule* module = (wxModule *)classInfo->CreateObject();
644cb537 64 wxModule::RegisterModule(module);
c801d85f 65 }
c801d85f 66 }
c801d85f
KB
67}
68
af266e5b
VZ
69bool wxModule::DoInitializeModule(wxModule *module,
70 wxModuleList &initializedModules)
c801d85f 71{
af266e5b 72 if ( module->m_state == State_Initializing )
c801d85f 73 {
af266e5b
VZ
74 wxLogError(_("Circular dependency involving module \"%s\" detected."),
75 module->GetClassInfo()->GetClassName());
76 return false;
77 }
78
79 module->m_state = State_Initializing;
80
d04a9fdf
VZ
81 // translate named dependencies to the normal ones first
82 if ( !module->ResolveNamedDependencies() )
83 return false;
84
af266e5b
VZ
85 const wxArrayClassInfo& dependencies = module->m_dependencies;
86
87 // satisfy module dependencies by loading them before the current module
88 for ( unsigned int i = 0; i < dependencies.size(); ++i )
89 {
90 wxClassInfo * cinfo = dependencies[i];
91
92 // Check if the module is already initialized
93 wxModuleList::compatibility_iterator node;
94 for ( node = initializedModules.GetFirst(); node; node = node->GetNext() )
8aa4edd2 95 {
af266e5b
VZ
96 if ( node->GetData()->GetClassInfo() == cinfo )
97 break;
98 }
99
100 if ( node )
101 {
102 // this dependency is already initialized, nothing to do
103 continue;
104 }
8c18c674 105
af266e5b
VZ
106 // find the module in the registered modules list
107 for ( node = m_modules.GetFirst(); node; node = node->GetNext() )
108 {
109 wxModule *moduleDep = node->GetData();
110 if ( moduleDep->GetClassInfo() == cinfo )
8aa4edd2 111 {
af266e5b
VZ
112 if ( !DoInitializeModule(moduleDep, initializedModules ) )
113 {
114 // failed to initialize a dependency, so fail this one too
115 return false;
116 }
117
118 break;
8aa4edd2 119 }
af266e5b 120 }
8aa4edd2 121
af266e5b
VZ
122 if ( !node )
123 {
124 wxLogError(_("Dependency \"%s\" of module \"%s\" doesn't exist."),
125 cinfo->GetClassName(),
126 module->GetClassInfo()->GetClassName());
4e32eea1 127 return false;
8aa4edd2 128 }
c801d85f 129 }
8aa4edd2 130
af266e5b
VZ
131 if ( !module->Init() )
132 {
133 wxLogError(_("Module \"%s\" initialization failed"),
134 module->GetClassInfo()->GetClassName());
135 return false;
136 }
137
138 wxLogTrace(TRACE_MODULE, wxT("Module \"%s\" initialized"),
139 module->GetClassInfo()->GetClassName());
140
141 module->m_state = State_Initialized;
142 initializedModules.Append(module);
143
4e32eea1 144 return true;
c801d85f
KB
145}
146
af266e5b
VZ
147// Initialize user-defined modules
148bool wxModule::InitializeModules()
c801d85f 149{
af266e5b
VZ
150 wxModuleList initializedModules;
151
152 for ( wxModuleList::compatibility_iterator node = m_modules.GetFirst();
153 node;
154 node = node->GetNext() )
155 {
156 wxModule *module = node->GetData();
157
158 // the module could have been already initialized as dependency of
159 // another one
160 if ( module->m_state == State_Registered )
161 {
162 if ( !DoInitializeModule( module, initializedModules ) )
163 {
164 // failed to initialize all modules, so clean up the already
165 // initialized ones
166 DoCleanUpModules(initializedModules);
167
168 return false;
169 }
170 }
171 }
172
173 // remember the real initialisation order
174 m_modules = initializedModules;
175
176 return true;
177}
178
179// Clean up all currently initialized modules
180void wxModule::DoCleanUpModules(const wxModuleList& modules)
181{
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();
185 node;
186 node = node->GetPrevious() )
c801d85f 187 {
3b96fc2f
MB
188 wxLogTrace(TRACE_MODULE, wxT("Cleanup module %s"),
189 node->GetData()->GetClassInfo()->GetClassName());
af266e5b
VZ
190
191 wxModule * module = node->GetData();
192
193 wxASSERT_MSG( module->m_state == State_Initialized,
9a83f860 194 wxT("not initialized module being cleaned up") );
af266e5b
VZ
195
196 module->Exit();
197 module->m_state = State_Registered;
c801d85f 198 }
8aa4edd2 199
af266e5b 200 // clear all modules, even the non-initialized ones
df5168c4 201 WX_CLEAR_LIST(wxModuleList, m_modules);
c801d85f 202}
d04a9fdf
VZ
203
204bool wxModule::ResolveNamedDependencies()
205{
206 // first resolve required dependencies
207 for ( size_t i = 0; i < m_namedDependencies.size(); ++i )
208 {
209 wxClassInfo *info = wxClassInfo::FindClass(m_namedDependencies[i]);
210
211 if ( !info )
212 {
213 // required dependency not found
214 return false;
215 }
216
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);
221 }
222
223 return true;
224}