我一直在尝试寻找一种有效的方法来存储和检索许多对象。让我解释一下我想要实现的目标,然后列出我想出的选项(但我不满意)。
以下在技术上做了我需要它做的事情,但显然是一个禁忌:
std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::unordered_map<uint32_t, Component*>>>>
//Scene -> Layer -> Type -> Id -> Component*
最内部的地图根据其 ID 保存组件。它之前的每个类型都有一个映射(组件的子类)。后者是这样完成的,以便当我检索它们时,我可以完全安全地动态地将它们转换为它们的类型,因为知道 TYPE 哈希映射只包含它们的类型的指针,还允许使用 count 来快速检查某个 ID 是否存在某些东西. 后面的地图按层存储,第一个地图按场景存储。在任何时候,将举行大约 30-50 个场景,每个场景包含大约 6-10 个图层,每个图层包含大约 30-40 个类型,每个类型包含 1 到 500 个对象。
每个循环我们都会根据指针的类型迭代指针,一次一层。场景很少改变(每 2-3 分钟)。使用 Type 和 Id 的组合访问组件。代码会定期检查哪些其他组件类型存在于同一 Id 中。场景、层和类型可以通过它们的名称进行访问,名称存储为 32 位 CRC 散列。速度至关重要。ID 是由代码分配的数字,只是从 0 开始。ID 在每个场景中都是唯一的。
毫无疑问,有一些疯狂的(阅读:常见的)成语可以帮助我,而我从未听说过。有谁知道吗? 到目前为止,我提出的任何替代方案都不可接受,但无论如何我都会列出它们:
选项1:
std::unordered_map<uint32_t, std::vector<Component*>>
ID -> Component*
组件保存它来自哪个类型、场景和图层,每当我们遍历所有条目时,我们都会忽略不来自当前场景或图层的条目。或者,按顺序存储它们,以便您只需在一定范围内进行迭代。向量包含组件,当我们需要访问某种类型的组件时,我们会通过向量进行搜索。不理想,因为它需要一个周期进行多次搜索。或者使用 unordered_map 代替向量。
选项 2:
与嵌套地图相同,但带有向量。映射将 Id 转换为向量内的索引。
选项 3:
std::vector<Component*>
std::unordered_map<uint32_t, std::vector<int>>
(Type / Layer / Scene / Id) -> Component* 简单地用向量的索引存储所有组件。有一个 unordered_map,其中包含主存储向量中的索引向量。当我们检查两者之间的冲突时,ID 和字符串哈希都可以存在(不太可能)。对于场景、图层和类型,名称必须是唯一的。ID 返回该 ID 的组成部分的所有索引的向量,名称或类型返回包含该类型或场景的所有索引的向量。感觉 hackish,所有这些向量的迭代。
选项 4:
组件获取一个“Component* next”指针来遍历属于同一实体的组件。最后一个组件链接到第一个。组件再次获得类型和场景/图层成员。