我对模板和编译时函数还很陌生,我目前正在尝试编写一个基本的实体组件系统(ECS),该系统将允许我在容器中存储泛型类型(组件)。我希望功能能够在编译时和运行时设置容器。在我的应用程序中有一些实例,我可以肯定哪些组件对于某个实体将始终存在,因此我希望能够在编译时进行设置并保留插槽。在某些情况下,需要在运行时动态删除/添加组件。
template <typename T, size_t N>
struct ComponentArray {
public:
template<typename... Args>
constexpr const T& AddComponent(const uint64_t entity, Args &&... args) const
{
//T component{ std::forward<Args>(args)... }; //i want to be able to do something like this..
//m_components[0] = component; //create the component and give it a slot, but this is const
return m_components[0];
}
std::array<T, N> m_components = {};
std::array<T, N> m_entityIds = {};
uint32_t m_used = 0;
};
template <uint64_t entityId, typename Component, typename ... Args>
constexpr const Component& AddComponentCT(Args&&... args)
{
constexpr uint64_t componentHash = GetHashForString(ComponentTypeInfo<Component>::m_name, ComponentTypeInfo<Component>::m_nameLength);
constexpr uint64_t storageHash = ComponentStorageMapping<componentHash>::m_hash;
static_assert(storageHash == componentHash);
constexpr const auto& componentStorage = ComponentStorageMapping<componentHash>::m_componentStorage;
constexpr const Component& rComponent = componentStorage.AddComponent(entityId /*std::forward<Args>(args)...*/);
return rComponent;
}
constexpr const TransformComponent transform = AddComponentCT<ENTITY_ID, TransformComponent>(5.0f, 5.0f, 5.0f);
这似乎可行,当我将鼠标悬停在transform
上时,我可以看到返回的内容,但显然是不正确的值,因为我无法使用const函数中的参数构造类型。
我也曾尝试从变量中删除一些const,但随后它抱怨说东西不是const或无法求值。
我正在使用提供的参数创建Component
类型,然后在m_components
中找到一个空闲插槽来存储它。这样的事情在编译时可能吗?如果有人对我如何实现我想要的东西或改进解决方案有任何建议,将不胜感激。这里没有包含一些宏代码,这些宏代码会生成类似ComponentStorageMapping
,ComponentTypeInfo
和m_componentStorage
]的类。
下面是注释中要求的更简化/通用的版本
struct A { float x, y, z; }; struct B { int i, j, k; }; template <typename T, size_t N> struct C { public: template<typename... Args> constexpr const T& AddToArray(Args &&... args) const { //T element{ std::forward<Args>(args)... }; //i want to be able to do something like this.. //m_array[0] = element; //create the component and give it a slot, but this is const return m_array[0]; } std::array<T, N> m_array = {}; }; template <typename T, typename ... Args> constexpr const T& AddElement(Args&&... args) { constexpr const T& element = C<T, 50>::AddToArray(/*std::forward<Args>(args)...*/); return element; } constexpr const A& someArrayElement = AddElement<A>(5.0f, 5.0f, 5.0f); //this would point to C<A,50>::m_array[0], fully constructed constexpr const A& someArrayElement2 = AddElement<A>(10.0f, 10.0f, 10.0f); //this would point to C<A,50>::m_array[1], fully constructed constexpr const B& someArrayElement3 = AddElement<B>(1, 1, 1); //this would point to C<B,50>::m_array[0], fully constructed constexpr const B& someArrayElement4 = AddElement<B>(2, 2, 2); //this would point to C<B,50>::m_array[1], fully constructed
为了记录,我在此之前创建了另一篇文章(https://gamedev.stackexchange.com/questions/176301/how-can-i-create-a-templated-function-to-add-components-to-their-necessary-conta),以了解我将如何处理这种情况,并且没有收到很多建议,因此我只是尝试自己做,这是我遇到的问题。还有另一个框架可以某种方式实现我正在尝试做的事情,但是我不太了解他们在做什么,因为它们都是模板。到该框架的链接在另一篇文章中。
我对模板和编译时函数还很陌生,我目前正在尝试编写一个基本的实体组件系统(ECS),该系统将允许我在容器中存储泛型类型(组件)。 ...
我认为您想要的是不可能的。