diff --git a/src/EcsRx.Plugins.Computeds/Groups/ComputedGroup.cs b/src/EcsRx.Plugins.Computeds/Groups/ComputedGroup.cs index 963edcb..c588b61 100644 --- a/src/EcsRx.Plugins.Computeds/Groups/ComputedGroup.cs +++ b/src/EcsRx.Plugins.Computeds/Groups/ComputedGroup.cs @@ -71,7 +71,7 @@ public void OnEntityRemovingFromGroup(IEntity entity) public void RefreshEntities() { var applicableEntities = InternalObservableGroup.Where(IsEntityApplicable).ToArray(); - var entitiesToRemove = InternalObservableGroup.Where(x => applicableEntities.All(y => y.Id != x.Id)).ToArray(); + var entitiesToRemove = CachedEntities.Where(x => applicableEntities.All(y => y.Id != x.Id)).ToArray(); var entitiesToAdd = applicableEntities.Where(x => !CachedEntities.Contains(x.Id)).ToArray(); for (var i = entitiesToAdd.Length - 1; i >= 0; i--) diff --git a/src/EcsRx.Tests/Plugins/Computeds/ComputedGroupTests.cs b/src/EcsRx.Tests/Plugins/Computeds/ComputedGroupTests.cs index 3023122..70fe800 100644 --- a/src/EcsRx.Tests/Plugins/Computeds/ComputedGroupTests.cs +++ b/src/EcsRx.Tests/Plugins/Computeds/ComputedGroupTests.cs @@ -129,5 +129,73 @@ public void should_only_remove_and_fire_events_when_non_applicable_entity_remove Assert.Equal(1, removingFiredTimes); Assert.Equal(1, removedFiredTimes); } + + [Fact] + public void should_only_fire_events_from_refresh_when_cache_changed() + { + + var applicableEntity = Substitute.For(); + applicableEntity.Id.Returns(1); + applicableEntity.HasComponent().Returns(false); + + var inapplicableEntity = Substitute.For(); + inapplicableEntity.Id.Returns(2); + inapplicableEntity.HasComponent().Returns(false); + + var dummyEntitySnapshot = new List { applicableEntity, inapplicableEntity }; + + var mockObservableGroup = Substitute.For(); + mockObservableGroup.GetEnumerator().Returns(x => dummyEntitySnapshot.GetEnumerator()); + mockObservableGroup.OnEntityAdded.Returns(Observable.Empty()); + mockObservableGroup.OnEntityRemoving.Returns(Observable.Empty()); + mockObservableGroup.OnEntityRemoved.Returns(Observable.Empty()); + + var computedGroup = new TestComputedGroup(mockObservableGroup); + + var addedFiredTimes = 0; + computedGroup.OnEntityAdded.Subscribe(x => + { + addedFiredTimes++; + }); + + var removingFiredTimes = 0; + computedGroup.OnEntityRemoving.Subscribe(x => + { + removingFiredTimes++; + }); + + var removedFiredTimes = 0; + computedGroup.OnEntityRemoved.Subscribe(x => + { + removedFiredTimes++; + }); + + //No events should fire + computedGroup.RefreshEntities(); + + Assert.Equal(0, addedFiredTimes); + Assert.Equal(0, removingFiredTimes); + Assert.Equal(0, removedFiredTimes); + + applicableEntity.HasComponent().Returns(true); + + //Add should fire only once + computedGroup.RefreshEntities(); + + Assert.Single(computedGroup.CachedEntities); + Assert.Equal(1, addedFiredTimes); + Assert.Equal(0, removingFiredTimes); + Assert.Equal(0, removedFiredTimes); + + applicableEntity.HasComponent().Returns(false); + + //Remove should fire only once + computedGroup.RefreshEntities(); + + Assert.Empty(computedGroup.CachedEntities); + Assert.Equal(1, addedFiredTimes); + Assert.Equal(1, removingFiredTimes); + Assert.Equal(1, removedFiredTimes); + } } } \ No newline at end of file