私は単純なメッセージパッシングエンティティシステムを作っています。私は、単純なswitch文することができます知っている、クラス情報を実行時にアクセス可能にする拡張可能な方法
今EntityManager manager; //managers have all of the entity table information (See below)
//Counter is a sample class that inherits from Entity
Counter* counter = manager.makeEntity("Counter"); //the string doesn't have to match the class name.
:私は、実行時にエンティティのサブクラスを作成するための工場にフックエンティティ記述子テーブルを持っている、と私は、彼らが文字列で作成することができるので、それを持ってしたいと思います私のシステムの他のユーザが新しいEntityサブクラスを作成したい場合、スイッチブロックに移動して追加する必要はありません。現在、マクロを使用してヘルパークラスを作成します。これを静的にインスタンス化し、コンストラクタがエンティティテーブルにエントリを追加します。これらのクラスはエンティティを初期化し、多くの定型文をコンストラクタから削除します。
//EHandle is a wrapper for Entity*. Currently std::shared_ptr<Entity>
class GenericDesc
{
public:
virtual ~GenericDesc() {}
virtual EHandle makeEntity() const =0;
};
namespace Descriptor
{
//Adds a descriptor to an internal map<string, GenericDesc*>
void addEntityDescriptor(const std::string& type, GenericDesc& desc);
EHandle newEntity(const std::string& type); //Factory method
}
//Add this to every entity class definition
#define DECLARE_ENTITY_CLASS(CLASS_NAME) \
friend class CLASS_NAME##Descriptor;
//Use these after a class definition to add the entity class to the descriptor table
#define BEGIN_ENTITY_TYPE(ENTITY_NAME, CLASS_NAME, BASE_NAME) \
BEGIN_ENTITY_TYPE_GUTS(ENTITY_NAME, CLASS_NAME) \
BASE_NAME##Descriptor::prepareEntity(ent);
#define BEGIN_ENTITY_TYPE_BASELESS(ENTITY_NAME, CLASS_NAME) \
BEGIN_ENTITY_TYPE_GUTS(ENTITY_NAME, CLASS_NAME) \
ent->self = ent;
#define BEGIN_ENTITY_TYPE_GUTS(ENTITY_NAME, CLASS_NAME) \
class CLASS_NAME##Descriptor : public GenericDesc \
{ \
private: \
typedef CLASS_NAME ClassName; \
public: \
CLASS_NAME##Descriptor() \
{ \
Descriptor::addEntityDescriptor(ENTITY_NAME, *this); \
} \
virtual ~CLASS_NAME##Descriptor() {} \
virtual EHandle makeEntity() const\
{ \
auto ent = std::shared_ptr<CLASS_NAME>(new CLASS_NAME); \
prepareEntity(ent); \
ent->type = ENTITY_NAME; \
return ent; \
} \
static void prepareEntity(std::shared_ptr<ClassName> ent) \
{
//These functions are caled between BEGIN_ENTITY_TYPE and END_ENTITY_TYPE
//ADD_ENTITY_INPUT binds a function to a string
#define ADD_ENTITY_INPUT(INPUT_NAME, INPUT_FUNC) \
ent->addInput(INPUT_NAME, std::bind(&ClassName::INPUT_FUNC, ent, std::placeholders::_1));
//ADD_ENTITY_OUTPUT binds an Output object to a string
#define ADD_ENTITY_OUTPUT(OUTPUT_NAME, OUTPUT_OBJECT) \
ent->addOutput(OUTPUT_NAME, ent->OUTPUT_OBJECT);
#define END_ENTITY_TYPE(CLASS_NAME) \
} \
}; \
static CLASS_NAME##Descriptor CLASS_NAME##Desc; //TODO: find a way to fix the multiple-static-allocation issue
アイデアは、あなたが途中でADD_ENTITY_xビットでBEGIN_ENTITY_TYPE(...)END_ENTITY_TYPE(...)節を作成することです。私の質問は、これを行うマクロ的ではない方法があるかどうかです。それでも、定型文は最小限に抑えられ、Entityサブクラスを定義するファイル以外のファイルは変更する必要がありません。テンプレートクラスはうまくいくかもしれませんが、テンプレートクラスを使ってADD_ENTITY_INPUT/OUTPUTをどうやってやるのか分かりません。
テンプレートを使用している: – Lucretiel
これは質問ですか? :-) –