.join()
iterator? e.g. for z-ordering?
Hi, I've been working on the movement system and got an issue:
impl<'a> System<'a> for DestinationMovement {
type SystemData = (
Entities<'a>,
WriteStorage<'a, Position>,
ReadStorage<'a, Speed>,
ReadStorage<'a, Destination>,
ReadExpect<'a, Timings>,
ReadExpect<'a, Map>,
);
fn run(
&mut self,
(entities, mut positions, speeds, destinations, timings, map): Self::SystemData,
) {
for (_entity, speed, destination, position) in
(&entities, &speeds, &destinations, &mut positions).join()
{
let destination_position = positions.get(destination.0).cloned().unwrap();
// rest of the code is irrelevant
}
}
}
Some entities have a destination
, which is wrapper over Entity
, and to calculate a path to destination I need to retrieve destination's position. Naturally, I also want to have own position of the current entity itself.
Issue is that iterator mutably borrows positions
, so I cannot use it inside loop. For me it looks like a very common issue, so maybe there is known solution for this problem?
I could remove positions
dependency from join
and get both entity and destination position inside loop, but I don't like that it will relax component requirements for this system. Another potential solution I can think of, but haven't tried, is to collect all new positions into separate Vec
and then assign them with another loop. I don't like performance implications of this approach and unsoundness of it.
Is there anything else I can do?
join
within join
by using just Entities
to get both entities, then compare them for inequality and then access storages. In our game I think we first did that, but now were doing simple sweep-and-prune by using flagged storage to maintain internal data structure.
world.insert(unsafe { transmute::<&'_ DebugOverlay, &'static DebugOverlay>(surface.debug_overlay()) });
hey, can someone tell me if a VecStorage will ever shrink in size?
Looking at the VecStorage implementation of UnsafeStorage it seems that when entities as entities are added the vec grows, but the only way it can shrink is when it is cleaned, where all entities are removed. Is my thinking correct?
EventChannel
resource which can be read and written to by systems. This allows specs/shred to optimize which systems can be executed in parallel automatically, like it's done for component reads/writes. It's working pretty nicely for me so far. Also, this is how specs does events internally for its FlaggedStorage, which allows you to check if/which components have been modified.
I have a problem with pathfinding. I wrote a function to calculate paths. It needs bunch of storages, read-only. Unfortunately, one system that interacts with pathfinding requires one of this storages for mutable access. I had to specify WriteStorage
for pathfinding arguments just because one of system needs it this way. Documentation specifies that it is forbidden to require both ReadStorage
and WriteStorage
simultaneously, so I cannot do that. At this point it doesn't really bother me that much, but I suspect I will have problem with FlaggedStorage
in future.
Is there way to specify argument type for function so it would accept both ReadStorage
and WriteStorage
whichever is available for me in the system, so I can pass it to pathfinding?
i'm having trouble using the .join() method outside of the System trait implementation block. anyone know how i should fix it?
pardon the ugly code, but here is something that I'm having issues with.
https://pastebin.com/wzURVPS5
the method at line 121 does not work when used in a method for the Ai struct, but it does inside the system's .run() function at line 156. what am i doing wrong? perhaps am I just structuring my code wrong in the first place? should I be approaching this sort of thing in a different way?
for (player_entity, target_pos, player) in (&data.entities, &data.positions, &data.players).join()