Hello, rust community!
I am developing an ECS based application (mostly as a way to learn more advanced topics of Rust by building a larger scale project), but I have encountered an issue that I am not able to resolve.
Take this (it is a simplification of the actual implementation)
The idea is to be able to return the corresponding type given a generic argument that implements a certain trait. But this does not work! Anyone have an idea as to why, and how I might achieve similar functionality?
There is no way to make this signature work. Returning a reference to a HashMap, with the same lifetime as the borrow of self, implies that such a HashMap must be stored somewhere in memory, accessible from self. Your signature claims to be able to return such a reference to HashMap<IndexType, T> for everyT that implements Component, but this is certainly not possible—if I, the user of your library, implement Component for my own type Foo, there is no way your TComponents has a HashMap<IndexType, Foo> stashed away somewhere.
There are a bunch of existing ECS libraries written in Rust (Specs, Legion, Shipyard, Bevy); maybe looking at what they do would help you find a good approach for your own project?
I managed to make this work, but I had to use an unsafe block. This is not actually a library. The trait implementation is generated for any struct via a reasonably simple proc macro.
pub fn get<T:crate::ecs::Component>(&self)->&HashMap<IndexType,T>{
let m:&HashMap<IndexType,T> =unsafe{match T::get_type(){
#(ecs::components::ComponentType::#n=>std::mem::transmute(&self.#sn),)*
}
};
m
}