As part of my rust journey of discovery I am writing a roguelike using the legion ECS library.
I am trying to see if there's a way I can refactor a spawner function so that tuple that is used within that function be called within a system.
In other words, currently have a bunch of functions that look like:
Unfortunately, IntoComponentSource is private in legion.
I'd like to refactor the function that I can return the tuple from one function and use in the existing function. Something like:
// Question: what would T look like here?
pub fn spawn_giant_rat_tuple(pt: Point) -> T {
(
Actor,
Render{ ... },
...
)
}
// So that I can pass it in here?
pub fn spawn_giant_rat(ecs: &mut World, pt: Point) {
ecs.push(spawn_rat_tuble(pt));
}
Thank you. That worked to get the fn spawn_giant_rat_tuple to compile. Do you have any guidance for the call on the ecs.push(spawn_giant_rat_tuple(pt)) side? I currently get:
error[E0277]: the trait bound `legion::internals::insert::Aos<impl
legion::storage::IntoComponentSource, std::option::IntoIter<impl legion::storage::IntoComponentSource>>: legion::storage::ComponentSource` is not satisfied
--> src/spawners/actors.rs:36:9
|
36 | ecs.push(spawn_rat_tuple(pt));
| ^^^^ the trait `legion::storage::ComponentSource` is not implemented for
`legion::internals::insert::Aos<impl legion::storage::IntoComponentSource, std::option::IntoIter<impl legion::storage::IntoComponentSource>>`
|
= help: the following implementations were found:
<legion::internals::insert::Aos<(), Iter> as legion::storage::ComponentSource>
<legion::internals::insert::Aos<(A, B, C, D, E, F, G, H), Iter> as legion::storage::ComponentSource>
<legion::internals::insert::Aos<(B, C, D, E, F, G, H), Iter> as legion::storage::ComponentSource>
<legion::internals::insert::Aos<(C, D, E, F, G, H), Iter> as legion::storage::ComponentSource>
and 5 others
= note: required because of the requirements on the impl of `legion::storage::IntoComponentSource` for `std::option::Option<impl legion::storage::IntoComponentSource>`
No worries, if not. I'm researching now to try and understand the error message.
P.S. Not sure how my research into the legion code led me into the internals module rather than the storage module. Thanks for the clarificatino there. I'm using 0.3.1 of legion.
So that error is pointing out that there is no implementation of ComponentSource for Aos<impl IntoComponentSource, ..>. Apparently, it is implemented for all tuples in Aos<(A, B, ..), ..>. So I don't think you can actually avoid writing out the type in full. What I would do is just bite the bullet and do that:
That should make it go away. You can see the impls being generated here (Though the line numbers seem to be messed up.) This impl is needed to satisfy the bounds on the associated type IntoComponentSource::Source set by the World::push method.
There may be a way to do it like that with the right set of bounds or an extra trait impl somewhere, but I'm not seeing it.
Cool. I was just trying to understand that file. It's a little verbose but not too bad, especially compared to writing two completely different functions for &World and &CommandBuffer. I can definitely live with it.