I have a feature registration implementation, wherein new features can be added to the registry with a simple macro.
However, I want to follow Open-closed principle and NOT have to change the the main.cpp whenever a new feature is created, as their implementation details are not relevant for main.cpp.
The issue lies in the #include
directive: If a feature file is not #included
, the index for it does not exist in the scope. This is because each TYPE##Registered value exists only inside each header file, not inside the Register.h. But how can I get around this limitation?
To reiterate the question, How can I register features without modifying main.cpp for every new feature added?
main.cpp:
#include "Foo.h" // Must include, otherwise won't show up in registry!
#include "Bar.h"
int main()
{
for (auto it : FeatureRegistry::GetInstance().GetFeatureRegistry())
{
printf(" registry: %s", it.first);
}
return 0;
}
Registry.h:
#pragma once
#include <cstddef>
#include <map>
#include <utility>
#define TYPE_REGISTER_ERROR 255 // Value not found in TypeRegistry
// Registers type into GlobalTypeRegistry
#define ENGINE_REGISTER_FEATURE(TYPE) class TYPE; static bool TYPE##Registered = \
(FeatureRegistry::GetInstance().GetFeatureRegistry()[#TYPE] = \
FeatureRegistry::GetInstance().GetFeatureRegistry().size(), true);
class FeatureRegistry
{
public:
static FeatureRegistry& GetInstance()
{
static FeatureRegistry Instance;
return Instance;
}
std::map<const char*, unsigned char>& GetFeatureRegistry()
{
static std::map<const char*, unsigned char> Registry;
return Registry;
}
// Returns the value of the type in TypeRegistryMap
unsigned char GetTypeIndex(const char* Classname)
{
auto it = GetFeatureRegistry().find(Classname);
if (it != GetFeatureRegistry().end())
{
return it->second;
}
// Return a default value if the type is not found
return TYPE_REGISTER_ERROR;
}
};
#define TypeIndex(TYPE) \
([] { \
class TYPE; \
return FeatureRegistry::GetInstance().GetTypeIndex(#TYPE); \
})()
Foo.h (Bar.h is identical)
#pragma once
#include "Register.h"
ENGINE_REGISTER_FEATURE(Foo)
class Foo
{
};
Aucun commentaire:
Enregistrer un commentaire