我已经研究了一段时间,我似乎无法找到如何实现这一目标。
有一个非常明确的标题 emscripten_get_canvas_size,它没有做我期望它做的事情。实际的 Emscripten 画布元素已设置为 100% 的宽度和高度,但是如果我通过 emscripten_get_canvas_size 检索宽度和高度,我只会获得画布内显示的 GLFW 窗口的宽度和高度,而不是画布缩放到的实际尺寸。
我想获得浏览器中显示的实际画布大小,以便我可以调用 glfwSetWindowSize 来缩放视口以填充整个浏览器窗口。
即使我将画布设置为 100x100px,emscripten_get_canvas_size 也只会返回我在程序开始时通过 glfwSetWindowSize 设置的 1920x1080。
我可能遗漏了一些明显的东西,但是什么?
我一直在尝试找出一种有效的方法来存储和检索许多对象。让我解释一下我要实现的目标,然后列出我想出的选择(但不满意)。
从技术上讲,以下内容可以满足我的需要,但显然是不行的:
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*
Run Code Online (Sandbox Code Playgroud)
最内部的映射根据组件的ID保存组件。每个类型前面都有一个映射(Component的子类)。这样做是为了使我在检索它们时,可以完全安全地将它们动态地转换为它们的类型,因为TYPE哈希图仅包含其类型的指针,还允许使用count来快速检查某个ID是否存在。接下来的地图按层存储它们,第一个地图按场景存储它们。在任何时候,将保留大约30-50个场景,每个场景包含大约6-10层,每个场景包含大约30-40种类型,每种类型包含1到500个对象。
每个周期,我们将根据指针的类型遍历指针,一次一层。场景变化很少(每2-3分钟一次)。可以使用类型和ID的组合来访问组件。代码会定期检查在同一ID中还存在哪些其他Component类型。场景,图层和类型通过其名称进行访问,名称存储为32位CRC哈希。速度至关重要。ID是由代码分配的数字,仅从0开始。ID在每个场景中都是唯一的。
毫无疑问,有一些疯狂的(惯用的)成语可以帮助我,但我从未听说过。有人认识吗? 到目前为止,我没有提出任何备选方案,但是无论如何,我都会列出它们:
选项1:
std::unordered_map<uint32_t, std::vector<Component*>>
ID -> Component*
Run Code Online (Sandbox Code Playgroud)
Component保留它来自哪个类型,场景和图层,每当我们遍历所有条目时,我们都会忽略那些不是来自当前场景或图层的条目。或者,按顺序存储它们,以便您只需要迭代一定范围。向量包含组件,当我们需要访问某种类型的组件时,我们将在向量中进行搜索。这并不理想,因为它需要一个周期进行多次搜索。或者,使用unordered_map代替矢量。
选项2:
与嵌套地图相同,但带有矢量。映射将Id转换为向量内的索引。
选项3:
std::vector<Component*>
std::unordered_map<uint32_t, std::vector<int>>
Run Code Online (Sandbox Code Playgroud)
(类型/层/场景/ ID)->分量*仅使用矢量索引存储所有分量。有一个unordered_map,它在主存储向量中包含索引向量。当我们检查两者之间的冲突时,ID和字符串哈希都可以存在(不太可能)。场景,图层和类型的名称必须唯一。ID返回该ID的组成部分的所有索引的向量,Name或类型返回包含该类型或场景的所有索引的向量。这些向量的所有这些迭代都让人感到骇俗。
选项4:
组件获取一个“ Component * next”指针,以遍历属于同一实体的组件。最后一个组件链接到第一个。组件再次获得类型和场景/图层成员。