gpt4 book ai didi

c++ - 使用 bitset 访问 vector 索引

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:19:40 26 4
gpt4 key购买 nike

我正在尝试编写我自己的实体组件系统,我想要一种快速(尽可能恒定的时间)但内存高效的方式来访问实体的组件。

使用全局映射 (std::unordered_map) 将每个实体映射到包含其组件的排序 vector :

Key        Value
--- -----
EntityA -> Sorted vector of components
EntityB -> Sorted vector of components
[..] -> [..]

每个实体都有一个位集,指示该实体具有哪些组件,即。 :

|C0 |C1 |C2 |C3 |C4 |C5
0 0 1 0 1 1

and on the map:
Key Value
--- -----
EntityA -> [C2,C4,C5]

由于很少添加组件,我可以负担排序插入的成本,但我绝对想要快速访问。

现在我从 bitset 知道 C4 是第二个元素集(从左边数起)所以它应该在第二个 vector 索引处。

如何将它写入一个方法,该方法将返回给定该组件类型 ID 的实体的组件?例如。

Component* getComponent(ComponentID id){ // component id of C5 should be 6 since it occupies the 6th position of the bitset
return [..];
}

最佳答案

假设我们的成员是:

std::bitset<6> bits;
std::vector<Component> comps;

然后:

Component* getComponent(int id) {
// we need to find how many bits are set for ids < id
// first, make sure this one is set:
if (!bits[id]) return nullptr;

// then, let's count
int idx = 0;
for (int i = 0; i < id; ++i) {
if (bits[i]) ++idx;
}

// now, just return the right pointer
return &comps[idx];
}

你也可以使用 std::bitset::test如果你想进行边界检查,而不是索引运算符。

一个更快的解决方案可能是这样的:

Component* getComponent(int id) {
if (!bits[id]) return nullptr;

// flip id and get a mask
// if we have C0 .. C5, and we pass in 4
// we want the mask 0x111100
unsigned long mask = (1 << (bits.size() - id)) - 1;
mask = ~mask;

// apply the mask to the bitset
// so from 0x001011, we get 0x001000
unsigned long new_bits = bits.to_ulong() & mask;

// count how many bits are set there
unsigned int popcnt = __builtin_popcount(new_bits);

// and there we have it
return &comps[popcnt];
}

关于c++ - 使用 bitset 访问 vector 索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28256984/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com