amethyst / specs

Specs - Parallel ECS
https://amethyst.github.io/specs/
Apache License 2.0
2.49k stars 218 forks source link

FlaggedStorage with information about the change in value. #638

Open blargg opened 4 years ago

blargg commented 4 years ago

Description

Update flagged storage, or create a new storage, so that the ComponentEvent contains information about the component before and after the change.

Motivation

I maintain collision detection information in a resource. This needs to be kept in sync with the entities in specs.

When an entity is deleted, I need to find the handle stored on the component to identify the object in the collision information. This handle can be used to delete it from the collision world. Since the entity has already been deleted, I can't look up this information from the world.

Right now, whenever I delete an entity, I just check if it has the information and delete the collision object. This is less than ideal, since I must change every system to account for my collision detection system.

Drawbacks

Unresolved questions

WaDelma commented 4 years ago

So you're have separate handle for physics object? Can't you just use index of an entity?

blargg commented 4 years ago

In this case, it looks like I can't. I'm using ncollide2d, which has its own handle object. When you add an object to CollisionWorld, you get a handle to the object in the world, and a mutable reference to the object. (CollisionObjectSlabHandle, &mut CollisionObject<N, T>).

I don't think I can influence the handle to relate it to the entity id.

One other thing I've tried: You can store information on the object, for example the entity index. You can then iterate over all the objects to get the handle and remove it. But this is O(n), and I haven't found a faster way.

WaDelma commented 4 years ago

You could have map from entity index to collision handle then.

blargg commented 4 years ago

True, but the drawback to this approach is that it requires more code to determine when an entity is deleted to free space on the index. If it is a component, this is done by specs. Is there a way to join over the map? There are a few systems that use the component in a join, and it would be nice to still have that.

blargg commented 4 years ago

I did a bit of development on this. You can implement this outside of the specs crate, making a new struct similar to FlaggedStorage.

At this point, my use case is covered. The question that I have left is: Is this something that we should put in this library to share, or should we leave it to other libraries/code?

visceralfield commented 4 years ago

Regarding the question in the last comment, thought I would chime in and say I would also get a lot of use out of this feature were it in specs.

Dollab commented 3 years ago

@blargg this would be a very useful feature. I can think of the following use cases :