如何通过泛型获取数组结构 (SOA) 中的值?

How to get values in a struct-of-arrays (SOA) through a generic type?

我正在寻找您的 feedback/advice 一段代码。

基本上,我有这样一个 SOA:

struct Entities {
    pub meshes: FakeArena<Mesh>,
    pub lights: FakeArena<Light>,
}

我可以通过他的“句柄”访问特定的值(每个句柄都绑定到特定的类型),所以我可以通过 entities.meshes.get(&handle) 来获取网格的值。

到目前为止一切顺利,但我正在尝试通过相应的竞技场动态检索值来实现这一点。通过执行 entities.get(&handle) 如果句柄类型是 Mesh,我 return entities.meshes.get(&handle)。我的 Entities 结构有一个名为 get:

的方法
fn get<T: Any>(&self, handle: &Handle<T>) -> &T {
    let mut entity: Option<&dyn Any> = None;
    let any = handle as &dyn Any;

    any.downcast_ref::<Handle<Mesh>>()
        .map(|handle| entity = Some(self.meshes.get(handle) as &dyn Any));

    any.downcast_ref::<Handle<Light>>()
        .map(|handle| entity = Some(self.lights.get(handle) as &dyn Any));

    if entity.is_none() {
        panic!("Type not found in stored entites.");
    }

    entity
        .unwrap()
        .downcast_ref::<T>()
        .expect("Error while downcasting the entity type")
}

Playground

这非常有效。我将通用类型向下转换为具体类型,然后再次转换为通用类型,但这看起来很奇怪而且很棘手。

也许我遗漏了什么,或者您对此有更好的主意;你会怎么做? :)

这里不需要任何动态调度,普通的静态调度就足够了。

创建一个特征,它被赋予对容器结构的引用。每个组件类型都实现这个特征并选择容器的适当字段。然后,在你的 get 方法中要求特征并使用它:

struct Mesh;
struct Light;

struct Entities {
    meshes: Vec<Mesh>,
    lights: Vec<Light>,
}

trait Example {
    fn get_in<'a>(&self, entities: &'a Entities) -> &'a Self;
}

impl Example for Mesh {
    fn get_in<'a>(&self, entities: &'a Entities) -> &'a Self {
        &entities.meshes[0]
    }
}

impl Example for Light {
    fn get_in<'a>(&self, entities: &'a Entities) -> &'a Self {
        &entities.lights[0]
    }
}

impl Entities {
    fn get<T: Example>(&self, handle: T) -> &T {
        handle.get_in(self)
    }
}

fn example(entities: &Entities) {
    let m = entities.get(Mesh);
    let l = entities.get(Light);
}