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