我有一个组件注册表,用于注册组件(类/类型)。我成功地做到了,如果您尝试将其与未注册的类一起使用,系统将无法工作。但是,即使它只在一种注册表中注册过一次,它也可以与所有注册表一起使用,因为有:
template <typename T> static inline component_id;
它通过宏放置在类内部。
template <typename name>
struct ComponentRegistry
{
using this_type = ComponentRegistry;
template <typename component_t>
static char register_new_component(const char* name)
{
static int counter = 0;
component_t::template component_id<this_type> = counter++;
/* REGISTER THE COMPONENT HERE*/
return char(); /* ANYTHING. THE ONLY ONLY REASON THE DUMMY EXISTS IS TO TRIGGER THIS FUNCTION CALL ON PROGRAM INITIALIZATION */
}
template <typename component_t>
int getComponentID()
{
/* IF THE COMPONENT WASN'T REGISTERED WITH ANY REGISTRY AT ALL, THEN THE template component_id DOESN'T EXIST AND SO IT WORKS
- THE PROBLEM IS THAT EVEN IF IT WAS REGISTERED WITH ANOTHER REGISTRY THIS WILL STILL INSTANTIATE THE TEMPLATE
- HOW DO I THROW A COMPILE ERROR? */
return component_t::template component_id<this_type>;
}
};
#define REGISTER_COMPONENT_WITH_REGISTRY(comp_name, ecs_registry_type, comp_type) \
static inline char dummy_assignee_##ecs_registry_type = ecs_registry_type::register_new_component<comp_type>(comp_name); \
template <typename T> \
static inline int component_id;
struct ComponentRegistryName {}; // JUST USED TO DISTINGUISH. EACH TYPE CAN HAVE ITS OWN SET OF COMPONENTS
using ComponentRegistryType = ComponentRegistry<ComponentRegistryName>;
struct MyComponentType
{
REGISTER_COMPONENT_WITH_REGISTRY("MyComponentTypeName", ComponentRegistryType, MyComponentType)
};
struct MyComponentType2
{
/* NOT REGISTERED */
};
int main()
{
ComponentRegistryType component_registry;
component_registry.getComponentID<MyComponentType>(); // THIS SUCCEEDS BECAUSE IT WAS REGISTERED
//component_registry.getComponentID<MyComponentType2>(); // THIS FAILS TO COMPILE BECAUSE THE COMPONENT WASN'T REGISTERED
}
这可以很好地检查组件是否已注册,因为如果没有注册:
但问题是,如果我想将组件注册到另一个注册表类型,就不再进行限制检查,因为当我这样做时:
component_t::template 组件 ID
根本不存在。但是,即使使用已注册到任何注册表的组件的模板参数调用 getComponentID,它也会成功。我希望使用可以作为成员检查的宏在类中放置一个 typedef,如果它存在,那么就很好了。
可能是这样的:
然后注册宏将会输出如下内容:
该宏将被放置在组件类之外,而不是像现在这样放置在内部。
在注册表中,您可以访问组件 ID
ComponentIdHolder<this_type, component_t>::component_id
。对于任何未提供专业化的类型对,这都会导致编译失败。