added possibility to specify modules dependencies

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39677 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-06-11 22:19:12 +00:00
parent dc26eeb36a
commit af266e5bf7
5 changed files with 277 additions and 34 deletions

View File

@@ -36,6 +36,7 @@ wxModuleList wxModule::m_modules;
void wxModule::RegisterModule(wxModule* module)
{
module->m_state = State_Registered;
m_modules.Append(module);
}
@@ -69,42 +70,133 @@ void wxModule::RegisterModules()
}
}
bool wxModule::InitializeModules()
bool wxModule::DoInitializeModule(wxModule *module,
wxModuleList &initializedModules)
{
// Initialize user-defined modules
wxModuleList::compatibility_iterator node;
for ( node = m_modules.GetFirst(); node; node = node->GetNext() )
if ( module->m_state == State_Initializing )
{
wxModule *module = node->GetData();
if ( !module->Init() )
wxLogError(_("Circular dependency involving module \"%s\" detected."),
module->GetClassInfo()->GetClassName());
return false;
}
module->m_state = State_Initializing;
const wxArrayClassInfo& dependencies = module->m_dependencies;
// satisfy module dependencies by loading them before the current module
for ( unsigned int i = 0; i < dependencies.size(); ++i )
{
wxClassInfo * cinfo = dependencies[i];
// Check if the module is already initialized
wxModuleList::compatibility_iterator node;
for ( node = initializedModules.GetFirst(); node; node = node->GetNext() )
{
wxLogError(_("Module \"%s\" initialization failed"),
module->GetClassInfo()->GetClassName());
if ( node->GetData()->GetClassInfo() == cinfo )
break;
}
// clean up already initialized modules - process in reverse order
wxModuleList::compatibility_iterator n;
for ( n = node->GetPrevious(); n; n = n->GetPrevious() )
if ( node )
{
// this dependency is already initialized, nothing to do
continue;
}
// find the module in the registered modules list
for ( node = m_modules.GetFirst(); node; node = node->GetNext() )
{
wxModule *moduleDep = node->GetData();
if ( moduleDep->GetClassInfo() == cinfo )
{
n->GetData()->OnExit();
}
if ( !DoInitializeModule(moduleDep, initializedModules ) )
{
// failed to initialize a dependency, so fail this one too
return false;
}
break;
}
}
if ( !node )
{
wxLogError(_("Dependency \"%s\" of module \"%s\" doesn't exist."),
cinfo->GetClassName(),
module->GetClassInfo()->GetClassName());
return false;
}
}
if ( !module->Init() )
{
wxLogError(_("Module \"%s\" initialization failed"),
module->GetClassInfo()->GetClassName());
return false;
}
wxLogTrace(TRACE_MODULE, wxT("Module \"%s\" initialized"),
module->GetClassInfo()->GetClassName());
module->m_state = State_Initialized;
initializedModules.Append(module);
return true;
}
void wxModule::CleanUpModules()
// Initialize user-defined modules
bool wxModule::InitializeModules()
{
// Cleanup user-defined modules
wxModuleList::compatibility_iterator node;
for ( node = m_modules.GetFirst(); node; node = node->GetNext() )
wxModuleList initializedModules;
for ( wxModuleList::compatibility_iterator node = m_modules.GetFirst();
node;
node = node->GetNext() )
{
wxModule *module = node->GetData();
// the module could have been already initialized as dependency of
// another one
if ( module->m_state == State_Registered )
{
if ( !DoInitializeModule( module, initializedModules ) )
{
// failed to initialize all modules, so clean up the already
// initialized ones
DoCleanUpModules(initializedModules);
return false;
}
}
}
// remember the real initialisation order
m_modules = initializedModules;
return true;
}
// Clean up all currently initialized modules
void wxModule::DoCleanUpModules(const wxModuleList& modules)
{
// cleanup user-defined modules in the reverse order compared to their
// initialization -- this ensures that dependencies are respected
for ( wxModuleList::compatibility_iterator node = modules.GetLast();
node;
node = node->GetPrevious() )
{
wxLogTrace(TRACE_MODULE, wxT("Cleanup module %s"),
node->GetData()->GetClassInfo()->GetClassName());
node->GetData()->Exit();
wxModule * module = node->GetData();
wxASSERT_MSG( module->m_state == State_Initialized,
_T("not initialized module being cleaned up") );
module->Exit();
module->m_state = State_Registered;
}
// clear all modules, even the non-initialized ones
WX_CLEAR_LIST(wxModuleList, m_modules);
}