/// <summary>
        /// Handles operation UnsubscribeItem: manually unsubscribes an existing InterestArea from an existing Item.
        /// The client receives event ItemUnsubscribed on success.
        /// </summary>
        public OperationResponse OperationUnsubscribeItem(PeerBase peer, OperationRequest request, SendParameters sendParameters)
        {
            var operation = new UnsubscribeItem(peer.Protocol, request);
            if (!operation.IsValid)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() };
            }

            operation.OnStart();

            Item item;
            bool actorItem = this.TryGetItem(operation.ItemId, out item);
            if (actorItem == false)
            {
                if (this.World.ItemCache.TryGetItem(operation.ItemId, out item) == false)
                {
                    return operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound");
                }
            }

            this.interestItems.UnsubscribeItem(item);

            if (actorItem)
            {
                // we are already in the item thread, invoke directly
                return this.ItemOperationUnsubscribeItem(item, operation);
            }
            else
            {
                // second parameter (peer) allows us to send an error event to the client (in case of an error)
                item.Fiber.Enqueue(() => this.ExecItemOperation(() => this.ItemOperationUnsubscribeItem(item, operation), sendParameters));

                // operation continues later
                return null;
            }
        }
        private OperationResponse ItemOperationUnsubscribeItem(Item item, UnsubscribeItem operation)
        {
            if (item.Disposed)
            {
                return operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound");
            }

            this.interestItems.UnsubscribeItem(item);

            var unsubscribeEvent = new ItemUnsubscribed { ItemId = item.Id };

            var eventData = new EventData((byte)EventCode.ItemUnsubscribed, unsubscribeEvent);
            this.Peer.SendEvent(eventData, new SendParameters { ChannelId = Settings.ItemEventChannel });

            // don't send response
            operation.OnComplete();
            return null;
        }
Example #3
0
        /// <summary>
        ///   Handles operation <see cref = "UnsubscribeItem" />: Unsubscribes an existing <see cref = "InterestArea" /> from an existing <see cref = "Item" />.
        ///   The client receives event <see cref = "ItemUnsubscribed" /> on success.
        /// </summary>
        /// <param name = "peer">
        ///   The client peer.
        /// </param>
        /// <param name = "request">
        ///   The request.
        /// </param>
        /// <returns>
        ///   Null or an <see cref = "OperationResponse" /> with error code <see cref = "ReturnCode.InterestAreaNotFound" /> or <see cref = "ReturnCode.ItemNotFound" />.
        /// </returns>
        public OperationResponse OperationUnsubscribeItem(PeerBase peer, OperationRequest request)
        {
            var operation = new UnsubscribeItem(peer.Protocol, request);
            if (!operation.IsValid)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() };
            }

            operation.OnStart();
            InterestArea interestArea;
            if (this.TryGetInterestArea(operation.InterestAreaId, out interestArea) == false)
            {
                return operation.GetOperationResponse((int)ReturnCode.InterestAreaNotFound, "InterestAreaNotFound");
            }

            IWorld world = this.World;

            Item item;
            bool actorItem = this.TryGetItem(operation.ItemType, operation.ItemId, out item);
            if (actorItem == false)
            {
                if (world.ItemCache.TryGetItem(operation.ItemType, operation.ItemId, out item) == false)
                {
                    return operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound");
                }
            }

            lock (interestArea.SyncRoot)
            {
                interestArea.UnsubscribeItem(item);
            }

            // don't send response
            return null;
        }