@@ -358,13 +358,20 @@ enum DiffWireRef<'a, C, Patch> {
358358pub trait DiffEntityExt {
359359 /// Applies `patch` to component `C` and records it in the entity's [`PatchHistory`].
360360 ///
361+ /// [`EntityWorldMut`] and [`EntityCommands`] insert missing patch history before
362+ /// recording. [`EntityMut`] can't perform structural changes, so it requires an
363+ /// existing [`PatchHistory`].
364+ ///
361365 /// For [`EntityCommands`], this queues the patch application. Missing components
362366 /// or patch application errors are reported when commands are applied.
363367 fn apply_patch < C : Diffable > ( & mut self , patch : C :: Patch ) -> Result < ( ) > ;
364368}
365369
366370impl DiffEntityExt for EntityWorldMut < ' _ > {
367371 fn apply_patch < C : Diffable > ( & mut self , patch : C :: Patch ) -> Result < ( ) > {
372+ if !self . contains :: < PatchHistory < C > > ( ) {
373+ self . insert ( PatchHistory :: < C > :: default ( ) ) ;
374+ }
368375 let mut entity = self . as_mutable ( ) ;
369376 apply_patch_to_entity :: < C > ( & mut entity, patch)
370377 }
@@ -378,7 +385,12 @@ impl DiffEntityExt for EntityMut<'_> {
378385
379386impl DiffEntityExt for EntityCommands < ' _ > {
380387 fn apply_patch < C : Diffable > ( & mut self , patch : C :: Patch ) -> Result < ( ) > {
381- self . queue ( move |mut entity : EntityWorldMut | entity. apply_patch :: < C > ( patch) ) ;
388+ self . queue ( move |mut entity : EntityWorldMut | {
389+ if !self . contains :: < PatchHistory < C > > ( ) {
390+ self . insert ( PatchHistory :: < C > :: default ( ) ) ;
391+ }
392+ entity. apply_patch :: < C > ( patch)
393+ } ) ;
382394 Ok ( ( ) )
383395 }
384396}
@@ -464,7 +476,6 @@ pub(crate) fn register_required_components<C: Diffable>(
464476 world : & mut World ,
465477 registry : & mut ReplicationRegistry ,
466478) -> ComponentId {
467- world. register_required_components :: < C , PatchHistory < C > > ( ) ;
468479 registry. set_receive_fns :: < C > ( world, write :: < C > , remove :: < C > ) ;
469480 world. register_component :: < PatchHistory < C > > ( )
470481}
@@ -609,7 +620,7 @@ pub(crate) fn write<C: Diffable>(
609620
610621pub ( crate ) fn remove < C : Diffable > ( _ctx : & mut RemoveCtx , entity : & mut DeferredEntity ) {
611622 entity
612- . remove :: < C > ( )
623+ . remove_with_requires :: < C > ( )
613624 . remove :: < PatchHistory < C > > ( )
614625 . remove :: < PatchBuffer < C > > ( ) ;
615626}
@@ -642,4 +653,16 @@ mod tests {
642653 assert_eq ! ( batches. first_index( ) , 1 ) ;
643654 assert ! ( !batches. is_empty( ) ) ;
644655 }
656+
657+ #[ test]
658+ fn entity_world_mut_apply_patch_inserts_missing_history ( ) {
659+ let mut world = World :: new ( ) ;
660+ let entity = world. spawn ( TestDiff ( 0 ) ) . id ( ) ;
661+
662+ world. entity_mut ( entity) . apply_patch :: < TestDiff > ( 1 ) . unwrap ( ) ;
663+
664+ let entity = world. entity ( entity) ;
665+ assert_eq ! ( entity. get:: <TestDiff >( ) . unwrap( ) . 0 , 1 ) ;
666+ assert ! ( entity. contains:: <PatchHistory <TestDiff >>( ) ) ;
667+ }
645668}
0 commit comments