【问题标题】:How to get values in a struct-of-arrays (SOA) through a generic type?如何通过泛型类型获取数组结构 (SOA) 中的值?
【发布时间】:2020-03-07 14:44:01
【问题描述】:

我正在寻找您对一段代码的反馈/建议。

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

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

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

到目前为止,一切都很好,但我正试图通过相应的 arena 动态检索值来实现这一点。如果句柄类型是Mesh,则通过执行entities.get(&amp;handle),我返回entities.meshes.get(&amp;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

这非常有效。我将泛型类型转换为具体类型,然后再转换为泛型类型,但这似乎很奇怪和棘手。

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

【问题讨论】:

    标签: rust game-development entity-component-system


    【解决方案1】:

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

    创建一个 trait,它会引用你的容器结构。每个组件类型都实现了这个特征并选择容器的适当字段。然后,在您的 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);
    }
    

    【讨论】:

    • 哦,你的方式好多了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    相关资源
    最近更新 更多