11use std:: marker:: PhantomData ;
22
3- use crate :: tilemap:: { TileData , TileStorage , Tilemap } ;
4- use bevy_ecs:: { entity:: Entity , hierarchy:: ChildOf , system:: { Command , Commands } , world:: World } ;
3+ use crate :: {
4+ tilemap:: { TileData , TileStorage , Tilemap } ,
5+ TileStorages ,
6+ } ;
7+ use bevy_ecs:: {
8+ change_detection:: DetectChangesMut ,
9+ entity:: Entity ,
10+ hierarchy:: ChildOf ,
11+ system:: { Command , Commands } ,
12+ world:: World ,
13+ } ;
514use bevy_math:: { IVec2 , Vec2 , Vec3 } ;
615use bevy_transform:: components:: Transform ;
716
@@ -13,7 +22,7 @@ pub trait CommandsTilemapExt {
1322 maybe_tile : Option < T > ,
1423 ) ;
1524
16- fn remove_tile < T : TileData > ( & mut self , tilemap_id : Entity , tile_position : IVec2 ) ;
25+ fn remove_tile ( & mut self , tilemap_id : Entity , tile_position : IVec2 ) ;
1726}
1827
1928impl CommandsTilemapExt for Commands < ' _ , ' _ > {
@@ -23,11 +32,24 @@ impl CommandsTilemapExt for Commands<'_, '_> {
2332 tile_position : IVec2 ,
2433 maybe_tile : Option < T > ,
2534 ) {
26- self . queue ( move |world : & mut World | { SetTile { tilemap_id, tile_position, maybe_tile } . apply ( world) ; } ) ;
35+ self . queue ( move |world : & mut World | {
36+ SetTile {
37+ tilemap_id,
38+ tile_position,
39+ maybe_tile,
40+ }
41+ . apply ( world) ;
42+ } ) ;
2743 }
2844
29- fn remove_tile < T : TileData > ( & mut self , tilemap_id : Entity , tile_position : IVec2 ) {
30- self . queue ( move |world : & mut World | { RemoveTile :: < T > { tilemap_id, tile_position, _t : PhantomData :: default ( ) } . apply ( world) ; } ) ;
45+ fn remove_tile ( & mut self , tilemap_id : Entity , tile_position : IVec2 ) {
46+ self . queue ( move |world : & mut World | {
47+ RemoveTile {
48+ tilemap_id,
49+ tile_position,
50+ }
51+ . apply ( world) ;
52+ } ) ;
3153 }
3254}
3355
@@ -44,107 +66,115 @@ pub struct SetTileResult<T: TileData> {
4466
4567impl < T : TileData > Default for SetTileResult < T > {
4668 fn default ( ) -> Self {
47- Self { replaced_tile : Default :: default ( ) , chunk_id : Default :: default ( ) }
69+ Self {
70+ replaced_tile : Default :: default ( ) ,
71+ chunk_id : Default :: default ( ) ,
72+ }
4873 }
4974}
5075
5176impl < T : TileData > Command < SetTileResult < T > > for SetTile < T > {
5277 fn apply ( self , world : & mut World ) -> SetTileResult < T > {
53- let Ok ( mut tilemap_entity) = world. get_entity_mut ( self . tilemap_id ) else {
54- tracing:: warn!( "Could not find Tilemap Entity {:?}" , self . tilemap_id) ;
55- return Default :: default ( ) ;
56- } ;
57-
58- let Some ( tilemap) = tilemap_entity. get :: < Tilemap > ( ) else {
59- tracing:: warn!( "Could not find Tilemap on Entity {:?}" , self . tilemap_id) ;
60- return Default :: default ( ) ;
61- } ;
78+ let Ok ( mut tilemap_entity) = world. get_entity_mut ( self . tilemap_id ) else {
79+ tracing:: warn!( "Could not find Tilemap Entity {:?}" , self . tilemap_id) ;
80+ return Default :: default ( ) ;
81+ } ;
6282
63- let chunk_position = tilemap. tile_chunk_position ( self . tile_position ) ;
64- let tile_relative_position = tilemap. tile_relative_position ( self . tile_position ) ;
83+ let Some ( tilemap) = tilemap_entity. get :: < Tilemap > ( ) else {
84+ tracing:: warn!( "Could not find Tilemap on Entity {:?}" , self . tilemap_id) ;
85+ return Default :: default ( ) ;
86+ } ;
6587
66- if let Some ( tile_storage_id) = tilemap. chunks . get ( & chunk_position) . cloned ( ) {
67- let replaced_tile = tilemap_entity. world_scope ( move |w| {
68- let Ok ( mut tilestorage_entity) = w. get_entity_mut ( tile_storage_id) else {
69- tracing:: warn!( "Could not find TileStorage Entity {:?}" , tile_storage_id) ;
70- return None ;
71- } ;
88+ let chunk_position = tilemap. tile_chunk_position ( self . tile_position ) ;
89+ let tile_relative_position = tilemap. tile_relative_position ( self . tile_position ) ;
7290
73- let Some ( mut tile_storage) = tilestorage_entity. get_mut :: < TileStorage < T > > ( )
74- else {
75- tracing:: warn!(
76- "Could not find TileStorage on Entity {:?}" ,
77- tile_storage_id
78- ) ;
79- return None ;
80- } ;
91+ if let Some ( tile_storage_id) = tilemap. chunks . get ( & chunk_position) . cloned ( ) {
92+ let replaced_tile = tilemap_entity. world_scope ( move |w| {
93+ let Ok ( mut tilestorage_entity) = w. get_entity_mut ( tile_storage_id) else {
94+ tracing:: warn!( "Could not find TileStorage Entity {:?}" , tile_storage_id) ;
95+ return None ;
96+ } ;
8197
82- tile_storage. set ( tile_relative_position, self . maybe_tile )
83- } ) ;
84- SetTileResult { chunk_id : Some ( tile_storage_id) , replaced_tile }
85- } else {
86- let chunk_size = tilemap. chunk_size ;
87- let tile_size = tilemap. tile_display_size ;
88- let tile_storage_id = tilemap_entity. world_scope ( move |w| {
89- let mut tile_storage = TileStorage :: < T > :: new ( chunk_size) ;
90- tile_storage. set ( tile_relative_position, self . maybe_tile ) ;
91- let translation = Vec2 :: new ( chunk_size. x as f32 , chunk_size. y as f32 ) * Vec2 :: new ( tile_size. x as f32 , tile_size. y as f32 ) * Vec2 :: new ( chunk_position. x as f32 , chunk_position. y as f32 ) ;
92- let translation = Vec3 :: new ( translation. x , translation. y , 0.0 ) ;
93- let transform = Transform :: from_translation ( translation) ;
94- w. spawn ( ( ChildOf ( self . tilemap_id ) , tile_storage, transform) ) . id ( )
95- } ) ;
96- let Some ( mut tilemap) = tilemap_entity. get_mut :: < Tilemap > ( ) else {
97- tracing:: warn!( "Could not find Tilemap on Entity {:?}" , self . tilemap_id) ;
98- return Default :: default ( ) ;
98+ let Some ( mut tile_storage) = tilestorage_entity. get_mut :: < TileStorage < T > > ( ) else {
99+ tracing:: warn!( "Could not find TileStorage on Entity {:?}" , tile_storage_id) ;
100+ return None ;
99101 } ;
100- tilemap. chunks . insert ( chunk_position, tile_storage_id) ;
101- SetTileResult { chunk_id : Some ( tile_storage_id) , replaced_tile : None }
102+
103+ tile_storage. set ( tile_relative_position, self . maybe_tile )
104+ } ) ;
105+ SetTileResult {
106+ chunk_id : Some ( tile_storage_id) ,
107+ replaced_tile,
108+ }
109+ } else {
110+ let chunk_size = tilemap. chunk_size ;
111+ let tile_size = tilemap. tile_display_size ;
112+ let tile_storage_id = tilemap_entity. world_scope ( move |w| {
113+ let mut tile_storage = TileStorage :: < T > :: new ( chunk_size) ;
114+ tile_storage. set ( tile_relative_position, self . maybe_tile ) ;
115+ let translation = Vec2 :: new ( chunk_size. x as f32 , chunk_size. y as f32 )
116+ * Vec2 :: new ( tile_size. x as f32 , tile_size. y as f32 )
117+ * Vec2 :: new ( chunk_position. x as f32 , chunk_position. y as f32 ) ;
118+ let translation = Vec3 :: new ( translation. x , translation. y , 0.0 ) ;
119+ let transform = Transform :: from_translation ( translation) ;
120+ w. spawn ( ( ChildOf ( self . tilemap_id ) , tile_storage, transform) )
121+ . id ( )
122+ } ) ;
123+ let Some ( mut tilemap) = tilemap_entity. get_mut :: < Tilemap > ( ) else {
124+ tracing:: warn!( "Could not find Tilemap on Entity {:?}" , self . tilemap_id) ;
125+ return Default :: default ( ) ;
126+ } ;
127+ tilemap. chunks . insert ( chunk_position, tile_storage_id) ;
128+ SetTileResult {
129+ chunk_id : Some ( tile_storage_id) ,
130+ replaced_tile : None ,
102131 }
132+ }
103133 }
104134}
105135
106- pub struct RemoveTile < T : TileData > {
136+ pub struct RemoveTile {
107137 pub tilemap_id : Entity ,
108138 pub tile_position : IVec2 ,
109- pub _t : PhantomData < T >
110139}
111140
112- impl < T : TileData > Command < Option < T > > for RemoveTile < T > {
113- fn apply ( self , world : & mut World ) -> Option < T > {
141+ impl Command for RemoveTile {
142+ fn apply ( self , world : & mut World ) {
114143 let Ok ( mut tilemap_entity) = world. get_entity_mut ( self . tilemap_id ) else {
115144 tracing:: warn!( "Could not find Tilemap Entity {:?}" , self . tilemap_id) ;
116- return Default :: default ( ) ;
145+ return ;
117146 } ;
118147
119148 let Some ( tilemap) = tilemap_entity. get :: < Tilemap > ( ) else {
120149 tracing:: warn!( "Could not find Tilemap on Entity {:?}" , self . tilemap_id) ;
121- return Default :: default ( ) ;
150+ return ;
122151 } ;
123152
124153 let chunk_position = tilemap. tile_chunk_position ( self . tile_position ) ;
125154 let tile_relative_position = tilemap. tile_relative_position ( self . tile_position ) ;
126-
155+
127156 if let Some ( tile_storage_id) = tilemap. chunks . get ( & chunk_position) . cloned ( ) {
128157 tilemap_entity. world_scope ( move |w| {
129- let Ok ( mut tilestorage_entity ) = w. get_entity_mut ( tile_storage_id) else {
158+ let Ok ( mut tile_storage_entity ) = w. get_entity_mut ( tile_storage_id) else {
130159 tracing:: warn!( "Could not find TileStorage Entity {:?}" , tile_storage_id) ;
131- return None ;
160+ return ;
132161 } ;
133162
134- let Some ( mut tile_storage) = tilestorage_entity. get_mut :: < TileStorage < T > > ( )
135- else {
163+ let Some ( tile_storages) = tile_storage_entity. get :: < TileStorages > ( ) . cloned ( ) else {
136164 tracing:: warn!(
137- "Could not find TileStorage on Entity {:?}" ,
165+ "Could not find TileStorages on Entity {:?}" ,
138166 tile_storage_id
139167 ) ;
140- return None ;
168+ return ;
141169 } ;
142170
143- tile_storage. remove ( tile_relative_position)
144- } )
145- }
146- else {
147- None
171+ for ( tile_storage, tile_removal) in tile_storages. removals {
172+ let Ok ( storage) = tile_storage_entity. get_mut_by_id ( tile_storage) else {
173+ continue ;
174+ } ;
175+ tile_removal ( storage, tile_relative_position) ;
176+ }
177+ } ) ;
148178 }
149179 }
150- }
180+ }
0 commit comments