Skip to content

Commit

Permalink
#5231: Change StaticModule implementation such that it doesn't immedi…
Browse files Browse the repository at this point in the history
…ately 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.
  • Loading branch information
codereader committed Apr 27, 2020
1 parent 1ce60d2 commit 40c73d7
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 10 deletions.
1 change: 1 addition & 0 deletions radiant/Makefile.am
Expand Up @@ -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 \
Expand Down
10 changes: 10 additions & 0 deletions radiant/modulesystem/ModuleRegistry.cpp
Expand Up @@ -5,6 +5,7 @@
#include <stdexcept>
#include <iostream>
#include "ApplicationContextImpl.h"
#include "StaticModule.h"

#include <wx/app.h>
#include <fmt/format.h>
Expand Down Expand Up @@ -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/
Expand Down
44 changes: 44 additions & 0 deletions radiant/modulesystem/StaticModule.cpp
@@ -0,0 +1,44 @@
#include "StaticModule.h"

#include <cassert>

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<void(const RegisterableModulePtr&)>& func)
{
for (const auto& module : Instance())
{
func(module);
}
}

void StaticModuleList::Clear()
{
Instance().clear();
}

StaticModuleList& StaticModuleList::Instance()
{
static StaticModuleList _list;
return _list;
}

}

}
48 changes: 38 additions & 10 deletions radiant/modulesystem/StaticModule.h
Expand Up @@ -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.
*
Expand All @@ -21,25 +22,52 @@
namespace module
{

namespace internal
{

/**
* Static container holding the modules registered by
* the StaticModule<T> helper. They will be picked up
* and acquired by the ModuleRegistry, after which point
* this list will be cleared.
*/
class StaticModuleList :
private std::list<RegisterableModulePtr>
{
public:
~StaticModuleList();

static void Add(const RegisterableModulePtr& module);

static void ForEachModule(const std::function<void(const RegisterableModulePtr&)>& func);

static void Clear();

private:
static StaticModuleList& Instance();
};

}

template <class ModuleType>
class StaticModule
{
static_assert(std::is_base_of<RegisterableModule, ModuleType>::value, "ModuleType must be of type RegisterableModule");

// Define a std::shared_ptr for the given class type
typedef std::shared_ptr<ModuleType> ModuleTypePtr;
private:
std::string _moduleName;

public:
// The constructor
StaticModule()
{
ModuleTypePtr module(new ModuleType());
auto module = std::make_shared<ModuleType>();
_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<ModuleType> getModule()
{
return std::static_pointer_cast<ModuleType>(
ModuleRegistry::Instance().getModule(_moduleName)
Expand Down
1 change: 1 addition & 0 deletions tools/msvc/DarkRadiant.vcxproj
Expand Up @@ -732,6 +732,7 @@
<ClCompile Include="..\..\radiant\model\NullModel.cpp" />
<ClCompile Include="..\..\radiant\model\NullModelNode.cpp" />
<ClCompile Include="..\..\radiant\model\ScaledModelExporter.cpp" />
<ClCompile Include="..\..\radiant\modulesystem\StaticModule.cpp" />
<ClCompile Include="..\..\radiant\namespace\ComplexName.cpp" />
<ClCompile Include="..\..\radiant\particles\editor\ParticleEditor.cpp" />
<ClCompile Include="..\..\radiant\particles\ParticleDef.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions tools/msvc/DarkRadiant.vcxproj.filters
Expand Up @@ -1612,6 +1612,9 @@
<ClCompile Include="..\..\radiant\model\ModelScalePreserver.cpp">
<Filter>src\model</Filter>
</ClCompile>
<ClCompile Include="..\..\radiant\modulesystem\StaticModule.cpp">
<Filter>src\modulesystem</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\radiant\RadiantModule.h">
Expand Down

0 comments on commit 40c73d7

Please sign in to comment.