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