首先,我不是这个意思:
int Value = 3;
SomeFunction(3);
SomeFunction(Value);
相反,我的意思是:
Editor.h:(**不是**
#include Foo
)
#include "GameObjectFactory.h"
int main()
{
Object * Foo = SpawnGameObject("Foo");
printf("%i ", value);
SomeFunction(Foo, "value", "3"); // <- This is what I want to do!
printf("%i", value);
// Foo->value = 3;
// Does not work, not #included
}
结果:
0 3
你 CANNOT
#include Foo
:如果客户创建一个新的类 Bar,他们可能会给它一个 string name
,它不能在只处理 Foo 的 int value
变量的编辑器代码中编辑。这意味着客户端在添加新类时必须更改编辑器代码。 类必须按原样工作,不更改任何其他代码文件
正因为如此,
SomeFunction()
应该能够在instance-to-instance 的基础上更改客户给它的any any 变量:一个客户可能有两个值为 2 的 Foos,和三个值为 1。在这种情况下,编辑器应该能够生成五个 Foos 并根据例如它读取的文本文件为它们赋予适当的值。
我知道这可能需要大量重新格式化。没事儿。只要能这样就好了
上例相关代码:
Foo类:
#include "GameObjectFactory.h"
ENGINE_SPAWNABLE(Foo);
class Foo : GameObject
{
int value = 0;
};
GameObjectFactory.h:(基本工厂实现)
#pragma once
#include <functional>
#include <string>
#include <unordered_map>
#include "Object.h"
// Allows GameObject to be spawnable through SpawnGameObject. No need to use this if the class is never spawned through the engine
#define ENGINE_SPAWNABLE(CLASSNAME) \
class CLASSNAME; \
static bool CLASSNAME##Registered \
= (GameObjectFactory::GetInstance().GetGameObjectRegistry()[#CLASSNAME] = &GameObjectFactory::SpawnObject<CLASSNAME>, true)
// Registers the class with the factory's registry, and connects that to a templated SpawnGameObject function
// Spawns a class of selected name
#define SpawnGameObject GameObjectFactory::GetInstance().SpawnGameObjectByName
// Singleton game object factory
class GameObjectFactory
{
public:
// Gets instance of the simpleton
static GameObjectFactory& GetInstance()
{
static GameObjectFactory Instance;
return Instance;
}
// A templated function to spawn any registered GameObject
template <typename TObject>
static Object* SpawnObject()
{
return new TObject();
}
// A factory function that spawns an object of the specified class name
Object* SpawnGameObjectByName(const std::string& Name);
std::unordered_map<std::string, std::function<Object*()>> &GetGameObjectRegistry(); // Returns the Registry of class names
private:
std::unordered_map<std::string, std::function<Object*()>> Registry; // Registry that maps class names to factory functions
};