diff --git a/include/wx/module.h b/include/wx/module.h index 993f765e0f..1f107029aa 100644 --- a/include/wx/module.h +++ b/include/wx/module.h @@ -12,18 +12,11 @@ #define _WX_MODULE_H_ #include "wx/object.h" -#include "wx/list.h" -#include "wx/arrstr.h" -#include "wx/dynarray.h" +#include "wx/vector.h" -// declare a linked list of modules -class WXDLLIMPEXP_FWD_BASE wxModule; -WX_DECLARE_USER_EXPORTED_LIST(wxModule, wxModuleList, WXDLLIMPEXP_BASE); - -// and an array of class info objects -WX_DEFINE_USER_EXPORTED_ARRAY_PTR(wxClassInfo *, wxArrayClassInfo, - class WXDLLIMPEXP_BASE); +class wxModule; +typedef wxVector wxModuleList; // declaring a class derived from wxModule will automatically create an // instance of this class on program startup, call its OnInit() method and call @@ -54,14 +47,17 @@ public: static void RegisterModule(wxModule *module); static void RegisterModules(); static bool InitializeModules(); - static void CleanUpModules() { DoCleanUpModules(m_modules); } + static void CleanUpModules(); + static bool AreInitialized() { return ms_areInitialized; } // used by wxObjectLoader when unloading shared libs's static void UnregisterModule(wxModule *module); protected: - static wxModuleList m_modules; + static wxModuleList ms_modules; + + static bool ms_areInitialized; // the function to call from constructor of a deriving class add module // dependency which will be initialized before the module and unloaded @@ -70,14 +66,14 @@ protected: { wxCHECK_RET( dep, wxT("NULL module dependency") ); - m_dependencies.Add(dep); + m_dependencies.push_back(dep); } // same as the version above except it will look up wxClassInfo by name on // its own. Note that className must be ASCII void AddDependency(const char *className) { - m_namedDependencies.Add(wxASCII_STR(className)); + m_namedDependencies.push_back(wxASCII_STR(className)); } @@ -89,7 +85,7 @@ private: // cleanup the modules in the specified list (which may not contain all // modules if we're called during initialization because not all modules - // could be initialized) and also empty m_modules itself + // could be initialized) and also empty ms_modules itself static void DoCleanUpModules(const wxModuleList& modules); // resolve all named dependencies and add them to the normal m_dependencies @@ -98,11 +94,12 @@ private: // module dependencies: contains wxClassInfo pointers for all modules which // must be initialized before this one + typedef wxVector wxArrayClassInfo; wxArrayClassInfo m_dependencies; // and the named dependencies: those will be resolved during run-time and // added to m_dependencies - wxArrayString m_namedDependencies; + wxVector m_namedDependencies; // used internally while initializing/cleaning up modules enum diff --git a/src/common/module.cpp b/src/common/module.cpp index 994f3d8093..7344cfbd96 100644 --- a/src/common/module.cpp +++ b/src/common/module.cpp @@ -20,25 +20,32 @@ #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; +wxModuleList wxModule::ms_modules; +bool wxModule::ms_areInitialized = false; void wxModule::RegisterModule(wxModule* module) { module->m_state = State_Registered; - m_modules.Append(module); + ms_modules.push_back(module); } void wxModule::UnregisterModule(wxModule* module) { - m_modules.DeleteObject(module); + for ( wxModuleList::iterator it = ms_modules.begin(); + it != ms_modules.end(); + ++it ) + { + if ( *it == module ) + { + ms_modules.erase(it); + break; + } + } + delete module; } @@ -87,23 +94,25 @@ bool wxModule::DoInitializeModule(wxModule *module, wxClassInfo * cinfo = dependencies[i]; // Check if the module is already initialized - wxModuleList::compatibility_iterator node; - for ( node = initializedModules.GetFirst(); node; node = node->GetNext() ) + wxModuleList::const_iterator it; + for ( it = initializedModules.begin(); + it != initializedModules.end(); + ++it ) { - if ( node->GetData()->GetClassInfo() == cinfo ) + if ( (*it)->GetClassInfo() == cinfo ) break; } - if ( node ) + if ( it != initializedModules.end() ) { // 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() ) + for ( it = ms_modules.begin(); it != ms_modules.end(); ++it ) { - wxModule *moduleDep = node->GetData(); + wxModule *moduleDep = *it; if ( moduleDep->GetClassInfo() == cinfo ) { if ( !DoInitializeModule(moduleDep, initializedModules ) ) @@ -116,7 +125,7 @@ bool wxModule::DoInitializeModule(wxModule *module, } } - if ( !node ) + if ( it == ms_modules.end() ) { wxLogError(_("Dependency \"%s\" of module \"%s\" doesn't exist."), cinfo->GetClassName(), @@ -136,7 +145,7 @@ bool wxModule::DoInitializeModule(wxModule *module, module->GetClassInfo()->GetClassName()); module->m_state = State_Initialized; - initializedModules.Append(module); + initializedModules.push_back(module); return true; } @@ -146,11 +155,11 @@ bool wxModule::InitializeModules() { wxModuleList initializedModules; - for ( wxModuleList::compatibility_iterator node = m_modules.GetFirst(); - node; - node = node->GetNext() ) + for ( wxModuleList::const_iterator it = ms_modules.begin(); + it != ms_modules.end(); + ++it ) { - wxModule *module = node->GetData(); + wxModule *module = *it; // the module could have been already initialized as dependency of // another one @@ -168,24 +177,33 @@ bool wxModule::InitializeModules() } // remember the real initialisation order - m_modules = initializedModules; + ms_modules = initializedModules; + + ms_areInitialized = true; return true; } +void wxModule::CleanUpModules() +{ + DoCleanUpModules(ms_modules); + + ms_areInitialized = false; +} + // 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() ) + for ( wxModuleList::const_reverse_iterator rit = modules.rbegin(); + rit != modules.rend(); + ++rit ) { wxLogTrace(TRACE_MODULE, wxT("Cleanup module %s"), - node->GetData()->GetClassInfo()->GetClassName()); + (*rit)->GetClassInfo()->GetClassName()); - wxModule * module = node->GetData(); + wxModule * module = *rit; wxASSERT_MSG( module->m_state == State_Initialized, wxT("not initialized module being cleaned up") ); @@ -195,7 +213,14 @@ void wxModule::DoCleanUpModules(const wxModuleList& modules) } // clear all modules, even the non-initialized ones - WX_CLEAR_LIST(wxModuleList, m_modules); + for ( wxModuleList::const_iterator it = ms_modules.begin(); + it != ms_modules.end(); + ++it ) + { + delete *it; + } + + ms_modules.clear(); } bool wxModule::ResolveNamedDependencies() @@ -214,7 +239,7 @@ bool wxModule::ResolveNamedDependencies() // 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); + m_dependencies.push_back(info); } return true; diff --git a/tests/misc/module.cpp b/tests/misc/module.cpp index efb8d64cf7..24ee867e28 100644 --- a/tests/misc/module.cpp +++ b/tests/misc/module.cpp @@ -15,16 +15,18 @@ #include "wx/module.h" #include "wx/wxcrt.h" // for wxStrcat() +static bool gs_wasInitialized = wxModule::AreInitialized(); + // ---------------------------------------------------------------------------- // test classes derived from wxModule // ---------------------------------------------------------------------------- -char g_strLoadOrder[256] = "\0"; +wxString g_strLoadOrder; class Module : public wxModule { protected: - virtual bool OnInit() wxOVERRIDE { wxStrcat(g_strLoadOrder, GetClassInfo()->GetClassName()); return true; } + virtual bool OnInit() wxOVERRIDE { g_strLoadOrder += GetClassInfo()->GetClassName(); return true; } virtual void OnExit() wxOVERRIDE { } }; @@ -86,32 +88,17 @@ ModuleD::ModuleD() } // ---------------------------------------------------------------------------- -// test class +// tests themselves // ---------------------------------------------------------------------------- -class ModuleTestCase : public CppUnit::TestCase +TEST_CASE("wxModule::Initialized", "[module]") { -public: - ModuleTestCase() { } + CHECK( !gs_wasInitialized ); + CHECK( wxModule::AreInitialized() ); +} -private: - CPPUNIT_TEST_SUITE( ModuleTestCase ); - CPPUNIT_TEST( LoadOrder ); - CPPUNIT_TEST_SUITE_END(); - - void LoadOrder(); - wxDECLARE_NO_COPY_CLASS(ModuleTestCase); -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( ModuleTestCase ); - -// also include in its own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ModuleTestCase, "ModuleTestCase" ); - -void ModuleTestCase::LoadOrder() +TEST_CASE("wxModule::LoadOrder", "[module]") { // module D is the only one with no dependencies and so should load as first (and so on): - CPPUNIT_ASSERT_EQUAL( std::string("ModuleDModuleCModuleBModuleA"), - g_strLoadOrder ); + CHECK( g_strLoadOrder == "ModuleDModuleCModuleBModuleA" ); }