Пример #1
0
        public void should_include_entity_snapshot_on_creation()
        {
            var mockEventSystem = Substitute.For <IEventSystem>();
            var accessorToken   = new ObservableGroupToken(new Type[] { }, "default");

            mockEventSystem.Receive <EntityAddedEvent>().Returns(Observable.Empty <EntityAddedEvent>());
            mockEventSystem.Receive <EntityRemovedEvent>().Returns(Observable.Empty <EntityRemovedEvent>());
            mockEventSystem.Receive <ComponentsAddedEvent>().Returns(Observable.Empty <ComponentsAddedEvent>());
            mockEventSystem.Receive <ComponentsRemovedEvent>().Returns(Observable.Empty <ComponentsRemovedEvent>());

            var dummyEntitySnapshot = new List <IEntity>
            {
                new Entity(Guid.NewGuid(), mockEventSystem),
                new Entity(Guid.NewGuid(), mockEventSystem),
                new Entity(Guid.NewGuid(), mockEventSystem)
            };

            var cacheableGroupAccessor = new ObservableGroup(mockEventSystem, accessorToken, dummyEntitySnapshot);

            Assert.Equal(3, cacheableGroupAccessor.CachedEntities.Count);
            Assert.Equal(dummyEntitySnapshot[0], cacheableGroupAccessor.CachedEntities[dummyEntitySnapshot[0].Id]);
            Assert.Equal(dummyEntitySnapshot[1], cacheableGroupAccessor.CachedEntities[dummyEntitySnapshot[1].Id]);
            Assert.Equal(dummyEntitySnapshot[2], cacheableGroupAccessor.CachedEntities[dummyEntitySnapshot[2].Id]);

            cacheableGroupAccessor.Dispose();
        }
Пример #2
0
        public void should_only_add_entity_when_components_match_group()
        {
            var mockEventSystem = Substitute.For <IEventSystem>();
            var accessorToken   = new ObservableGroupToken(new[] { typeof(TestComponentOne), typeof(TestComponentTwo) }, "default");

            var existingEntityOne = new Entity(Guid.NewGuid(), mockEventSystem);
            var componentToAdd    = new TestComponentOne();

            existingEntityOne.AddComponent <TestComponentTwo>();

            var existingEntityTwo     = new Entity(Guid.NewGuid(), mockEventSystem);
            var unapplicableComponent = new TestComponentThree();

            existingEntityTwo.AddComponent <TestComponentOne>();

            var dummyEventToSeedMock = new ComponentsAddedEvent(new Entity(Guid.NewGuid(), mockEventSystem), new[] { new TestComponentOne() });
            var underlyingEvent      = new ReactiveProperty <ComponentsAddedEvent>(dummyEventToSeedMock);

            mockEventSystem.Receive <ComponentsAddedEvent>().Returns(underlyingEvent);
            mockEventSystem.Receive <ComponentsRemovedEvent>().Returns(Observable.Empty <ComponentsRemovedEvent>());
            mockEventSystem.Receive <EntityAddedEvent>().Returns(Observable.Empty <EntityAddedEvent>());
            mockEventSystem.Receive <EntityRemovedEvent>().Returns(Observable.Empty <EntityRemovedEvent>());

            var cacheableGroupAccessor = new ObservableGroup(mockEventSystem, accessorToken, new IEntity[] {});

            existingEntityOne.AddComponent(componentToAdd);
            underlyingEvent.SetValueAndForceNotify(new ComponentsAddedEvent(existingEntityOne, new[] { componentToAdd }));

            existingEntityTwo.AddComponent(unapplicableComponent);
            underlyingEvent.SetValueAndForceNotify(new ComponentsAddedEvent(existingEntityTwo, new[] { unapplicableComponent }));

            Assert.Equal(1, cacheableGroupAccessor.CachedEntities.Count);
            Assert.Equal <IEntity>(existingEntityOne, cacheableGroupAccessor.CachedEntities[existingEntityOne.Id]);
        }
Пример #3
0
        public void should_only_remove_applicable_entity_when_entity_removed()
        {
            var mockEventSystem = Substitute.For <IEventSystem>();
            var accessorToken   = new ObservableGroupToken(new[] { typeof(TestComponentOne), typeof(TestComponentTwo) }, "default");
            var mockCollection  = Substitute.For <IEntityCollection>();

            var existingEntityOne = new Entity(Guid.NewGuid(), mockEventSystem);

            existingEntityOne.AddComponent <TestComponentOne>();
            existingEntityOne.AddComponent <TestComponentTwo>();

            var existingEntityTwo = new Entity(Guid.NewGuid(), mockEventSystem);

            existingEntityTwo.AddComponent <TestComponentOne>();
            existingEntityTwo.AddComponent <TestComponentTwo>();

            var unapplicableEntity = new Entity(Guid.NewGuid(), mockEventSystem);

            unapplicableEntity.AddComponent <TestComponentOne>();

            var underlyingEvent = new ReactiveProperty <EntityRemovedEvent>(new EntityRemovedEvent(unapplicableEntity, mockCollection));

            mockEventSystem.Receive <EntityRemovedEvent>().Returns(underlyingEvent);
            mockEventSystem.Receive <EntityAddedEvent>().Returns(Observable.Empty <EntityAddedEvent>());
            mockEventSystem.Receive <ComponentsAddedEvent>().Returns(Observable.Empty <ComponentsAddedEvent>());
            mockEventSystem.Receive <ComponentsRemovedEvent>().Returns(Observable.Empty <ComponentsRemovedEvent>());

            var cacheableGroupAccessor = new ObservableGroup(mockEventSystem, accessorToken, new IEntity[] { existingEntityOne, existingEntityTwo });

            underlyingEvent.SetValueAndForceNotify(new EntityRemovedEvent(existingEntityOne, mockCollection));

            Assert.Equal(1, cacheableGroupAccessor.CachedEntities.Count);
            Assert.Equal <IEntity>(existingEntityTwo, cacheableGroupAccessor.CachedEntities[existingEntityTwo.Id]);
        }
Пример #4
0
        public void should_add_entity_and_raise_event_when_components_match_group()
        {
            var collectionName = "default";
            var accessorToken  = new ObservableGroupToken(new[] { 1 }, new [] { 2 }, collectionName);
            var mockCollection = Substitute.For <IEntityCollection>();

            mockCollection.Name.Returns(collectionName);

            var applicableEntity = Substitute.For <IEntity>();

            applicableEntity.Id.Returns(1);

            var mockCollectionNotifier = Substitute.For <INotifyingEntityCollection>();

            var componentRemoved = new Subject <ComponentsChangedEvent>();

            mockCollectionNotifier.EntityAdded.Returns(Observable.Empty <CollectionEntityEvent>());
            mockCollectionNotifier.EntityRemoved.Returns(Observable.Empty <CollectionEntityEvent>());
            mockCollectionNotifier.EntityComponentsAdded.Returns(Observable.Empty <ComponentsChangedEvent>());
            mockCollectionNotifier.EntityComponentsRemoving.Returns(Observable.Empty <ComponentsChangedEvent>());
            mockCollectionNotifier.EntityComponentsRemoved.Returns(componentRemoved);

            var observableGroup = new ObservableGroup(accessorToken, new IEntity[0], mockCollectionNotifier);
            var wasCalled       = 0;

            observableGroup.OnEntityAdded.Subscribe(x => wasCalled++);

            applicableEntity.HasAllComponents(accessorToken.LookupGroup.RequiredComponents).Returns(true);
            applicableEntity.HasAnyComponents(accessorToken.LookupGroup.ExcludedComponents).Returns(false);
            componentRemoved.OnNext(new ComponentsChangedEvent(mockCollection, applicableEntity, null));

            Assert.Contains(applicableEntity, observableGroup.CachedEntities.Values);
            Assert.Equal(1, wasCalled);
        }
Пример #5
0
        public override void EventTriggered(SavePipelineEvent eventData)
        {
            var entity      = ObservableGroup.Single();
            var playerState = entity.GetComponent <PlayerStateComponent>();

            Task.Run(() => TriggerPipeline(playerState));
        }
        public void Ctor_ShouldHaveExpectedState()
        {
            var group = new ObservableGroup <string, int>("key");

            group.Key.Should().Be("key");
            group.Should().BeEmpty();
        }
Пример #7
0
        public void should_not_cache_applicable_entity_when_added_to_different_collection()
        {
            var mockEventSystem = Substitute.For <IEventSystem>();
            var collectionName  = "defaut";
            var accessorToken   = new ObservableGroupToken(new[] { typeof(TestComponentOne), typeof(TestComponentTwo) }, "some-other-entityCollection-name");
            var mockCollection  = Substitute.For <IEntityCollection>();

            mockCollection.Name.Returns(collectionName);

            var applicableEntity = new Entity(Guid.NewGuid(), mockEventSystem);

            applicableEntity.AddComponent <TestComponentOne>();
            applicableEntity.AddComponent <TestComponentTwo>();

            var unapplicableEntity = new Entity(Guid.NewGuid(), mockEventSystem);

            unapplicableEntity.AddComponent <TestComponentOne>();

            var underlyingEvent = new ReactiveProperty <EntityAddedEvent>(new EntityAddedEvent(applicableEntity, mockCollection));

            mockEventSystem.Receive <EntityAddedEvent>().Returns(underlyingEvent);
            mockEventSystem.Receive <EntityRemovedEvent>().Returns(Observable.Empty <EntityRemovedEvent>());
            mockEventSystem.Receive <ComponentsAddedEvent>().Returns(Observable.Empty <ComponentsAddedEvent>());
            mockEventSystem.Receive <ComponentsRemovedEvent>().Returns(Observable.Empty <ComponentsRemovedEvent>());

            var cacheableGroupAccessor = new ObservableGroup(mockEventSystem, accessorToken, new IEntity[] { });

            underlyingEvent.SetValueAndForceNotify(new EntityAddedEvent(unapplicableEntity, mockCollection));

            Assert.Empty(cacheableGroupAccessor.CachedEntities);
        }
Пример #8
0
        public void should_correctly_notify_when_matching_component_removed()
        {
            var componentTypes  = new[] { typeof(TestComponentOne), typeof(TestComponentTwo) };
            var fakeEventSystem = new EventSystem(new MessageBroker());
            var accessorToken   = new ObservableGroupToken(componentTypes, "default");

            var fakeEntity1 = new Entity(Guid.Empty, fakeEventSystem);

            fakeEntity1.AddComponent <TestComponentOne>();
            fakeEntity1.AddComponent <TestComponentTwo>();
            fakeEntity1.AddComponent <TestComponentThree>();

            var fakeEntity2 = new Entity(Guid.Empty, fakeEventSystem);

            fakeEntity2.AddComponent <TestComponentOne>();
            fakeEntity2.AddComponent <TestComponentThree>();

            var timesCalled = 0;

            var observableGroup = new ObservableGroup(fakeEventSystem, accessorToken, new IEntity[] { fakeEntity1 });

            ObservableExtensions.Subscribe <IEntity>(observableGroup.OnEntityRemoved, x =>
            {
                Assert.Equal <IEntity>(fakeEntity1, x);
                timesCalled++;
            });

            fakeEntity1.RemoveComponent <TestComponentThree>();
            fakeEntity1.RemoveComponent <TestComponentTwo>();
            fakeEntity2.RemoveComponent <TestComponentThree>();

            Assert.Equal(1, timesCalled);
        }
        public void Ctor_WithCollection_ShouldHaveExpectedState()
        {
            var source = new[] { 1, 2, 3 };
            var group  = new ObservableGroup <string, int>("key", source);

            group.Key.Should().Be("key");
            group.Should().BeEquivalentTo(new[] { 1, 2, 3 }, option => option.WithStrictOrdering());
        }
        public void IReadOnlyObservableGroup_ShouldReturnExpectedValues(int count)
        {
            var group = new ObservableGroup <string, int>("key", Enumerable.Range(0, count));
            var iReadOnlyObservableGroup = (IReadOnlyObservableGroup)group;

            iReadOnlyObservableGroup.Key.Should().Be("key");
            iReadOnlyObservableGroup.Count.Should().Be(count);
        }
        public void Remove_ShouldRaiseEvent()
        {
            var collectionChangedEventRaised = false;
            var source = new[] { 1, 2, 3 };
            var group  = new ObservableGroup <string, int>("key", source);

            ((INotifyCollectionChanged)group).CollectionChanged += (s, e) => collectionChangedEventRaised = true;

            group.Remove(1);

            group.Key.Should().Be("key");
            group.Should().BeEquivalentTo(new[] { 2, 3 }, option => option.WithStrictOrdering());
            collectionChangedEventRaised.Should().BeTrue();
        }
        public void Clear_ShouldRaiseEvent()
        {
            var collectionChangedEventRaised = false;
            var source = new[] { 1, 2, 3 };
            var group  = new ObservableGroup <string, int>("key", source);

            ((INotifyCollectionChanged)group).CollectionChanged += (s, e) => collectionChangedEventRaised = true;

            group.Clear();

            group.Key.Should().Be("key");
            group.Should().BeEmpty();
            collectionChangedEventRaised.Should().BeTrue();
        }
Пример #13
0
        public void should_remove_entity_and_raise_events_when_entity_removed_with_components()
        {
            var collectionName = "default";
            var accessorToken  = new ObservableGroupToken(new[] { 1, 2 }, new int[0], collectionName);
            var mockCollection = Substitute.For <IEntityCollection>();

            mockCollection.Name.Returns(collectionName);

            var applicableEntity = Substitute.For <IEntity>();

            applicableEntity.Id.Returns(1);
            applicableEntity.HasComponent(Arg.Is <int>(x => accessorToken.LookupGroup.RequiredComponents.Contains(x))).Returns(true);
            applicableEntity.HasComponent(Arg.Is <int>(x => accessorToken.LookupGroup.ExcludedComponents.Contains(x))).Returns(false);

            var mockCollectionNotifier = Substitute.For <INotifyingEntityCollection>();

            var entityRemoved     = new Subject <CollectionEntityEvent>();
            var componentRemoving = new Subject <ComponentsChangedEvent>();

            mockCollectionNotifier.EntityRemoved.Returns(entityRemoved);
            mockCollectionNotifier.EntityAdded.Returns(Observable.Empty <CollectionEntityEvent>());
            mockCollectionNotifier.EntityComponentsAdded.Returns(Observable.Empty <ComponentsChangedEvent>());
            mockCollectionNotifier.EntityComponentsRemoving.Returns(componentRemoving);
            mockCollectionNotifier.EntityComponentsRemoved.Returns(Observable.Empty <ComponentsChangedEvent>());

            var observableGroup   = new ObservableGroup(accessorToken, new[] { applicableEntity }, mockCollectionNotifier);
            var wasRemovingCalled = 0;

            observableGroup.OnEntityRemoving.Subscribe(x => wasRemovingCalled++);
            var wasRemovedCalled = 0;

            observableGroup.OnEntityRemoved.Subscribe(x => wasRemovedCalled++);

            componentRemoving.OnNext(new ComponentsChangedEvent(null, applicableEntity, new[] { 1 }));

            Assert.Contains(applicableEntity, observableGroup.CachedEntities.Values);
            Assert.Equal(1, wasRemovingCalled);
            Assert.Equal(0, wasRemovedCalled);

            wasRemovingCalled = wasRemovedCalled = 0;
            entityRemoved.OnNext(new CollectionEntityEvent(applicableEntity, null));

            Assert.DoesNotContain(applicableEntity, observableGroup.CachedEntities.Values);
            Assert.Equal(0, wasRemovingCalled);
            Assert.Equal(1, wasRemovedCalled);
        }
Пример #14
0
        public void should_add_entity_and_raise_event_when_applicable_entity_added()
        {
            var collectionName = "default";
            var accessorToken  = new ObservableGroupToken(new[] { 1, 2 }, new int[0], collectionName);
            var mockCollection = Substitute.For <IEntityCollection>();

            mockCollection.Name.Returns(collectionName);

            var applicableEntity = Substitute.For <IEntity>();

            applicableEntity.Id.Returns(1);
            applicableEntity.HasComponent(Arg.Is <int>(x => accessorToken.LookupGroup.RequiredComponents.Contains(x))).Returns(true);

            var unapplicableEntity = Substitute.For <IEntity>();

            unapplicableEntity.Id.Returns(2);
            unapplicableEntity.HasComponent(Arg.Is <int>(x => accessorToken.LookupGroup.RequiredComponents.Contains(x))).Returns(false);

            var mockCollectionNotifier = Substitute.For <INotifyingEntityCollection>();

            var entityAddedSub = new Subject <CollectionEntityEvent>();

            mockCollectionNotifier.EntityAdded.Returns(entityAddedSub);
            mockCollectionNotifier.EntityRemoved.Returns(Observable.Empty <CollectionEntityEvent>());
            mockCollectionNotifier.EntityComponentsAdded.Returns(Observable.Empty <ComponentsChangedEvent>());
            mockCollectionNotifier.EntityComponentsRemoving.Returns(Observable.Empty <ComponentsChangedEvent>());
            mockCollectionNotifier.EntityComponentsRemoved.Returns(Observable.Empty <ComponentsChangedEvent>());

            var observableGroup = new ObservableGroup(accessorToken, new IEntity[0], mockCollectionNotifier);
            var wasCalled       = 0;

            observableGroup.OnEntityAdded.Subscribe(x => wasCalled++);

            entityAddedSub.OnNext(new CollectionEntityEvent(unapplicableEntity, mockCollection));
            Assert.Empty(observableGroup.CachedEntities);

            entityAddedSub.OnNext(new CollectionEntityEvent(applicableEntity, mockCollection));
            Assert.Equal(1, observableGroup.CachedEntities.Count);
            Assert.Equal(applicableEntity, observableGroup.CachedEntities[applicableEntity.Id]);

            Assert.Equal(1, wasCalled);
        }
Пример #15
0
        public void should_correctly_notify_when_matching_entity_removed()
        {
            var componentTypes  = new[] { typeof(TestComponentOne), typeof(TestComponentTwo) };
            var mockEventSystem = Substitute.For <IEventSystem>();
            var mockCollection  = Substitute.For <IEntityCollection>();
            var accessorToken   = new ObservableGroupToken(componentTypes, "default");

            var fakeEntity1 = new Entity(Guid.Empty, mockEventSystem);

            fakeEntity1.AddComponent <TestComponentOne>();
            fakeEntity1.AddComponent <TestComponentTwo>();

            var fakeEntity2 = new Entity(Guid.Empty, mockEventSystem);

            fakeEntity2.AddComponent <TestComponentOne>();
            fakeEntity2.AddComponent <TestComponentThree>();

            var timesCalled = 0;

            mockCollection.Name.Returns("default");

            var underlyingEvent = new Subject <EntityRemovedEvent>();

            mockEventSystem.Receive <ComponentsAddedEvent>().Returns(Observable.Empty <ComponentsAddedEvent>());
            mockEventSystem.Receive <ComponentsRemovedEvent>().Returns(Observable.Empty <ComponentsRemovedEvent>());
            mockEventSystem.Receive <EntityAddedEvent>().Returns(Observable.Empty <EntityAddedEvent>());
            mockEventSystem.Receive <EntityRemovedEvent>().Returns(underlyingEvent);

            var observableGroup = new ObservableGroup(mockEventSystem, accessorToken, new IEntity[] { fakeEntity1 });

            ObservableExtensions.Subscribe <IEntity>(observableGroup.OnEntityRemoved, x =>
            {
                Assert.Equal <IEntity>(fakeEntity1, x);
                timesCalled++;
            });

            underlyingEvent.OnNext(new EntityRemovedEvent(fakeEntity1, mockCollection));
            underlyingEvent.OnNext(new EntityRemovedEvent(fakeEntity2, mockCollection));

            Assert.Equal(1, timesCalled);
        }
        public void ReplaceGroupInSource_ShoudReplaceGroup()
        {
            NotifyCollectionChangedEventArgs collectionChangedEventArgs = null;
            var collectionChangedEventsCount      = 0;
            var isCountPropertyChangedEventRaised = false;
            var aItemsList = new[] { 1, 2, 3 };
            var bItemsList = new[] { 2, 4, 6 };
            var cItemsList = new[] { 7, 8, 9 };
            var groups     = new List <IGrouping <string, int> >
            {
                new IntGroup("A", aItemsList),
                new IntGroup("B", bItemsList),
            };
            var source        = new ObservableGroupedCollection <string, int>(groups);
            var readOnlyGroup = new ReadOnlyObservableGroupedCollection <string, int>(source);

            ((INotifyCollectionChanged)readOnlyGroup).CollectionChanged += (s, e) =>
            {
                collectionChangedEventArgs = e;
                collectionChangedEventsCount++;
            };
            ((INotifyPropertyChanged)readOnlyGroup).PropertyChanged += (s, e) => isCountPropertyChangedEventRaised = isCountPropertyChangedEventRaised || e.PropertyName == nameof(readOnlyGroup.Count);

            source[0] = new ObservableGroup <string, int>("C", cItemsList);

            readOnlyGroup.Should().HaveCount(2);
            readOnlyGroup.Count.Should().Be(2);
            readOnlyGroup.ElementAt(0).Key.Should().Be("C");
            readOnlyGroup.ElementAt(0).Should().BeEquivalentTo(cItemsList, o => o.WithoutStrictOrdering());
            readOnlyGroup.ElementAt(1).Key.Should().Be("B");
            readOnlyGroup.ElementAt(1).Should().BeEquivalentTo(bItemsList, o => o.WithoutStrictOrdering());

            isCountPropertyChangedEventRaised.Should().BeFalse();
            collectionChangedEventArgs.Should().NotBeNull();
            collectionChangedEventsCount.Should().Be(1);
            IsReplaceEventValid(collectionChangedEventArgs, aItemsList, cItemsList).Should().BeTrue();
        }
Пример #17
0
        public void should_include_entity_snapshot_on_creation()
        {
            var mockCollectionNotifier = Substitute.For <INotifyingEntityCollection>();
            var accessorToken          = new ObservableGroupToken(new[] { 1 }, new int[0], "default");

            var applicableEntity1    = Substitute.For <IEntity>();
            var applicableEntity2    = Substitute.For <IEntity>();
            var notApplicableEntity1 = Substitute.For <IEntity>();

            applicableEntity1.Id.Returns(1);
            applicableEntity2.Id.Returns(2);
            notApplicableEntity1.Id.Returns(3);

            applicableEntity1.HasComponent(Arg.Any <int>()).Returns(true);
            applicableEntity2.HasComponent(Arg.Any <int>()).Returns(true);
            notApplicableEntity1.HasComponent(Arg.Any <int>()).Returns(false);

            var dummyEntitySnapshot = new List <IEntity>
            {
                applicableEntity1,
                applicableEntity2,
                notApplicableEntity1
            };

            mockCollectionNotifier.EntityAdded.Returns(Observable.Empty <CollectionEntityEvent>());
            mockCollectionNotifier.EntityRemoved.Returns(Observable.Empty <CollectionEntityEvent>());
            mockCollectionNotifier.EntityComponentsAdded.Returns(Observable.Empty <ComponentsChangedEvent>());
            mockCollectionNotifier.EntityComponentsRemoving.Returns(Observable.Empty <ComponentsChangedEvent>());
            mockCollectionNotifier.EntityComponentsRemoved.Returns(Observable.Empty <ComponentsChangedEvent>());

            var observableGroup = new ObservableGroup(accessorToken, dummyEntitySnapshot, mockCollectionNotifier);

            Assert.Equal(2, observableGroup.CachedEntities.Count);
            Assert.Contains(applicableEntity1, observableGroup.CachedEntities.Values);
            Assert.Contains(applicableEntity2, observableGroup.CachedEntities.Values);
        }