示例#1
0
        /// <summary>
        /// Modifying messages instead of cache objects as cache objects are not meant to
        /// be modified locally but only as response to messages from cloud.
        /// </summary>
        /// <param name="modifyRequest"></param>
        public void ModifyObject(ModifyRequestMessage modifyRequest)
        {
            CloudObject cloudObject = cloudCache.GetObject(modifyRequest.ObjectFragment.ObjectId);

            modifyRequest.ObjectFragment.ObjectIndex = cloudObject.RemoteObjectIndex;
            client.Send(modifyRequest);
        }
示例#2
0
 public void RemoveObject(Guid objectId)
 {
     if (objects.ContainsKey(objectId))
     {
         CloudObject cloudObject = objects[objectId];
         objects.Remove(objectId);
         objectList.Remove(objectId);
         bubbleObjects[cloudObject.BubbleId].Remove(objectId);
         bubbleObjectGuidIndexDictionary[cloudObject.BubbleId].Remove(objectId);
         bubbleObjectIndexGuidDictionary[cloudObject.BubbleId].Remove(cloudObject.RemoteObjectIndex);
         if (bubbleObjects[cloudObject.BubbleId].Count == 0)
         {
             bubbleObjects.Remove(cloudObject.BubbleId);
             bubbleObjectGuidIndexDictionary.Remove(cloudObject.BubbleId);
             bubbleObjectIndexGuidDictionary.Remove(cloudObject.BubbleId);
         }
         objectBubbleDictionary.Remove(cloudObject.ObjectId);
         objectKDTree.Remove(objectId);
         participantObjects[objectParticipantDictionary[objectId]].Remove(objectId);
         if (participantObjects[objectParticipantDictionary[objectId]].Count == 0)
         {
             participantObjects.Remove(objectParticipantDictionary[objectId]);
         }
         objectParticipantDictionary.Remove(objectId);
         CacheObjectRemoved(cloudObject);
     }
 }
示例#3
0
        private void RequestIdentify(BubbleLink bubbleLink, CloudObject cloudObject)
        {
            Session         session         = bubble.GetBubbleLinkSession(bubbleLink);
            Guid            participantId   = cloudObject.OwnerId;
            ParticipantLink participantLink = bubble.GetParticipant(cloudObject.OwnerId);

            // Delegate to access participant identity
            string participantIdentity = CloudParticipantIdentify(participantId);

            IdentifyRequestMessage identifyRequest = (IdentifyRequestMessage)MessageFactory.Current.ReserveMessage(typeof(IdentifyRequestMessage));

            identifyRequest.ParticipantId           = participantId;
            identifyRequest.ParticipantIdentityType = IdentifyRequestMessage.OPEN_ID_IDENTITY;
            identifyRequest.ParticipantIdentity     = participantIdentity;

            Handover handover = new Handover();

            handover.Started                  = DateTime.Now;
            handover.RemoteBubbleId           = bubbleLink.RemoteBubbleId;
            handover.ParticipantId            = cloudObject.OwnerId;
            handover.ObjectId                 = cloudObject.ObjectId;
            handover.IdentityRequestMessageId = identifyRequest.MessageId;
            handovers.Add(handover);

            LogUtil.Info("Sent identify request from " + bubble.BubbleName + " to " + bubbleLink.RemoteBubbleName + " for " + identifyRequest.ParticipantIdentity + " (" + identifyRequest.ParticipantIdentityType + ") to be able to handover object " + cloudObject.ObjectId + ".");

            session.Send(identifyRequest);
        }
示例#4
0
        private void HandleHandoverRequest(Session session, HandoverRequestMessage handoverRequest)
        {
            BubbleLink bubbleLink = bubble.GetBubbleLink(session);

            LogUtil.Info("Received handover request from " + bubbleLink.RemoteBubbleName + " to " + bubble.BubbleName + " for object " + handoverRequest.ObjectFragment.ObjectId + ").");

            HandoverResponseMessage handoverResponse = (HandoverResponseMessage)MessageFactory.Current.ReserveMessage(typeof(HandoverResponseMessage));

            handoverResponse.RequestMessageId = handoverRequest.MessageId;

            // Calling delegate to allow application to reject the handover.
            handoverResponse.FailureCode = CloudObjectHandover(bubble, handoverRequest);

            if (handoverResponse.FailureCode == MxpResponseCodes.SUCCESS)
            {
                CloudObject cloudObject = bubble.CloudCache.GetObject(handoverRequest.ObjectFragment.ObjectId);

                if (cloudObject == null)
                {
                    // Remote object does not exist in cache so creating new one.
                    cloudObject = new CloudObject();
                }
                else
                {
                    // Object should be located in bubble requesting handover
                    if (cloudObject.BubbleId != handoverRequest.SourceBubbleId)
                    {
                        handoverResponse.FailureCode = MxpResponseCodes.UNAUTHORIZED_OPERATION;
                        session.Send(handoverResponse);
                        return;
                    }

                    // Object should be owned by same participant if not then this is id collision.
                    if (cloudObject.OwnerId != handoverRequest.ObjectFragment.OwnerId)
                    {
                        handoverResponse.FailureCode = MxpResponseCodes.RESERVED_ID;
                        session.Send(handoverResponse);
                        return;
                    }
                }

                cloudObject.FromObjectFragment(bubble.BubbleId, handoverRequest.ObjectFragment);
                // Setting remove object index to 0 as it is local object now and cache will then set it equal to local index
                cloudObject.RemoteObjectIndex = 0;
                bubble.CloudCache.PutObject(cloudObject, true);
            }

            session.Send(handoverResponse);

            // send event
        }
示例#5
0
        private void OnCloudParticipantDisconnected(CloudBubble bubble, Guid participantId)
        {
            HashSet <Guid> participantObjectIds       = bubble.CloudCache.GetParticipantObjectIds(participantId);
            List <Guid>    participantObjectsToRemove = participantObjectIds.ToList <Guid>();

            foreach (Guid objectId in participantObjectsToRemove)
            {
                MXP.Cloud.CloudObject cloudObject = bubble.CloudCache.GetObject(objectId);
                // Remove if local bubble is primary bubble.
                if (bubble.BubbleId == cloudObject.BubbleId)
                {
                    bubble.CloudCache.RemoveObject(objectId);
                }
            }
        }
示例#6
0
        public void EvaluateHandoverNeed(CloudObject cloudObject)
        {
            if (cloudObject.BubbleId != bubble.BubbleId)
            {
                throw new Exception("Remote objects can not need to be handed over.");
            }

            MsdVector3f origo = new MsdVector3f();

            // Evaluating if object center is inside bubble range
            float distanceFromCenter = MathUtil.Distance(cloudObject.Location, origo);

            if (distanceFromCenter < bubble.BubbleRange)
            {
                return;
            }

            foreach (Handover handover in handovers)
            {
                if (handover.ObjectId == cloudObject.ObjectId)
                {
                    // Object is already in handover process.
                    return;
                }
            }

            // Object is not inside bubble radius
            // Evaluate if there is another linked bubble where object center would be inside bubble range
            float      shortestDistance  = float.MaxValue;
            BubbleLink closestBubbleLink = null;

            foreach (BubbleLink bubbleLink in bubble.GetBubbleLinks().Values)
            {
                float distanceFromRemoteCenter = MathUtil.Distance(cloudObject.Location, bubbleLink.RemoteBubbleCenter);
                if (distanceFromRemoteCenter < bubble.BubbleRange && distanceFromCenter < shortestDistance)
                {
                    shortestDistance  = distanceFromRemoteCenter;
                    closestBubbleLink = bubbleLink;
                }
            }

            if (closestBubbleLink != null)
            {
                RequestIdentify(closestBubbleLink, cloudObject);
            }
        }
示例#7
0
        private void HandleIdentifyResponse(Session session, IdentifyResponseMessage identifyResponse)
        {
            foreach (Handover handover in handovers)
            {
                if (identifyResponse.RequestMessageId == handover.IdentityRequestMessageId)
                {
                    CloudObject cloudObject = bubble.CloudCache.GetObject(handover.ObjectId);
                    if (cloudObject == null)
                    {
                        return;
                    }
                    if (cloudObject.BubbleId != bubble.BubbleId)
                    {
                        throw new Exception("Remote objects can not need to be handed over.");
                    }
                    ParticipantLink participantLink = bubble.GetParticipant(cloudObject.OwnerId);
                    BubbleLink      bubbleLink      = bubble.GetBubbleLink(handover.RemoteBubbleId);

                    LogUtil.Info("Received identify response (" + identifyResponse.FailureCode + ") from " + bubble.BubbleName + " to " + bubbleLink.RemoteBubbleName + " to be able to handover object " + handover.ObjectId + ".");

                    if (identifyResponse.FailureCode != MxpResponseCodes.SUCCESS)
                    {
                        return;
                    }

                    HandoverRequestMessage handoverRequest = (HandoverRequestMessage)MessageFactory.Current.ReserveMessage(typeof(HandoverRequestMessage));
                    handoverRequest.SourceBubbleId = bubble.BubbleId;
                    handoverRequest.TargetBubbleId = handover.RemoteBubbleId;
                    cloudObject.ToObjectFragment(handoverRequest.ObjectFragment);
                    handoverRequest.ObjectFragment.Location.X = cloudObject.Location.X - bubbleLink.RemoteBubbleCenter.X;
                    handoverRequest.ObjectFragment.Location.Y = cloudObject.Location.Y - bubbleLink.RemoteBubbleCenter.Y;
                    handoverRequest.ObjectFragment.Location.Z = cloudObject.Location.Z - bubbleLink.RemoteBubbleCenter.Z;
                    handover.HandoverRequestMessageId         = handoverRequest.MessageId;
                    session.Send(handoverRequest);

                    // Storing cloud object in case of rollback
                    handover.CloudObject = cloudObject;
                    // Removing cloud object from bubble.
                    bubble.CloudCache.RemoveObject(cloudObject.ObjectId);

                    return;
                }
            }
        }
示例#8
0
 public void Process()
 {
     // Crawling cache to remove timed out remote objects.
     for (int i = 0; i < cacheObjectsToCrawlPerCycle && objectList.Count > 0; i++)
     {
         lastCrawledObjectListIndex++;
         if (lastCrawledObjectListIndex >= objectList.Count)
         {
             lastCrawledObjectListIndex = 0;
         }
         CloudObject cloudObject = objects[objectList[lastCrawledObjectListIndex]];
         if (cloudObject.LastUpdated.Add(cacheObjectLifeSpan) < DateTime.Now &&
             cloudObject.BubbleId != localBubbleId &&
             localBubbleId != Guid.Empty)
         {
             LogUtil.Debug("Carbage collecting object: " + cloudObject.ObjectId + " frm bubble " + localBubbleId);
             RemoveObject(cloudObject.ObjectId);
         }
     }
 }
示例#9
0
 public void OnServerMessageReceived(Message message)
 {
     if (message.GetType() == typeof(PerceptionEventMessage))
     {
         PerceptionEventMessage perception  = (PerceptionEventMessage)message;
         CloudObject            cloudObject = cloudCache.GetObject(perception.ObjectFragment.ObjectId);
         if (cloudObject == null)
         {
             cloudObject = new CloudObject();
         }
         cloudObject.FromObjectFragment(client.BubbleId, perception.ObjectFragment);
         cloudCache.PutObject(cloudObject, true);
     }
     if (message.GetType() == typeof(MovementEventMessage))
     {
         MovementEventMessage movement    = (MovementEventMessage)message;
         CloudObject          cloudObject = cloudCache.GetObject(client.BubbleId, movement.ObjectIndex);
         if (cloudObject != null)
         {
             cloudObject.Location.X    = movement.Location.X;
             cloudObject.Location.Y    = movement.Location.Y;
             cloudObject.Location.Z    = movement.Location.Z;
             cloudObject.Orientation.X = movement.Orientation.X;
             cloudObject.Orientation.Y = movement.Orientation.Y;
             cloudObject.Orientation.Z = movement.Orientation.Z;
             cloudObject.Orientation.W = movement.Orientation.W;
             cloudCache.PutObject(cloudObject, true);
         }
     }
     if (message.GetType() == typeof(DisappearanceEventMessage))
     {
         DisappearanceEventMessage disappearance = (DisappearanceEventMessage)message;
         CloudObject cloudObject = cloudCache.GetObject(client.BubbleId, disappearance.ObjectIndex);
         if (cloudObject != null)
         {
             cloudCache.RemoveObject(cloudObject.ObjectId);
         }
     }
     if (message.GetType() == typeof(ActionEventMessage))
     {
         ServerAction((ActionEventMessage)message);
     }
     if (message.GetType() == typeof(SynchronizationBeginEventMessage))
     {
         ServerSynchronizationBegin((SynchronizationBeginEventMessage)message);
     }
     if (message.GetType() == typeof(SynchronizationEndEventMessage))
     {
         ServerSynchronizationEnd((SynchronizationEndEventMessage)message);
     }
     if (message.GetType() == typeof(ListBubblesResponse))
     {
         LinkedBubbleListReceived((ListBubblesResponse)message);
     }
     if (message.GetType() == typeof(HandoverEventMessage))
     {
         ServerObjectHandover((HandoverEventMessage)message);
     }
     if (message.GetType() == typeof(InteractRequestMessage))
     {
         ServerInteractRequest((InteractRequestMessage)message);
     }
     if (message.GetType() == typeof(InteractResponseMessage))
     {
         ServerInteractResponse((InteractResponseMessage)message);
     }
 }
示例#10
0
        public void PutObject(CloudObject cloudObject, bool publicUpdate)
        {
            if (!objects.ContainsKey(cloudObject.ObjectId))
            {
                // Assigning local cache index to the object. This will be used when object is sent to clients.
                cloudObject.LastUpdated = DateTime.Now;
                localObjectIndexCounter++;
                cloudObject.LocalObjectIndex = localObjectIndexCounter;
                if (cloudObject.RemoteObjectIndex == 0)
                {
                    // For participant lets set remote object index.
                    cloudObject.RemoteObjectIndex = localObjectIndexCounter;
                }

                objects.Add(cloudObject.ObjectId, cloudObject);
                objectList.Add(cloudObject.ObjectId);
                if (!bubbleObjects.ContainsKey(cloudObject.BubbleId))
                {
                    bubbleObjects.Add(cloudObject.BubbleId, new Dictionary <Guid, Guid>());
                    bubbleObjectGuidIndexDictionary.Add(cloudObject.BubbleId, new Dictionary <Guid, uint>());
                    bubbleObjectIndexGuidDictionary.Add(cloudObject.BubbleId, new Dictionary <uint, Guid>());
                }
                bubbleObjects[cloudObject.BubbleId].Add(cloudObject.ObjectId, cloudObject.ObjectId);
                bubbleObjectGuidIndexDictionary[cloudObject.BubbleId].Add(cloudObject.ObjectId, cloudObject.RemoteObjectIndex);
                bubbleObjectIndexGuidDictionary[cloudObject.BubbleId].Add(cloudObject.RemoteObjectIndex, cloudObject.ObjectId);

                objectBubbleDictionary.Add(cloudObject.ObjectId, cloudObject.BubbleId);
                objectKDTree.Put(cloudObject.Location.X - cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.Y - cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.Z - cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.X + cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.Y + cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.Z + cloudObject.BoundingSphereRadius,
                                 cloudObject.ObjectId
                                 );

                if (!participantObjects.ContainsKey(cloudObject.OwnerId))
                {
                    participantObjects.Add(cloudObject.OwnerId, new HashSet <Guid>());
                }
                participantObjects[cloudObject.OwnerId].Add(cloudObject.ObjectId);
                objectParticipantDictionary.Add(cloudObject.ObjectId, cloudObject.OwnerId);
            }
            else
            {
                if (cloudObject.RemoteObjectIndex == 0)
                {
                    // For participant lets set remote object index.
                    cloudObject.RemoteObjectIndex = cloudObject.LocalObjectIndex;
                }

                if (publicUpdate)
                {
                    cloudObject.LastUpdated = DateTime.Now;
                }

                if (objects[cloudObject.ObjectId] != cloudObject)
                {
                    throw new Exception("Cache must be updated with same cache object.");
                }

                // Updating changed bubble id.
                if (objectBubbleDictionary[cloudObject.ObjectId] != cloudObject.BubbleId)
                {
                    Guid oldBubbleId = objectBubbleDictionary[cloudObject.ObjectId];
                    bubbleObjects[oldBubbleId].Remove(cloudObject.ObjectId);
                    uint oldIndex = bubbleObjectGuidIndexDictionary[oldBubbleId][cloudObject.ObjectId];
                    bubbleObjectGuidIndexDictionary[oldBubbleId].Remove(cloudObject.ObjectId);
                    bubbleObjectIndexGuidDictionary[oldBubbleId].Remove(oldIndex);
                    if (bubbleObjects[objectBubbleDictionary[cloudObject.ObjectId]].Count == 0)
                    {
                        bubbleObjects.Remove(oldBubbleId);
                        bubbleObjectGuidIndexDictionary.Remove(oldBubbleId);
                        bubbleObjectIndexGuidDictionary.Remove(oldBubbleId);
                    }

                    if (!bubbleObjects.ContainsKey(cloudObject.BubbleId))
                    {
                        bubbleObjects.Add(cloudObject.BubbleId, new Dictionary <Guid, Guid>());
                        bubbleObjectGuidIndexDictionary.Add(cloudObject.BubbleId, new Dictionary <Guid, uint>());
                        bubbleObjectIndexGuidDictionary.Add(cloudObject.BubbleId, new Dictionary <uint, Guid>());
                    }
                    bubbleObjects[cloudObject.BubbleId].Add(cloudObject.ObjectId, cloudObject.ObjectId);
                    bubbleObjectGuidIndexDictionary[cloudObject.BubbleId].Add(cloudObject.ObjectId, cloudObject.RemoteObjectIndex);
                    bubbleObjectIndexGuidDictionary[cloudObject.BubbleId].Add(cloudObject.RemoteObjectIndex, cloudObject.ObjectId);
                    objectBubbleDictionary[cloudObject.ObjectId] = cloudObject.BubbleId;
                }

                // Updating changed object index.
                if (bubbleObjectGuidIndexDictionary[cloudObject.BubbleId][cloudObject.ObjectId] != cloudObject.RemoteObjectIndex)
                {
                    uint oldRemoteIndex = bubbleObjectGuidIndexDictionary[cloudObject.BubbleId][cloudObject.ObjectId];
                    bubbleObjectIndexGuidDictionary[cloudObject.BubbleId].Remove(oldRemoteIndex);
                    bubbleObjectGuidIndexDictionary[cloudObject.BubbleId][cloudObject.ObjectId] = cloudObject.RemoteObjectIndex;
                    bubbleObjectIndexGuidDictionary[cloudObject.BubbleId].Add(cloudObject.RemoteObjectIndex, cloudObject.ObjectId);
                }

                objectKDTree.Put(cloudObject.Location.X - cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.Y - cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.Z - cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.X + cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.Y + cloudObject.BoundingSphereRadius,
                                 cloudObject.Location.Z + cloudObject.BoundingSphereRadius,
                                 cloudObject.ObjectId
                                 );

                // Updating changed object participantId
                if (cloudObject.OwnerId != objectParticipantDictionary[cloudObject.ObjectId])
                {
                    participantObjects[objectParticipantDictionary[cloudObject.ObjectId]].Remove(cloudObject.ObjectId);
                    if (participantObjects[objectParticipantDictionary[cloudObject.ObjectId]].Count == 0)
                    {
                        participantObjects.Remove(objectParticipantDictionary[cloudObject.ObjectId]);
                    }
                    if (!participantObjects.ContainsKey(cloudObject.OwnerId))
                    {
                        participantObjects.Add(cloudObject.OwnerId, new HashSet <Guid>());
                    }
                    participantObjects[cloudObject.OwnerId].Add(cloudObject.ObjectId);
                    objectParticipantDictionary[cloudObject.ObjectId] = cloudObject.OwnerId;
                }
            }
            if (publicUpdate)
            {
                CacheObjectPut(cloudObject);
            }
        }