Extendable Id System
目的:
- 扩展性:可肆意Agnostic插入新Voxel-ID 且不造成ID冲突,
- 高性能:永久ID使用StrId 对内部使用即时生成的NumId
方案:
- 结合StrId和NumId: 使用 StrId (e.g.
minecraft:stone
) 作为永久ID/宇宙唯一/面向人类,而使用 NumId (e.g. 9) 作为运行时ID/运行时动态生成/面向程序内部。 - 同一批StrId对应的NumId总是不变: 有助于缓存(Atlases/Baked), IdSystem Hash.
StrId at Defination and NumId at Runtime.
- 使用
rust
struct RegEntry<T> {
str_id: &str,
num_id: u32,
entry: T,
}
struct Registry<T> {
reg: Vec<RegEntry<T>>,
cache_str2num: HashMap<&str, usize>,
}
impl Registry<T> {
fn regist(&mut self, str_id: &str, entry: T) {
self.reg.insert(str_id, entry);
}
fn build(&mut self) {
self.reg.sort();
cache_str2num.clear();
cache_str2num.insert_all(self.reg);
}
fn entry(&self, num_id: usize) -> &RegEntry<T> {
self.reg[num_id]
}
fn at(&self, num_id: usize) -> &T {
self.entry(num_id).val
}
fn num_id(&self, str_id: &str) -> usize {
self.cache_str2num[str_id]
}
fn get(&self, str_id: &str) -> &T {
self.at(self.num_id(str_id))
}
}
fn main() {
}
Naive Method
cpp
using BlockId = uint16_t;
namespace blocks {
BlockId AIR = 0,
STONE = 1,
DIRT = 2,
GRASS = 3,
SAND = 4;
}
class Chunk {
BlockId m_Voxels[16*16*16];
...
}
- 优点:简单高效
- 缺点:不可扩展,如果其他多个mod作者要插入新id,很可能造成id冲突