Пример #1
0
 private void ThrowIfNoEntityInterestManaged(NetworkEntityGuid entryContext, NetworkEntityGuid entityGuid)
 {
     if (!ManagedInterestCollections.ContainsKey(entryContext))
     {
         throw new InvalidOperationException($"Guid: {entityGuid} tried to enter Entity: {entryContext} interest. But Entity does not maintain interest. Does not exist in interest collection.");
     }
 }
Пример #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();
            }
        }
Пример #3
0
        /// <inheritdoc />
        protected override void HandleEvent(EntityInterestChangeEventArgs args)
        {
            //TODO: Check if entity is still known
            KnownEntities.LockObject.EnterReadLock();
            try
            {
                ThrowIfNoEntityInterestManaged(args.EnterableEntity, args.EnteringEntity);

                //When we encounter an entity interest change, we just want to register into the interest collection
                //Something should eventually run to handle the interest changes, we just basically register/queue them up.
                switch (args.ChangingType)
                {
                case EntityInterestChangeEventArgs.ChangeType.Enter:
                    //HelloKitty: Yea, so if we actually register a change of ourselves it actually breaks the client for some reason
                    //right now but technically everything is fine even if we do. No exceptions on either the client or server. Very strange
                    //but limited time to investigate
                    if (args.EnterableEntity != args.EnteringEntity)
                    //if (!ManagedInterestCollections.RetrieveEntity(args.EnterableEntity).Contains(args.EnteringEntity))
                    {
                        //If the entity already knows the entity then we should not register it.
                        ManagedInterestCollections.RetrieveEntity(args.EnterableEntity).Register(args.EnteringEntity, args.EnteringEntity);
                        ActorReferenceMappable.RetrieveEntity(args.EnterableEntity).Tell(new EntityInterestGainedMessage(args.EnteringEntity), ActorReferenceMappable.RetrieveEntity(args.EnterableEntity));
                    }
                    break;

                case EntityInterestChangeEventArgs.ChangeType.Exit:
                    //It's possible we'll want to be having an entity EXIT without being known.
                    //They could have Entered (and will be added above at some point) but within
                    //the time before this interest system services interest it's possible
                    //that they also LEFT it. Therefore there could be an ENTER + EXIT in one go.
                    //Registering exits always will address this cleanup.
                    ManagedInterestCollections.RetrieveEntity(args.EnterableEntity).Unregister(args.EnteringEntity);
                    ActorReferenceMappable.RetrieveEntity(args.EnterableEntity).Tell(new EntityInterestRemoveMessage(args.EnteringEntity), ActorReferenceMappable.RetrieveEntity(args.EnterableEntity));
                    break;
                }
            }
            finally
            {
                KnownEntities.LockObject.ExitReadLock();
            }
        }