From 40c73d7d69aab1cf12eeee785db0e282f9f8155a Mon Sep 17 00:00:00 2001 From: codereader Date: Mon, 27 Apr 2020 13:17:28 +0200 Subject: [PATCH] #5231: Change StaticModule implementation such that it doesn't immediately register the statically enlisted modules. As long as we have the StaticModules, the ModuleRegistry will pick them up during loadAndInitialiseModules(), but ideally we wouldn't have any of these statically registered ones. --- radiant/Makefile.am | 1 + radiant/modulesystem/ModuleRegistry.cpp | 10 ++++++ radiant/modulesystem/StaticModule.cpp | 44 +++++++++++++++++++++++ radiant/modulesystem/StaticModule.h | 48 +++++++++++++++++++------ tools/msvc/DarkRadiant.vcxproj | 1 + tools/msvc/DarkRadiant.vcxproj.filters | 3 ++ 6 files changed, 97 insertions(+), 10 deletions(-) create mode 100644 radiant/modulesystem/StaticModule.cpp diff --git a/radiant/Makefile.am b/radiant/Makefile.am index 57b1e5f86e..bd4432e241 100644 --- a/radiant/Makefile.am +++ b/radiant/Makefile.am @@ -361,6 +361,7 @@ darkradiant_SOURCES = main.cpp \ modulesystem/ApplicationContextImpl.cpp \ modulesystem/ModuleLoader.cpp \ modulesystem/ModuleRegistry.cpp \ + modulesystem/StaticModule.cpp \ selection/SelectedNodeList.cpp \ selection/clipboard/Clipboard.cpp \ selection/shaderclipboard/ShaderClipboard.cpp \ diff --git a/radiant/modulesystem/ModuleRegistry.cpp b/radiant/modulesystem/ModuleRegistry.cpp index 6a158b3049..58b5eca8a9 100644 --- a/radiant/modulesystem/ModuleRegistry.cpp +++ b/radiant/modulesystem/ModuleRegistry.cpp @@ -5,6 +5,7 @@ #include #include #include "ApplicationContextImpl.h" +#include "StaticModule.h" #include #include @@ -146,6 +147,15 @@ void ModuleRegistry::loadAndInitialiseModules() _sigModuleInitialisationProgress.emit(_("Searching for Modules"), 0.0f); + // Pick up all the statically registered modules + internal::StaticModuleList::ForEachModule([this](const RegisterableModulePtr& module) + { + registerModule(module); + }); + + // Be sure the list is cleared after registration + internal::StaticModuleList::Clear(); + rMessage() << "ModuleRegistry Compatibility Level is " << getCompatibilityLevel() << std::endl; // Invoke the ModuleLoad routine to load the DLLs from modules/ and plugins/ diff --git a/radiant/modulesystem/StaticModule.cpp b/radiant/modulesystem/StaticModule.cpp new file mode 100644 index 0000000000..30aecb7710 --- /dev/null +++ b/radiant/modulesystem/StaticModule.cpp @@ -0,0 +1,44 @@ +#include "StaticModule.h" + +#include + +namespace module +{ + +namespace internal +{ + +StaticModuleList::~StaticModuleList() +{ + // We assume that the list instance is cleared by the time the + // application is shut down + assert(empty()); +} + +void StaticModuleList::Add(const RegisterableModulePtr& module) +{ + Instance().push_back(module); +} + +void StaticModuleList::ForEachModule(const std::function& func) +{ + for (const auto& module : Instance()) + { + func(module); + } +} + +void StaticModuleList::Clear() +{ + Instance().clear(); +} + +StaticModuleList& StaticModuleList::Instance() +{ + static StaticModuleList _list; + return _list; +} + +} + +} diff --git a/radiant/modulesystem/StaticModule.h b/radiant/modulesystem/StaticModule.h index c34d9a0c0f..0e25c37053 100644 --- a/radiant/modulesystem/StaticModule.h +++ b/radiant/modulesystem/StaticModule.h @@ -4,15 +4,16 @@ #include "ModuleRegistry.h" /** - * greebo: Use this class to define a static RegisterableModule. + * greebo: Use a StaticModule to define a static RegisterableModule, + * which enlists itself automatically during application startup. * * The template parameter must be a RegisterModule class and * is automatically registered with the ModuleRegistry by * the StaticModule constructor. * - * If immediate registering is not desired, the constructor - * could add the incoming modules to a static std::list - * and another static routine would add the modules on demand. + * Since immediate registering is not desired, the constructor + * adds the incoming modules to a static std::list + * for a later routine to add the modules to the registry. * * Note: does NOT hold actual shared_ptrs of the RegisterableModule. * @@ -21,25 +22,52 @@ namespace module { +namespace internal +{ + +/** + * Static container holding the modules registered by + * the StaticModule helper. They will be picked up + * and acquired by the ModuleRegistry, after which point + * this list will be cleared. + */ +class StaticModuleList : + private std::list +{ +public: + ~StaticModuleList(); + + static void Add(const RegisterableModulePtr& module); + + static void ForEachModule(const std::function& func); + + static void Clear(); + +private: + static StaticModuleList& Instance(); +}; + +} + template class StaticModule { static_assert(std::is_base_of::value, "ModuleType must be of type RegisterableModule"); - // Define a std::shared_ptr for the given class type - typedef std::shared_ptr ModuleTypePtr; +private: std::string _moduleName; public: - // The constructor StaticModule() { - ModuleTypePtr module(new ModuleType()); + auto module = std::make_shared(); _moduleName = module->getName(); - ModuleRegistry::Instance().registerModule(module); + + // Add this to the list in the backend, it will be picked up later + internal::StaticModuleList::Add(module); } - inline ModuleTypePtr getModule() + inline std::shared_ptr getModule() { return std::static_pointer_cast( ModuleRegistry::Instance().getModule(_moduleName) diff --git a/tools/msvc/DarkRadiant.vcxproj b/tools/msvc/DarkRadiant.vcxproj index 0b98b5a378..5745219b96 100644 --- a/tools/msvc/DarkRadiant.vcxproj +++ b/tools/msvc/DarkRadiant.vcxproj @@ -732,6 +732,7 @@ + diff --git a/tools/msvc/DarkRadiant.vcxproj.filters b/tools/msvc/DarkRadiant.vcxproj.filters index f2523549e5..42d0b932ce 100644 --- a/tools/msvc/DarkRadiant.vcxproj.filters +++ b/tools/msvc/DarkRadiant.vcxproj.filters @@ -1612,6 +1612,9 @@ src\model + + src\modulesystem +