/// <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
        }
Esempio n. 2
0
        /// <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

            KnownEntities.LockObject.EnterReadLock();
            try
            {
                //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 entity in KnownEntities)
                {
                    InterestCollection interestCollection = ManagedInterestCollections.RetrieveEntity(entity);

                    //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 (!interestCollection.HasPendingChanges())
                    {
                        continue;
                    }

                    //We should only build packets for players.
                    if (entity.EntityType == EntityType.Player)
                    {
                        VisibilityMessageSender.Send(new EntityVisibilityChangeContext(entity, interestCollection));
                    }

                    //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(interestCollection);

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