]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/module.cpp
[ 1509599 ] 'Split pickers page in widgets sample' with more icons and rebaking.
[wxWidgets.git] / src / common / module.cpp
... / ...
CommitLineData
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
31WX_DEFINE_LIST(wxModuleList)
32
33IMPLEMENT_CLASS(wxModule, wxObject)
34
35wxModuleList wxModule::m_modules;
36
37void wxModule::RegisterModule(wxModule* module)
38{
39 module->m_state = State_Registered;
40 m_modules.Append(module);
41}
42
43void 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.
51void wxModule::RegisterModules()
52{
53 wxHashTable::compatibility_iterator node;
54 wxClassInfo* classInfo;
55
56 wxClassInfo::sm_classTable->BeginFind();
57 node = wxClassInfo::sm_classTable->Next();
58 while (node)
59 {
60 classInfo = (wxClassInfo *)node->GetData();
61 if ( classInfo->IsKindOf(CLASSINFO(wxModule)) &&
62 (classInfo != (& (wxModule::ms_classInfo))) )
63 {
64 wxLogTrace(TRACE_MODULE, wxT("Registering module %s"),
65 classInfo->GetClassName());
66 wxModule* module = (wxModule *)classInfo->CreateObject();
67 RegisterModule(module);
68 }
69 node = wxClassInfo::sm_classTable->Next();
70 }
71}
72
73bool wxModule::DoInitializeModule(wxModule *module,
74 wxModuleList &initializedModules)
75{
76 if ( module->m_state == State_Initializing )
77 {
78 wxLogError(_("Circular dependency involving module \"%s\" detected."),
79 module->GetClassInfo()->GetClassName());
80 return false;
81 }
82
83 module->m_state = State_Initializing;
84
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() )
95 {
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 }
105
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 )
111 {
112 if ( !DoInitializeModule(moduleDep, initializedModules ) )
113 {
114 // failed to initialize a dependency, so fail this one too
115 return false;
116 }
117
118 break;
119 }
120 }
121
122 if ( !node )
123 {
124 wxLogError(_("Dependency \"%s\" of module \"%s\" doesn't exist."),
125 cinfo->GetClassName(),
126 module->GetClassInfo()->GetClassName());
127 return false;
128 }
129 }
130
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
144 return true;
145}
146
147// Initialize user-defined modules
148bool wxModule::InitializeModules()
149{
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() )
187 {
188 wxLogTrace(TRACE_MODULE, wxT("Cleanup module %s"),
189 node->GetData()->GetClassInfo()->GetClassName());
190
191 wxModule * module = node->GetData();
192
193 wxASSERT_MSG( module->m_state == State_Initialized,
194 _T("not initialized module being cleaned up") );
195
196 module->Exit();
197 module->m_state = State_Registered;
198 }
199
200 // clear all modules, even the non-initialized ones
201 WX_CLEAR_LIST(wxModuleList, m_modules);
202}