#include "Factory.h"
#include "Object.h"
#include <iostream>
// Not required if Features are forcefully compiled into the project.
// It's better to not include anything so if we change Features, we don't change main.cpp
#include "Features.h"
using namespace std;
int main()
{
for (const auto& pair : Factory::GetInstance().GetFeatureMap())
{
printf("Key: %s, Value: %i\n", pair.second.c_str(), pair.first);
}
Object* ExampleObject = new Object();
ExampleObject->FeatureList |= (1 << 0); // Spawn Feature1
ExampleObject->FeatureList |= (1 << 1); // Spawn Feature2
ExampleObject->FeatureList |= (1 << 2); // Spawn Feature3
ExampleObject->Initialize();
return 0;
}
#pragma once
#include <cstring>
#include <functional>
#include <string>
#include <unordered_map>
#include "Component.h"
#define REGISTER_FEATURE(CLASSNAME) class CLASSNAME; \
static bool CLASSNAME##ComponentRegistered = \
(Factory::GetInstance().GetComponentRegistry()[#CLASSNAME] = \
std::bind(&Factory::SpawnComponent<CLASSNAME>), true); \
static bool CLASSNAME##FeatureRegistered = \
Factory::GetInstance().AddFeature(#CLASSNAME); \
static bool CLASSNAME##DamnRemoveThis = Factory::GetInstance().Print(#CLASSNAME);
class Component;
class Factory
{
public:
static Factory& GetInstance()
{
static Factory Instance;
return Instance;
}
std::unordered_map<int, std::string>& GetFeatureMap()
{
static std::unordered_map<int, std::string> Map;
return Map;
}
bool AddFeature(std::string Name)
{
GetFeatureMap()[GetFeatureMap().size()] = Name;
return true;
}
std::unordered_map<std::string, std::function<Component* ()>>& GetComponentRegistry()
{
static std::unordered_map<std::string, std::function<Component* ()>> ComponentRegistry;
return ComponentRegistry;
}
bool Print(std::string Name)
{
printf("Registered Feature: %s \n", Name.c_str());
return true;
}
// A templated function to spawn any registered Component
template <typename TObject>
static Component* SpawnComponent()
{
return new TObject();
}
// A factory function that spawns an object of the specified class name
Component* SpawnComponentByName(const std::string& ClassName, const char* Name = "");
};
#pragma once
#include "Component.h"
REGISTER_FEATURE(Feature1);
class Feature1 : public Component
{
public:
Feature1() : Component()
{
}
};
REGISTER_FEATURE(Feature2);
class Feature2 : public Component
{
};
REGISTER_FEATURE(Feature3);
class Feature3 : public Component
{
};
#include "Factory.h"
#include "Component.h"
Component* Factory::SpawnComponentByName(const std::string& ClassName, const char* Name)
{
auto it = GetComponentRegistry().find(ClassName);
if (it != GetComponentRegistry().end())
{
Component* comp = it->second();
comp->Name = Name;
return comp;
}
return nullptr;
}
#pragma once
#include <string>
// Base class so the factory works :)
class Component
{
public:
Component()
{
}
std::string Name;
};
#pragma once
#include "Factory.h"
#include <iostream>
const int MAX_FEATURES = 32; // Assuming each integer holds 32 bits (you can adjust this according to your implementation)
class Object
{
public:
Object()
{
}
void Initialize()
{
for (int i = 0; i < MAX_FEATURES; ++i)
{
// Spawn features that share bit locations
if ((FeatureList & (1 << i)))
{
auto Feature =
Factory::GetInstance().SpawnComponentByName(
Factory::GetInstance().GetFeatureMap()[i], Factory::GetInstance().GetFeatureMap()[i].c_str());
printf("Spawned feature corresponding with bit %i: %s \n", i, Feature->Name.c_str());
}
}
}
unsigned int FeatureList : MAX_FEATURES;
};