예제 #1
0
        /// <summary>
        /// This method is called by the LLUDPServer and should never be called by anyone else
        /// It loops through the available updates and sends them out (no waiting)
        /// </summary>
        /// <param name="numUpdates">The number of updates to send</param>
        public void SendPrimUpdates (int numPrimUpdates, int numAvaUpdates)
        {
            if (m_inUse || ((ScenePresence)m_presence).IsInTransit)
                return;

            if (m_numberOfLoops < NUMBER_OF_LOOPS_TO_WAIT) //Wait for the client to finish connecting fully before sending out bunches of updates
            {
                m_numberOfLoops++;
                return;
            }

            m_inUse = true;
            //This is for stats
            int AgentMS = Util.EnvironmentTickCount ();

            #region New client entering the Scene, requires all objects in the Scene

            ///If we havn't started processing this client yet, we need to send them ALL the prims that we have in this Scene (and deal with culling as well...)
            if (!m_SentInitialObjects && m_presence.DrawDistance != 0.0f)
            {
                //If they are not in this region, we check to make sure that we allow seeing into neighbors
                if (!m_presence.IsChildAgent || (m_presence.Scene.RegionInfo.SeeIntoThisSimFromNeighbor) && m_prioritizer != null)
                {
                    m_SentInitialObjects = true;
                    ISceneEntity[] entities = m_presence.Scene.Entities.GetEntities ();
                    PriorityQueue<EntityUpdate, double> m_entsqueue = new PriorityQueue<EntityUpdate, double> (entities.Length, DoubleComparer);
                    List<ISceneEntity> NewGrpsInView = new List<ISceneEntity> ();
                    // build a prioritized list of things we need to send

                    foreach (ISceneEntity e in entities)
                    {
                        if (e != null && e is SceneObjectGroup)
                        {
                            if (e.IsDeleted)
                                continue;

                            if (lastGrpsInView.Contains (e))
                                continue;

                            //Check for culling here!
                            if (Culler != null)
                            {
                                if (!Culler.ShowEntityToClient (m_presence, e))
                                    continue;
                                NewGrpsInView.Add (e);
                            }

                            //Send the root object first!
                            EntityUpdate rootupdate = new EntityUpdate (e.RootChild, PrimUpdateFlags.FullUpdate);
                            PriorityQueueItem<EntityUpdate, double> rootitem = new PriorityQueueItem<EntityUpdate, double> ();
                            rootitem.Value = rootupdate;
                            rootitem.Priority = m_prioritizer.GetUpdatePriority (m_presence, e.RootChild);
                            m_entsqueue.Enqueue (rootitem);

                            foreach (ISceneChildEntity child in e.ChildrenEntities ())
                            {
                                if (child == e.RootChild)
                                    continue; //Already sent
                                EntityUpdate update = new EntityUpdate (child, PrimUpdateFlags.ForcedFullUpdate);
                                PriorityQueueItem<EntityUpdate, double> item = new PriorityQueueItem<EntityUpdate, double> ();
                                item.Value = update;
                                item.Priority = m_prioritizer.GetUpdatePriority (m_presence, child);
                                m_entsqueue.Enqueue (item);
                            }
                        }
                    }
                    //Merge the last seen lists
                    lastGrpsInView.UnionWith (NewGrpsInView);
                    NewGrpsInView.Clear ();
                    entities = null;
                    // send them 
                    SendQueued (m_entsqueue);
                }
            }

            int presenceNumToSend = numAvaUpdates;
            lock (m_presenceUpdatesToSend)
            {
                //Send the numUpdates of them if that many
                // if we don't have that many, we send as many as possible, then switch to objects
                if (m_presenceUpdatesToSend.Count != 0)
                {
                    try
                    {
                        int count = m_presenceUpdatesToSend.Count > presenceNumToSend ? presenceNumToSend : m_presenceUpdatesToSend.Count;
                        List<EntityUpdate> updates = new List<EntityUpdate> ();
                        for (int i = 0; i < count; i++)
                        {
                            EntityUpdate update = ((EntityUpdate)m_presenceUpdatesToSend[0]);
                            if (m_EntitiesInPacketQueue.Contains (update.Entity.UUID))
                            {
                                m_presenceUpdatesToSend.RemoveAt (0);
                                m_presenceUpdatesToSend.Insert (m_presenceUpdatesToSend.Count, update.Entity.UUID, update);
                                continue;
                            }
                            updates.Add (update);
                            m_EntitiesInPacketQueue.Add (update.Entity.UUID);
                            m_presenceUpdatesToSend.RemoveAt (0);
                        }
                        if (updates.Count != 0)
                        {
                            presenceNumToSend -= updates.Count;
                            //Make sure we don't have an update for us
                            if (updates[0].Entity.UUID == m_presence.UUID)
                                m_ourPresenceHasUpdate = false;
                            m_presence.ControllingClient.SendAvatarUpdate (updates);
                        }
                    }
                    catch (Exception ex)
                    {
                        m_log.WarnFormat ("[SceneViewer]: Exception while running presence loop: {0}", ex.ToString ());
                    }
                }
            }

            lock (m_presenceAnimationsToSend)
            {
                //Send the numUpdates of them if that many
                // if we don't have that many, we send as many as possible, then switch to objects
                if (m_presenceAnimationsToSend.Count != 0 && presenceNumToSend > 0)
                {
                    try
                    {
                        int count = m_presenceAnimationsToSend.Count > presenceNumToSend ? presenceNumToSend : m_presenceAnimationsToSend.Count;
                        for (int i = 0; i < count; i++)
                        {
                            AnimationGroup update = ((AnimationGroup)m_presenceAnimationsToSend[0]);
                            if (m_AnimationsInPacketQueue.Contains (update.AvatarID))
                            {
                                m_presenceAnimationsToSend.RemoveAt (0);
                                m_presenceAnimationsToSend.Insert (m_presenceAnimationsToSend.Count, update.AvatarID, update);
                                continue;
                            }
                            m_AnimationsInPacketQueue.Add (update.AvatarID);
                            m_presenceAnimationsToSend.RemoveAt (0);
                            m_presence.ControllingClient.SendAnimations (update);
                        }
                    }
                    catch (Exception ex)
                    {
                        m_log.WarnFormat ("[SceneViewer]: Exception while running presence loop: {0}", ex.ToString ());
                    }
                }
            }

            int primsNumToSend = numPrimUpdates;

            lock (m_objectPropertiesToSend)
            {
                //Send the numUpdates of them if that many
                // if we don't have that many, we send as many as possible, then switch to objects
                if (m_objectPropertiesToSend.Count != 0)
                {
                    try
                    {
                        List<IEntity> entities = new List<IEntity> ();
                        int count = m_objectPropertiesToSend.Count > primsNumToSend ? primsNumToSend : m_objectPropertiesToSend.Count;
                        for (int i = 0; i < count; i++)
                        {
                            ISceneChildEntity entity = ((ISceneChildEntity)m_objectPropertiesToSend[0]);
                            if (m_PropertiesInPacketQueue.Contains (entity.UUID))
                            {
                                m_objectPropertiesToSend.RemoveAt (0);
                                m_objectPropertiesToSend.Insert (m_objectPropertiesToSend.Count, entity.UUID, entity);
                                continue;
                            }
                            m_PropertiesInPacketQueue.Add (entity.UUID);
                            m_objectPropertiesToSend.RemoveAt (0);
                            entities.Add (entity);
                        }
                        if (entities.Count > 0)
                        {
                            primsNumToSend -= entities.Count;
                            m_presence.ControllingClient.SendObjectPropertiesReply (entities);
                        }
                    }
                    catch (Exception ex)
                    {
                        m_log.WarnFormat ("[SceneViewer]: Exception while running presence loop: {0}", ex.ToString ());
                    }
                }
            }

            lock (m_objectUpdatesToSend)
            {
                if (m_objectUpdatesToSend.Count != 0)
                {
                    try
                    {
                        int count = m_objectUpdatesToSend.Count > primsNumToSend ? primsNumToSend : m_objectUpdatesToSend.Count;
                        List<EntityUpdate> updates = new List<EntityUpdate> ();
                        for (int i = 0; i < count; i++)
                        {
                            EntityUpdate update = ((EntityUpdate)m_objectUpdatesToSend[0]);
                            if (m_EntitiesInPacketQueue.Contains (update.Entity.UUID))
                            {
                                m_objectUpdatesToSend.RemoveAt (0);
                                m_objectUpdatesToSend.Insert (m_objectUpdatesToSend.Count, update.Entity.UUID, update);
                                continue;
                            }
                            updates.Add (update);
                            m_EntitiesInPacketQueue.Add (update.Entity.UUID);
                            m_objectUpdatesToSend.RemoveAt (0);
                        }
                        m_presence.ControllingClient.SendPrimUpdate (updates);
                    }
                    catch (Exception ex)
                    {
                        m_log.WarnFormat ("[SceneViewer]: Exception while running object loop: {0}", ex.ToString ());
                    }
                }
            }

            //Add the time to the stats tracker
            IAgentUpdateMonitor reporter = (IAgentUpdateMonitor)m_presence.Scene.RequestModuleInterface<IMonitorModule> ().GetMonitor (m_presence.Scene.RegionInfo.RegionID.ToString (), "Agent Update Count");
            if (reporter != null)
                reporter.AddAgentTime (Util.EnvironmentTickCountSubtract (AgentMS));

            m_inUse = false;
        }
예제 #2
0
 private void QueueEntityUpdate(EntityUpdate update)
 {
     lock (m_objectUpdatesToSend)
     {
         EntityUpdate o = (EntityUpdate)m_objectUpdatesToSend[update.Entity.UUID];
         if (o == null)
             o = update;
         else
         {
             if (o.Flags == update.Flags)
                 return; //Same, leave it alone!
             o.Flags = o.Flags | update.Flags;
             m_objectUpdatesToSend.Remove(update.Entity.UUID);
         }
         m_objectUpdatesToSend.Insert(m_objectUpdatesToSend.Count, o.Entity.UUID, o);
     }
 }
예제 #3
0
        private void DoSignificantClientMovement (object o)
        {
            ISceneEntity[] entities = m_presence.Scene.Entities.GetEntities (m_presence.AbsolutePosition, m_presence.DrawDistance * 3);
            PriorityQueue<EntityUpdate, double> m_entsqueue = new PriorityQueue<EntityUpdate, double> (entities.Length, DoubleComparer);

            // build a prioritized list of things we need to send

            HashSet<ISceneEntity> NewGrpsInView = new HashSet<ISceneEntity> ();

            foreach (ISceneEntity e in entities)
            {
                if (e != null)
                {
                    if (e.IsDeleted)
                        continue;

                    if (lastGrpsInView.Contains (e)) //If we've already sent it, don't send it again
                        continue;

                    if (Culler != null)
                    {
                        if (!Culler.ShowEntityToClient (m_presence, e))
                            continue;
                        NewGrpsInView.Add (e);
                    }

                    //Send the root object first!
                    EntityUpdate rootupdate = new EntityUpdate (e.RootChild, PrimUpdateFlags.ForcedFullUpdate);
                    PriorityQueueItem<EntityUpdate, double> rootitem = new PriorityQueueItem<EntityUpdate, double> ();
                    rootitem.Value = rootupdate;
                    rootitem.Priority = m_prioritizer.GetUpdatePriority (m_presence, e.RootChild);
                    m_entsqueue.Enqueue (rootitem);

                    foreach (ISceneChildEntity child in e.ChildrenEntities ())
                    {
                        if (child == e.RootChild)
                            continue; //Already sent
                        EntityUpdate update = new EntityUpdate (child, PrimUpdateFlags.FullUpdate);
                        PriorityQueueItem<EntityUpdate, double> item = new PriorityQueueItem<EntityUpdate, double> ();
                        item.Value = update;
                        item.Priority = m_prioritizer.GetUpdatePriority (m_presence, child);
                        m_entsqueue.Enqueue (item);
                    }
                }
            }
            entities = null;
            lastGrpsInView.UnionWith (NewGrpsInView);
            NewGrpsInView.Clear ();

            // send them 
            SendQueued (m_entsqueue);

            HashSet<IScenePresence> NewPresencesInView = new HashSet<IScenePresence>();

            //Check for scenepresences as well
            IScenePresence[] presences = m_presence.Scene.Entities.GetPresences(m_presence.AbsolutePosition, m_presence.DrawDistance);
            foreach (IScenePresence presence in presences)
            {
                if (presence != null && presence.UUID != m_presence.UUID)
                {
                    //Check for culling here!
                    if (!Culler.ShowEntityToClient(m_presence, presence))
                        continue; // if 2 far ignore

                    NewPresencesInView.Add (presence);

                    if (lastPresencesInView.Contains (presence))
                        continue; //Don't resend the update

                    SendFullUpdateForPresence (presence);
                }
            }
            presences = null;
            lastPresencesInView.UnionWith(NewPresencesInView);
            NewPresencesInView.Clear();
        }
예제 #4
0
        public void QueuePresenceForUpdate (IScenePresence presence, PrimUpdateFlags flags)
        {
            if (Culler != null && !Culler.ShowEntityToClient (m_presence, presence))
            {
                //They are out of view and they changed, we need to update them when they do come in view
                lastPresencesInView.Remove (presence);
                return; // if 2 far ignore
            }
            if ((!(m_presence.DrawDistance > m_presence.Scene.RegionInfo.RegionSizeX &&
                    m_presence.DrawDistance > m_presence.Scene.RegionInfo.RegionSizeY)) && 
                    !lastPresencesInView.Contains (presence))
            {
                //The presence just entered our view, we need to send a full update
                SendFullUpdateForPresence (presence);
                lastPresencesInView.Add (presence);
                return;
            }

            lock (m_presenceUpdatesToSend)
            {
                EntityUpdate o = (EntityUpdate)m_presenceUpdatesToSend[presence.UUID];
                if (o == null)
                    o = new EntityUpdate(presence, flags);
                else
                {
                    if ((o.Flags & flags) == o.Flags)
                        return; //Same, leave it alone!
                    o.Flags = o.Flags | flags;
                    m_presenceUpdatesToSend.Remove(presence.UUID);
                }

                if (m_presence.UUID == presence.UUID)
                {
                    //Its us, set us first!
                    m_ourPresenceHasUpdate = true;
                    m_presenceUpdatesToSend.Insert(0, presence.UUID, o);
                }
                else if (m_ourPresenceHasUpdate) //If this is set, we start inserting at 1 so that our updates go first
                    // We can also safely assume that 1 is fine, because there has to be 0 already there set by us
                    m_presenceUpdatesToSend.Insert(m_presenceUpdatesToSend.Count, presence.UUID, o);
                else //Set us at 0, no updates from us
                    m_presenceUpdatesToSend.Insert(m_presenceUpdatesToSend.Count, presence.UUID, o);
            }
        }
예제 #5
0
        /// <summary>
        /// Add the objects to the queue for which we need to send an update to the client
        /// </summary>
        /// <param name="part"></param>
        public void QueuePartForUpdate (ISceneChildEntity part, PrimUpdateFlags flags)
        {
            if (Culler != null && !Culler.ShowEntityToClient (m_presence, part.ParentEntity))
            {
                //They are out of view and they changed, we need to update them when they do come in view
                lastGrpsInView.Remove (part.ParentEntity);
                return; // if 2 far ignore
            }
            if ((!(m_presence.DrawDistance > m_presence.Scene.RegionInfo.RegionSizeX &&
                    m_presence.DrawDistance > m_presence.Scene.RegionInfo.RegionSizeY)) && !lastGrpsInView.Contains (part.ParentEntity))
            {
                //This object entered our draw distance on its own, and we havn't seen it before
                flags = PrimUpdateFlags.ForcedFullUpdate;
            }

            EntityUpdate o = new EntityUpdate (part, flags);
            QueueEntityUpdate (o);
        }
예제 #6
0
        private void DoSignificantClientMovement (object o)
        {
            ISceneEntity[] entities = m_presence.Scene.Entities.GetEntities (m_presence.AbsolutePosition, m_presence.DrawDistance);
            PriorityQueue<EntityUpdate, double> m_entsqueue = new PriorityQueue<EntityUpdate, double> (entities.Length);

            // build a prioritized list of things we need to send

            HashSet<ISceneEntity> NewGrpsInView = new HashSet<ISceneEntity> ();

            foreach (ISceneEntity e in entities)
            {
                if (e != null)
                {
                    if (e.IsDeleted)
                        continue;

                    //Check for culling here!
                    if (!Culler.ShowEntityToClient(m_presence, e))
                        continue; // if 2 far ignore

                    double priority = m_prioritizer.GetUpdatePriority (m_presence, e);
                    NewGrpsInView.Add (e);

                    if (lastGrpsInView.Contains (e))
                        continue;

                    //Send the root object first!
                    EntityUpdate rootupdate = new EntityUpdate (e.RootChild, PrimUpdateFlags.FullUpdate);
                    PriorityQueueItem<EntityUpdate, double> rootitem = new PriorityQueueItem<EntityUpdate, double> ();
                    rootitem.Value = rootupdate;
                    rootitem.Priority = priority;
                    m_entsqueue.Enqueue (rootitem);

                    foreach (ISceneChildEntity child in e.ChildrenEntities ())
                    {
                        if (child == e.RootChild)
                            continue; //Already sent
                        EntityUpdate update = new EntityUpdate (child, PrimUpdateFlags.FullUpdate);
                        PriorityQueueItem<EntityUpdate, double> item = new PriorityQueueItem<EntityUpdate, double> ();
                        item.Value = update;
                        item.Priority = priority;
                        m_entsqueue.Enqueue (item);
                    }
                }
            }
            entities = null;
            lastGrpsInView.Clear ();
            lastGrpsInView.UnionWith (NewGrpsInView);
            NewGrpsInView.Clear ();

            // send them 
            SendQueued (m_entsqueue);
        }
예제 #7
0
        /// <summary>
        /// This method is called by the LLUDPServer and should never be called by anyone else
        /// It loops through the available updates and sends them out (no waiting)
        /// </summary>
        /// <param name="numUpdates">The number of updates to send</param>
        public void SendPrimUpdates (int numUpdates)
        {
            if (m_inUse)
                return;
            m_inUse = true;
            //This is for stats
            int AgentMS = Util.EnvironmentTickCount ();

            #region New client entering the Scene, requires all objects in the Scene

            ///If we havn't started processing this client yet, we need to send them ALL the prims that we have in this Scene (and deal with culling as well...)
            if (!m_SentInitialObjects && m_presence.DrawDistance != 0.0f)
            {
                m_SentInitialObjects = true;
                //If they are not in this region, we check to make sure that we allow seeing into neighbors
                if (!m_presence.IsChildAgent || (m_presence.Scene.RegionInfo.SeeIntoThisSimFromNeighbor) && Culler != null && m_prioritizer != null)
                {
                    ISceneEntity[] entities = m_presence.Scene.Entities.GetEntities ();
                    PriorityQueue<EntityUpdate, double> m_entsqueue = new PriorityQueue<EntityUpdate, double> (entities.Length);

                    // build a prioritized list of things we need to send

                    foreach (ISceneEntity e in entities)
                    {
                        if (e != null && e is SceneObjectGroup)
                        {
                            if (e.IsDeleted)
                                continue;

                            //Check for culling here!
                            if (!Culler.ShowEntityToClient (m_presence, e))
                                continue;

                            double priority = m_prioritizer.GetUpdatePriority (m_presence, e);
                            //Send the root object first!
                            EntityUpdate rootupdate = new EntityUpdate (e.RootChild, PrimUpdateFlags.FullUpdate);
                            PriorityQueueItem<EntityUpdate, double> rootitem = new PriorityQueueItem<EntityUpdate, double> ();
                            rootitem.Value = rootupdate;
                            rootitem.Priority = priority;
                            m_entsqueue.Enqueue (rootitem);

                            foreach (ISceneChildEntity child in e.ChildrenEntities ())
                            {
                                if (child == e.RootChild)
                                    continue; //Already sent
                                EntityUpdate update = new EntityUpdate (child, PrimUpdateFlags.FullUpdate);
                                PriorityQueueItem<EntityUpdate, double> item = new PriorityQueueItem<EntityUpdate, double> ();
                                item.Value = update;
                                item.Priority = priority;
                                m_entsqueue.Enqueue (item);
                            }
                        }
                    }
                    entities = null;
                    // send them 
                    SendQueued (m_entsqueue);
                }
            }

            int numberSent = 0;
            int presenceNumToSend = (int)(numUpdates * PresenceSendPercentage);
            lock (m_presenceUpdatesToSend)
            {
                //Send the numUpdates of them if that many
                // if we don't have that many, we send as many as possible, then switch to objects
                if (m_presenceUpdatesToSend.Count != 0)
                {
                    int count = m_presenceUpdatesToSend.Count > presenceNumToSend ? presenceNumToSend : m_presenceUpdatesToSend.Count;
                    List<EntityUpdate> updates = new List<EntityUpdate> ();
                    for (int i = 0; i < count; i++)
                    {
                        updates.Add ((EntityUpdate)m_presenceUpdatesToSend[0]);
                        m_presenceUpdatesToSend.RemoveAt (0);
                    }
                    //If we're first, we definitely got set, so we don't need to check this at all
                    m_ourPresenceHasUpdate = false;
                    m_presence.ControllingClient.SendPrimUpdate (updates);
                }
            }

            lock (m_objectUpdatesToSend)
            {
                numberSent = presenceNumToSend - numberSent;
                int numToSend = (int)(numUpdates * PrimSendPercentage) + numberSent; //If we didn't send that many presence updates, send a few more
                if (m_objectUpdatesToSend.Count != 0)
                {
                    int count = m_objectUpdatesToSend.Count > numToSend ? numToSend : m_objectUpdatesToSend.Count;
                    List<EntityUpdate> updates = new List<EntityUpdate> ();
                    for (int i = 0; i < count; i++)
                    {
                        updates.Add ((EntityUpdate)m_objectUpdatesToSend[0]);
                        m_objectUpdatesToSend.RemoveAt (0);
                    }
                    m_presence.ControllingClient.SendPrimUpdate (updates);
                }
            }

            //Add the time to the stats tracker
            IAgentUpdateMonitor reporter = (IAgentUpdateMonitor)m_presence.Scene.RequestModuleInterface<IMonitorModule> ().GetMonitor (m_presence.Scene.RegionInfo.RegionID.ToString (), "Agent Update Count");
            if (reporter != null)
                reporter.AddAgentTime (Util.EnvironmentTickCountSubtract (AgentMS));

            m_inUse = false;
        }
예제 #8
0
        public void QueuePresenceForUpdate (IScenePresence presence, PrimUpdateFlags flags)
        {
            if (Culler == null || !Culler.ShowEntityToClient (m_presence, presence))
                return; // if 2 far ignore

            lock (m_presenceUpdatesToSend)
            {
                EntityUpdate o = (EntityUpdate)m_presenceUpdatesToSend[presence.UUID];
                if (o == null)
                    o = new EntityUpdate(presence, flags);
                else
                {
                    if ((o.Flags & flags) == o.Flags)
                        return; //Same, leave it alone!
                    o.Flags = o.Flags & flags;
                    m_presenceUpdatesToSend.Remove(presence.UUID);
                }

                if (m_presence.UUID == presence.UUID)
                {
                    //Its us, set us first!
                    m_ourPresenceHasUpdate = true;
                    m_presenceUpdatesToSend.Insert(0, presence.UUID, o);
                }
                else if (m_ourPresenceHasUpdate) //If this is set, we start inserting at 1 so that our updates go first
                    // We can also safely assume that 1 is fine, because there has to be 0 already there set by us
                    m_presenceUpdatesToSend.Insert(m_presenceUpdatesToSend.Count, presence.UUID, o);
                else //Set us at 0, no updates from us
                    m_presenceUpdatesToSend.Insert(m_presenceUpdatesToSend.Count, presence.UUID, o);
            }
        }
예제 #9
0
        /// <summary>
        /// Add the objects to the queue for which we need to send an update to the client
        /// </summary>
        /// <param name="part"></param>
        public void QueuePartForUpdate (ISceneChildEntity part, PrimUpdateFlags flags)
        {
            if (Culler == null || !Culler.ShowEntityToClient(m_presence, part.ParentEntity))
                return; // if 2 far ignore

            EntityUpdate o = new EntityUpdate (part, flags);
            QueueEntityUpdate (o);
        }
예제 #10
0
 private void QueueEntityUpdate(EntityUpdate update)
 {
     lock (m_objectUpdatesToSend)
     {
         EntityUpdate o = (EntityUpdate)m_objectUpdatesToSend[update.Entity.UUID];
         if (o == null)
         {
             m_objectUpdatesToSend.Insert (0, update.Entity.UUID, update);
         }
         else
         {
             o.Flags = o.Flags & update.Flags;
             m_objectUpdatesToSend[update.Entity.UUID] = o;
         }
     }
 }
예제 #11
0
        /// <summary>
        /// Add the objects to the queue for which we need to send an update to the client
        /// </summary>
        /// <param name="part"></param>
        public void QueuePartForUpdate(SceneObjectPart part, PrimUpdateFlags UpdateFlags)
        {
            double priority = m_prioritizer.GetUpdatePriority(m_presence.ControllingClient, part.ParentGroup);
            EntityUpdate update = new EntityUpdate(part, UpdateFlags);
            //Fix the version with the newest locked m_version
            FixVersion(update);
            PriorityQueueItem<EntityUpdate, double> item = new PriorityQueueItem<EntityUpdate, double>();
            item.Priority = priority;
            item.Value = update;
            m_partsUpdateQueue.Enqueue(item);

            //Make it check when the user comes around to it again
            if (m_objectsInView.Contains(part.UUID))
                m_objectsInView.Remove(part.UUID);
        }
예제 #12
0
 /// <summary>
 /// Sorts a list of Parts by Link Number so they end up in the correct order
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 public int linkSetSorter(EntityUpdate a, EntityUpdate b)
 {
     return a.Entity.LinkNum.CompareTo(b.Entity.LinkNum);
 }
예제 #13
0
 /// <summary>
 /// Updates the last version securely and set the update's version correctly
 /// </summary>
 /// <param name="update"></param>
 private void FixVersion(EntityUpdate update)
 {
     _versionAllocateMutex.WaitOne();
     m_lastVersion++;
     update.Version = m_lastVersion;
     _versionAllocateMutex.ReleaseMutex();
 }