Files
wxWidgets/src/common/module.cpp
Vadim Zeitlin 3f66f6a5b3 Remove all lines containing cvs/svn "$Id$" keyword.
This keyword is not expanded by Git which means it's not replaced with the
correct revision value in the releases made using git-based scripts and it's
confusing to have lines with unexpanded "$Id$" in the released files. As
expanding them with Git is not that simple (it could be done with git archive
and export-subst attribute) and there are not many benefits in having them in
the first place, just remove all these lines.

If nothing else, this will make an eventual transition to Git simpler.

Closes #14487.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-07-26 16:02:46 +00:00

225 lines
6.4 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/common/module.cpp
// Purpose: Modules initialization/destruction
// Author: Wolfram Gloger/adapted by Guilhem Lavaux
// Modified by:
// Created: 04/11/98
// Copyright: (c) Wolfram Gloger and Guilhem Lavaux
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "wx/module.h"
#ifndef WX_PRECOMP
#include "wx/hash.h"
#include "wx/intl.h"
#include "wx/log.h"
#endif
#include "wx/listimpl.cpp"
#define TRACE_MODULE wxT("module")
WX_DEFINE_LIST(wxModuleList)
wxIMPLEMENT_ABSTRACT_CLASS(wxModule, wxObject)
wxModuleList wxModule::m_modules;
void wxModule::RegisterModule(wxModule* module)
{
module->m_state = State_Registered;
m_modules.Append(module);
}
void wxModule::UnregisterModule(wxModule* module)
{
m_modules.DeleteObject(module);
delete module;
}
// Collect up all module-derived classes, create an instance of each,
// and register them.
void wxModule::RegisterModules()
{
for (wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo(),
end = wxClassInfo::end_classinfo();
it != end; ++it)
{
const wxClassInfo* classInfo = *it;
if ( classInfo->IsKindOf(wxCLASSINFO(wxModule)) &&
(classInfo != (& (wxModule::ms_classInfo))) )
{
wxLogTrace(TRACE_MODULE, wxT("Registering module %s"),
classInfo->GetClassName());
wxModule* module = (wxModule *)classInfo->CreateObject();
wxModule::RegisterModule(module);
}
}
}
bool wxModule::DoInitializeModule(wxModule *module,
wxModuleList &initializedModules)
{
if ( module->m_state == State_Initializing )
{
wxLogError(_("Circular dependency involving module \"%s\" detected."),
module->GetClassInfo()->GetClassName());
return false;
}
module->m_state = State_Initializing;
// translate named dependencies to the normal ones first
if ( !module->ResolveNamedDependencies() )
return false;
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() )
{
if ( node->GetData()->GetClassInfo() == cinfo )
break;
}
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 )
{
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;
}
// Initialize user-defined modules
bool wxModule::InitializeModules()
{
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());
wxModule * module = node->GetData();
wxASSERT_MSG( module->m_state == State_Initialized,
wxT("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);
}
bool wxModule::ResolveNamedDependencies()
{
// first resolve required dependencies
for ( size_t i = 0; i < m_namedDependencies.size(); ++i )
{
wxClassInfo *info = wxClassInfo::FindClass(m_namedDependencies[i]);
if ( !info )
{
// required dependency not found
return false;
}
// add it even if it is not derived from wxModule because
// DoInitializeModule() will make sure a module with the same class
// info exists and fail if it doesn't
m_dependencies.Add(info);
}
return true;
}