You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
1.9 KiB

  1. use shrev::ReaderId;
  2. use specs::{hibitset::BitSetLike, prelude::*, Entities, ReadStorage, System, World, WriteStorage};
  3. use crate::{components::Position, misc::ComponentEvent, resources::Raster};
  4. pub struct RasterUpdate {
  5. need_update: BitSet,
  6. position_id: ReaderId<ComponentEvent<Position>>,
  7. }
  8. impl RasterUpdate {
  9. pub fn new(world: &mut World) -> Self {
  10. let need_update = BitSet::new();
  11. let position_id = unsafe {
  12. WriteStorage::<Position>::setup(world);
  13. let mut position = world.write_component::<Position>();
  14. position
  15. .unprotected_storage_mut()
  16. .channel_mut()
  17. .register_reader()
  18. };
  19. Self {
  20. need_update,
  21. position_id,
  22. }
  23. }
  24. }
  25. #[derive(SystemData)]
  26. pub struct RasterUpdateData<'a> {
  27. raster: WriteExpect<'a, Raster>,
  28. entities: Entities<'a>,
  29. positions: ReadStorage<'a, Position>,
  30. }
  31. impl<'a> System<'a> for RasterUpdate {
  32. type SystemData = RasterUpdateData<'a>;
  33. fn run(&mut self, data: Self::SystemData) {
  34. let RasterUpdateData {
  35. mut raster,
  36. entities,
  37. positions,
  38. } = data;
  39. self.need_update.clear();
  40. let events = positions
  41. .unprotected_storage()
  42. .channel()
  43. .read(&mut self.position_id);
  44. for event in events {
  45. match event {
  46. ComponentEvent::Inserted(id) => {
  47. self.need_update.add(*id);
  48. }
  49. ComponentEvent::Modified(id, position) | ComponentEvent::Removed(id, position) => {
  50. self.need_update.add(*id);
  51. raster.remove(id, position);
  52. }
  53. }
  54. }
  55. if self.need_update.is_empty() {
  56. return;
  57. }
  58. for (e, position) in (&entities, &positions).join() {
  59. raster.insert(e.id(), position);
  60. }
  61. }
  62. }