示例#1
0
        private void SendQueued (PriorityQueue<EntityUpdate, double> m_entsqueue)
        {
            PriorityQueueItem<EntityUpdate, double> up;
            List<EntityUpdate> updates = new List<EntityUpdate> ();
            //Enqueue them all
            while (m_entsqueue.TryDequeue (out up))
            {
                updates.Add (up.Value);
            }
            //Priorities are backwards, gotta flip them around
            updates.Reverse ();
            foreach (EntityUpdate update in updates)
                QueueEntityUpdate (update);

            m_lastUpdatePos = (m_presence.IsChildAgent) ?
                m_presence.AbsolutePosition :
                m_presence.CameraPosition;
        }
示例#2
0
        private void SendQueued (PriorityQueue<EntityUpdate, double> m_entsqueue)
        {
            PriorityQueueItem<EntityUpdate, double> up;

            //Enqueue them all
            while (m_entsqueue.TryDequeue (out up))
            {
                QueueEntityUpdate (up.Value);
            }
            m_entsqueue.Clear ();

            m_lastUpdatePos = (m_presence.IsChildAgent) ?
                m_presence.AbsolutePosition :
                m_presence.CameraPosition;
        }
示例#3
0
        public static BooleanChain BestFirstSearch(BitSet items, long max, params BooleanChain[] chains)
        {
            PriorityQueue<double, BooleanChain> queue = new PriorityQueue<double, BooleanChain>(Comparer<double>.Default);
            foreach (BooleanChain item in chains)
            {
                if (item.MaxNeighborhoodSize <= max)
                {
                    queue.Enqueue(item.BooleanWidth * (item.Right * items).Count, item);
                }
            }

            BooleanChain chain;
            while (queue.TryDequeue(out chain))
            {
                BitSet bitSet = chain.Right * items;

                bool empty = true;
                foreach (int item in bitSet)
                {
                    empty = false;
                    BooleanChain next = new BooleanChain(chain, item);
                    if (next.MaxNeighborhoodSize <= max)
                    {
                        queue.Enqueue(next.BooleanWidth * (next.Right * items).Count, next);
                    }
                }

                if (empty)
                {
                    return chain;
                }
            }

            return null;
        }
示例#4
0
        /// <summary>
        /// This loops through all of the lists that we have for the client
        ///  as well as checking whether the client has ever entered the sim before
        ///  and sending the needed updates to them if they have just entered.
        /// </summary>
        public void SendPrimUpdates()
        {
            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_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))
                {
                    EntityBase[] entities = m_presence.Scene.Entities.GetEntities();
                    //Use the PriorityQueue so that we can send them in the correct order
                    PriorityQueue<EntityUpdate, double> entityUpdates = new PriorityQueue<EntityUpdate, double>(entities.Length);

                    foreach (EntityBase e in entities)
                    {
                        if (e != null && e is SceneObjectGroup)
                        {
                            SceneObjectGroup grp = (SceneObjectGroup)e;

                            //Check for culling here!
                            if (!CheckForCulling(grp))
                                continue;

                            //Get the correct priority and add to the queue
                            double priority = m_prioritizer.GetUpdatePriority(m_presence.ControllingClient, grp);
                            PriorityQueueItem<EntityUpdate, double> item = new PriorityQueueItem<EntityUpdate,double>(
                                new EntityUpdate(grp, PrimUpdateFlags.FullUpdate), priority);
                            entityUpdates.Enqueue(item); //New object, send full
                        }
                    }
                    entities = null;
                    //Send all the updates to the client
                    PriorityQueueItem<EntityUpdate, double> update;
                    while (entityUpdates.TryDequeue(out update))
                    {
                        SendUpdate(PrimUpdateFlags.FullUpdate, (SceneObjectGroup)update.Value.Entity);
                    }
                }
            }

            #endregion

            #region Update loop that sends objects that have been recently added to the queue

            //Pull the parts out into a list first so that we don't lock the queue for too long
            Dictionary<UUID, List<EntityUpdate>> m_parentUpdates = new Dictionary<UUID, List<EntityUpdate>>();
            lock (m_partsUpdateQueue)
            {
                lock (m_removeNextUpdateOf)
                {
                    PriorityQueueItem<EntityUpdate, double> update;
                    while (m_partsUpdateQueue.TryDequeue(out update))
                    {
                        if (update.Value == null)
                            continue;
                        //Make sure not to send deleted or null objects
                        if (((SceneObjectPart)update.Value.Entity).ParentGroup == null || ((SceneObjectPart)update.Value.Entity).ParentGroup.IsDeleted)
                            continue;

                        //Make sure we are not supposed to remove it
                        if (m_removeNextUpdateOf.ContainsKey(update.Value.Entity.LocalId))
                        {
                            if (update.Value.Version > m_removeNextUpdateOf[update.Value.Entity.LocalId])
                            {
                                //This update is newer, let it go on by
                            }
                            else //Not newer, should be removed Note: if this is the same version, its the update we were supposed to remove... so we do NOT do >= above
                                continue;
                        }

                        //Make sure we are not supposed to remove it
                        if (m_removeUpdateOf.Contains(update.Value.Entity.LocalId))
                            continue;

                        if (!m_parentUpdates.ContainsKey(((SceneObjectPart)update.Value.Entity).ParentGroup.UUID))
                            m_parentUpdates.Add(((SceneObjectPart)update.Value.Entity).ParentGroup.UUID, new List<EntityUpdate>());

                        m_parentUpdates[((SceneObjectPart)update.Value.Entity).ParentGroup.UUID].Add(update.Value);
                    }
                    m_removeNextUpdateOf.Clear();
                }
            }

            //Now loop through the list and send the updates
            foreach (UUID ParentID in m_parentUpdates.Keys)
            {
                //Sort by LinkID
                m_parentUpdates[ParentID].Sort(linkSetSorter);
                foreach (EntityUpdate update in m_parentUpdates[ParentID])
                {
                    SceneObjectPart part = ((SceneObjectPart)update.Entity);
                    //Check for culling here!
                    if (!CheckForCulling(part.ParentGroup))
                        continue;

                    // Attachment handling. Attachments are 'special' and we have to send the full group update when we send updates
                    if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0)
                    {
                        if (part != part.ParentGroup.RootPart)
                            continue;

                        //Check to make sure this attachment is not a hud. Attachments that are huds are 
                        //   ONLY sent to the owner, noone else!
                        if (
                            (
                            part.ParentGroup.RootPart.Shape.State == (byte)AttachmentPoint.HUDBottom ||
                            part.ParentGroup.RootPart.Shape.State == (byte)AttachmentPoint.HUDBottomLeft ||
                            part.ParentGroup.RootPart.Shape.State == (byte)AttachmentPoint.HUDBottomRight ||
                            part.ParentGroup.RootPart.Shape.State == (byte)AttachmentPoint.HUDCenter ||
                            part.ParentGroup.RootPart.Shape.State == (byte)AttachmentPoint.HUDCenter2 ||
                            part.ParentGroup.RootPart.Shape.State == (byte)AttachmentPoint.HUDTop ||
                            part.ParentGroup.RootPart.Shape.State == (byte)AttachmentPoint.HUDTopLeft ||
                            part.ParentGroup.RootPart.Shape.State == (byte)AttachmentPoint.HUDTopRight
                            )
                            && 
                            part.OwnerID != m_presence.UUID)
                            continue;

                        SendUpdate(update.Flags, part.ParentGroup);
                        continue;
                    }

                    SendUpdate(part,
                            m_presence.GenerateClientFlags(part), update.Flags);
                }
            }

            #endregion

            //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;
        }