我可以按类类型访问哪些类型的集合,并在必要时返回未找到



对于冗长的,可能令人困惑的标题,我深表歉意,我将尝试澄清。所以情况是这样的,我有一个组件(自定义类)向量的元组。每个组件都有一个 id,该 id 对应于元组中各自向量中的索引。组件属于一个实体,所以我希望该实体跟踪它拥有的组件的所有ID。当然,如果不知道它所属的组件类型,那么 ID 将毫无意义,以便我可以将其从元组中提取出来。所以我希望实体有一个集合,也许是一个std::unordered_map,通过它我可以提供一个类类型并得到适当的索引,或者一些数字(在本例中SHRT_MAX)告诉我实体没有这样的组件。

这似乎是用枚举和开关语句实现的,但似乎也非常没有必要遍历开关语句的每个分支,只是为了为元组的 get 函数提供正确的类,所以我想知道是否有更好的方法。

我提供了一个代码示例,其中包含我正在寻找的注释示例:

#include <tuple>
#include <vector>
#include <unordered_map>
class Component {
unsigned short id;
};
class CameraComponent : public Component {
};
class VehicleComponent : public Component {
};
class Entity {
//This is kind of the data structure I am thinking about so far
//std::unordered_map<ComponentType, unsigned short> components
};
class EntityManager {
private:
//This is the tuple I am talking about
static std::tuple<std::vector<CameraComponent>, std::vector<VehicleComponent>> components;
public:
//This is used to make accessing the tuple more convenient
template<class T>
static auto& Components();
//This is kind of function I would like to be able to use
template<class T>
static T& GetComponentFromEntity(Entity& e);
};
//Initialize the static tuple
std::tuple<std::vector<CameraComponent>, std::vector<VehicleComponent>> EntityManager::components;
//This is used to make accessing the tuple more convenient
template<class T>
auto& EntityManager::Components()
{
return std::get<std::vector<T>>(components);
}
//This is kind of function I would like to be able to use
template<class T>
T& EntityManager::GetComponentFromEntity(Entity& e) {
//unorded_map<ComponentType, unsigned short>::iterator itr;
//itr = e.components.find(T);
//if(itr = e.components.end())
//return SHRT_MAX;
//return Components<T>()[itr];
}
int main() {
return 0;
}

任何帮助将不胜感激(我还想强调,我没有结婚使用unordered_map,这只是我想到的第一件事)。提前谢谢。

正如Igor Tandetkik所建议的那样,答案是以类似于以下内容的方法将unordered_mapstd::type_index一起使用:

#include <tuple>
#include <vector>
#include <unordered_map>
#include <typeindex>
#include<iostream>
using std::cout;
using std::getchar;
class Component {
public:
unsigned short id = SHRT_MAX;
};
class CameraComponent : public Component {
};
class VehicleComponent : public Component {
};
class Entity {
public:
std::unordered_map<std::type_index, unsigned short> components;
};
class EntityManager {
private:
//This is the tuple I am talking about
static std::tuple<std::vector<CameraComponent>, std::vector<VehicleComponent>> components;
public:
//This is used to make accessing the tuple more convenient
template<class T>
static auto& Components();
//This is what I want
template<class T>
static T* GetComponentFromEntity(Entity& e);
};
//Initialize the static tuple
std::tuple<std::vector<CameraComponent>, std::vector<VehicleComponent>> EntityManager::components;
//This is used to make accessing the tuple more convenient
template<class T>
auto& EntityManager::Components()
{
return std::get<std::vector<T>>(components);
}
template<class T>
T* EntityManager::GetComponentFromEntity(Entity& e) {
std::unordered_map<std::type_index, unsigned short>::iterator itr;
itr = e.components.find(typeid(T));
if(itr == e.components.end())
return nullptr;
return &Components<T>()[itr->second];
}
int main() {
Entity e;
VehicleComponent v;
v.id = EntityManager::Components<VehicleComponent>().size();
EntityManager::Components<VehicleComponent>().push_back(v);
e.components.insert(std::make_pair<std::type_index, unsigned short>(typeid(VehicleComponent), 0));
cout << EntityManager::GetComponentFromEntity<VehicleComponent>(e)->id;
getchar();
return 0;
}

再次感谢伊戈尔·坦德特尼克!

最新更新