/// <inheritdoc />
        protected override void OnFinishedServicingEvents()
        {
            //After ALL the queued interest changes have been serviced
            //we can actually handle the changes and send them and such

            //We need to iterate the entire interest dictionary
            //That means we need to check the new incoming and outgoing entities
            //We do this because we need to build update packets for the players
            //so that they can become aware of them AND we can start pushing
            //events to them
            foreach (var kvp in ManagedInterestCollections)
            {
                //We want to skip any collection that doesn't have any pending changes.
                //No reason to send a message about it nor dequeue anything
                if (!kvp.Value.HasPendingChanges())
                {
                    continue;
                }

                //Even though this modifies the collections
                //the write lock of this type is reserved only
                //for adding or removing new entities. Not for
                //actually changing the data itself.
                using (LockingPolicy.ReaderLock(null, CancellationToken.None))
                {
                    //We should only build packets for players.
                    if (kvp.Key.EntityType == EntityType.Player)
                    {
                        VisibilityMessageSender.Send(new EntityVisibilityChangeContext(kvp.Key, kvp.Value));
                    }

                    //No matter player or NPC we should dequeue the joining/leaving
                    //entites so that the state of the known entites reflects the diff packets sent
                    InterestDequeueSetCommand dequeueCommand = new InterestDequeueSetCommand(kvp.Value, kvp.Value);

                    //TODO: Should we execute right away? Or after all packets are sent?
                    dequeueCommand.Execute();
                }
            }

#if DEBUG || DEBUG_BUILD
            foreach (var kvp in ManagedInterestCollections)
            {
                if (!kvp.Value.EnteringDequeueable.isEmpty)
                {
                    throw new InvalidOperationException($"Failed to fully queue: {nameof(kvp.Value.EnteringDequeueable)}");
                }

                if (!kvp.Value.LeavingDequeueable.isEmpty)
                {
                    throw new InvalidOperationException($"Failed to fully queue: {nameof(kvp.Value.LeavingDequeueable)}");
                }
            }
#endif
        }
예제 #2
0
        public void Test_DequeueCommand_Handles_Entering_Entities()
        {
            //arrange
            //InterestDequeueSetCommand
            InterestCollection interestCollection = new InterestCollection();

            interestCollection.Register(new NetworkEntityGuid(1), new NetworkEntityGuid(1));
            interestCollection.Register(new NetworkEntityGuid(2), new NetworkEntityGuid(2));

            //act
            Assert.AreEqual(0, interestCollection.ContainedEntities.Count);
            InterestDequeueSetCommand dequeue = new InterestDequeueSetCommand(interestCollection, interestCollection);

            dequeue.Execute();

            //assert
            Assert.AreEqual(2, interestCollection.ContainedEntities.Count);
            Assert.True(interestCollection.EnteringDequeueable.isEmpty);
        }
예제 #3
0
        public void Test_DequeueCommand_Handles_Leaving_Entities()
        {
            //arrange
            //InterestDequeueSetCommand
            InterestCollection interestCollection = new InterestCollection();

            interestCollection.Add(new NetworkEntityGuid(1));
            interestCollection.Add(new NetworkEntityGuid(2));

            interestCollection.Unregister(new NetworkEntityGuid(1));
            interestCollection.Unregister(new NetworkEntityGuid(2));

            //act
            Assert.AreEqual(2, interestCollection.ContainedEntities.Count, "Has no contained entites.");
            InterestDequeueSetCommand dequeue = new InterestDequeueSetCommand(interestCollection, interestCollection);

            dequeue.Execute();

            //assert
            Assert.AreEqual(0, interestCollection.ContainedEntities.Count, "Expected the contained entities to be removed, but some remained.");
            Assert.True(interestCollection.LeavingDequeueable.isEmpty);
        }