示例#1
0
        /// <summary>
        ///     Dequeues this instance.
        /// </summary>
        /// <returns></returns>
        public TValue Dequeue()
        {
            bool   isValueAssigned = false;
            TValue value           = default(TValue);

            lock (_lock)
            {
                if (_count > 0)
                {
                    do
                    {
                        if (_currentIndexMarker.Previous == null)
                        {
                            _currentIndexMarker = _currentIndexMarker.LowerPriorityIndexMarker;
                        }
                        else
                        {
                            value           = _currentIndexMarker.Previous.Value;
                            isValueAssigned = true;
                            _currentIndexMarker.Previous = _currentIndexMarker.Previous.Previous;
                            if (_currentIndexMarker.Previous == null)
                            {
                                _currentIndexMarker.Last = null;
                            }
                        }
                    } while (_currentIndexMarker != null && !isValueAssigned);

                    //decrement the count
                    _count--;
                }
            }

            return(value);
        }
        /// <summary>
        /// Internal function for A* search.
        /// </summary>
        /// <param name="pq"></param>
        /// <param name="destNode"></param>
        /// <returns></returns>
        private static AStarSearchProgress AStarFindPath(ref PriorityQueue <double, AStarSearchProgress> pq, Node destNode)
        {
            PriorityQueueItem <double, AStarSearchProgress> pqItem = pq.Pop();

            if (pqItem != null)
            {
                double curWeight             = pqItem.Priority;
                AStarSearchProgress progress = pqItem.Item;
                Node curNode = progress.CurNode;

                if (object.ReferenceEquals(curNode, destNode))
                {
                    return(progress);
                }
                else
                {
                    List <Edge> edgeList = curNode.EdgeList;
                    foreach (Edge edge in edgeList)
                    {
                        if (!progress.IsNodeVisited(edge.Node))
                        {
                            double weight = curWeight + edge.Weight;
                            AStarSearchProgress newProgress = progress.Clone();
                            newProgress.Visit(edge);
                            newProgress.CurNode = edge.Node;

                            pq.Put(weight, newProgress);
                        }
                    }
                }
            }

            return(null);
        }
示例#3
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);
        }
示例#4
0
        public void Insert(Node value)
        {
            var item = new PriorityQueueItem(value, mItems.Count);

            mItems.Add(item);
            mHashSet.Add(value);
            RepairHeapUpwards(item.mHeapIndex);
        }
示例#5
0
 /// <summary>
 ///     Initializes a new instance of the <see cref = "PriorityQueue&lt;TValue&gt;" /> class.
 /// </summary>
 public PriorityQueue()
 {
     _lowerBound.HigherPriorityIndexMarker = _upperBound;
     _upperBound.LowerPriorityIndexMarker  = _lowerBound;
     _priorityQueue.Add(double.MinValue, _lowerBound);
     _priorityQueue.Add(double.MaxValue, _upperBound);
     _lastIndexMarker    = _upperBound;
     _currentIndexMarker = _lowerBound;
 }
示例#6
0
文件: Graph.cs 项目: junian/NeoGraph
        public void GeneratePrimMst(double[,] matrix)
        {
            int s = 0;

            int n = VertexList.Count;

            ClearSolution();
            Entry[] table = new Entry[n];
            for (int v = 0; v < n; v++)
            {
                table[v] = new Entry(false, int.MaxValue, int.MaxValue);
            }
            table[s].distance = 0;
            PriorityQueue <int, double> heap2 = new PriorityQueue <int, double>();

            heap2.Enqueue(s, 0);


            while (heap2.Count != 0)
            {
                PriorityQueueItem <int, double> pqitem = new PriorityQueueItem <int, double>();
                pqitem = heap2.Dequeue();
                int v0 = pqitem.Value;
                if (!table[v0].known)
                {
                    table[v0].known = true;
                    for (int i = 0; i < VertexList.Count; i++)
                    {
                        if (i != v0 && matrix[v0, i] > 0.0)
                        {
                            int v1 = i;
                            //Edge e = new Edge(VertexList[v0], VertexList[v1]);
                            double d = matrix[v0, i]; //e.Length;
                            if (!table[v1].known && table[v1].distance > d)
                            {
                                table[v1].distance    = d;
                                table[v1].predecessor = v0;
                                heap2.Enqueue(v1, d);
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < VertexList.Count; i++)
            {
                if (table[i].predecessor != int.MaxValue)
                {
                    int  next = table[i].predecessor;
                    Edge e    = new Edge(VertexList[i], VertexList[next]);
                    e.Length = matrix[i, next];
                    EdgeSolution.Add(e);
                }
            }
        }
示例#7
0
            public int Compare(PriorityQueueItem <TValue> x, PriorityQueueItem <TValue> y)
            {
                if (x.Priority > y.Priority)
                {
                    return(1);
                }

                if (x.Priority == y.Priority)
                {
                    return(x.Value.GetHashCode() - y.Value.GetHashCode());
                }

                return(-1);
            }
示例#8
0
        public void Solve()
        {
            IPriorityQueue <PriorityQueueItem> spots = priorityQueue; //Spots remaining to check
            List <Coordinate> seen = new List <Coordinate>();         //Spots already seen. Dont add them again.

            //Add the starting point to the graph.
            spots.Insert(new PriorityQueueItem
            {
                priority = 0,
                curr     = graph.Start,
                path     = new List <Coordinate>()
                {
                    graph.Start
                }
            });

            PriorityQueueItem current = spots.ExtractMin();                  //Get the min value from pqueue.

            while (!current.curr.Equals(graph.End))                          //Not to end yet.
            {
                List <Coordinate> adjs = graph.GetAdjacencies(current.curr); //Where all can I go?
                foreach (Coordinate adj in adjs)
                {
                    if (seen.Contains(adj)) //Already been here
                    {
                        continue;
                    }
                    //I could come here though
                    PriorityQueueItem new_spot = new PriorityQueueItem()
                    {
                        priority = current.path.Count + _heuristic.Score(graph, adj),
                        curr     = adj,
                        path     = new List <Coordinate>(current.path)
                    };
                    new_spot.path.Add(adj);   //Path includes current node
                    spots.Insert(new_spot);   //I'll check it
                }
                seen.Add(current.curr);       //Just checked you.
                current = spots.ExtractMin(); //Get next node.
            }
            path = current.path;              //Found a path.
        }
示例#9
0
        static void Main(string[] args)
        {
            PriorityQueue <AlarmEvent, AlarmEventType> pq =
                new PriorityQueue <AlarmEvent, AlarmEventType>();

            // Add a bunch of events to the queue
            pq.Enqueue(new AlarmEvent(AlarmEventType.Test, "Testing 1"), AlarmEventType.Test);
            pq.Enqueue(new AlarmEvent(AlarmEventType.Fire, "Fire alarm 1"), AlarmEventType.Fire);
            pq.Enqueue(new AlarmEvent(AlarmEventType.Trouble, "Battery low"), AlarmEventType.Trouble);
            pq.Enqueue(new AlarmEvent(AlarmEventType.Panic, "I've fallen and I can't get up!"), AlarmEventType.Panic);
            pq.Enqueue(new AlarmEvent(AlarmEventType.Test, "Another test."), AlarmEventType.Test);
            pq.Enqueue(new AlarmEvent(AlarmEventType.Alert, "Oops, I forgot the reset code."), AlarmEventType.Alert);

            Console.WriteLine("The queue contains {0} events", pq.Count);

            // Now remove the items in priority order
            Console.WriteLine();
            while (pq.Count > 0)
            {
                PriorityQueueItem <AlarmEvent, AlarmEventType> item = pq.Dequeue();
                Console.WriteLine("{0}: {1}", item.Priority, item.Value.Message);
            }
        }
示例#10
0
        /// <summary>
        ///     Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns>
        ///     An <see cref = "T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
        /// </returns>
        /// <filterpriority>2</filterpriority>
        IEnumerator <PriorityQueueItem <TValue> > IEnumerable <PriorityQueueItem <TValue> > .GetEnumerator()
        {
            List <PriorityQueueItem <TValue> > values = new List <PriorityQueueItem <TValue> >();

            PriorityQueueItem <TValue> _marker = _upperBound;
            PriorityQueueItem <TValue> _item   = null;

            while (_marker._lowerPriorityIndexMarker != null)
            {
                _item = _marker.Previous;

                while (_item != null)
                {
                    values.Add(_item);

                    _item = _item.Previous;
                }

                _marker = _marker._lowerPriorityIndexMarker;
            }

            return(new List <PriorityQueueItem <TValue> > .Enumerator());
        }
        /// <summary>
        /// Processes the events.
        /// </summary>
        private void ProcessEvents()
        {
            while (true)
            {
                EventAction action = null;
                lock (eventLock)
                {
                    if (eventQueue.Count > 0)
                    {
                        PriorityQueueItem <EventAction, EventPriority> eventItem = eventQueue.Dequeue();
                        action = eventItem.Value;
                        if (action == null)
                        {
                            return;
                        }
                    }
                }

                if (action != null)
                {
                    log.Info(string.Format("Processing events {0} from {1}", action.Notification, action.Computer));

                    // Start processing events
                    EventNotificationType notificationType = (EventNotificationType)StringEnum.Parse(typeof(EventNotificationType), action.Notification);
                    if (notificationType == EventNotificationType.NewMessage)
                    {
                        log.Info("New messages arrived");
                        RefreshMessageView(ViewAction.RefreshInbox);
                    }
                }
                else
                {
                    eventTrigger.WaitOne();       // wait for events
                }
            }
        }
示例#12
0
文件: Graph.cs 项目: junian/NeoGraph
        public void GenerateEuclideanPrimMst()
        {
            int s = 0;
            DateTime Start = DateTime.Now;
            int n = VertexList.Count;
            EdgeSolution.Clear();
            Entry[] table = new Entry[n];
            for (int v = 0; v < n; v++)
            {
                table[v] = new Entry(false, int.MaxValue, int.MaxValue);
            }
            table[s].distance = 0;
            PriorityQueue<int, double> heap2 = new PriorityQueue<int, double>();
            heap2.Enqueue(s, 0);

            //List<pqueue> heap1 = new List<pqueue>();
            //pqueue temp = new pqueue(s, 0);
            //heap1.Add(temp);

            //while (heap1.Count != 0)
            while (heap2.Count != 0)
            {
                //int v0 = heap1[0].vtx;
                //heap1.RemoveAt(0);
                PriorityQueueItem<int, double> pqitem = new PriorityQueueItem<int, double>();
                pqitem = heap2.Dequeue();
                int v0 = pqitem.Value;
                if (!table[v0].known)
                {
                    table[v0].known = true;
                    for (int i = 0; i < VertexList.Count; i++)
                    {
                        if (i != v0)
                        {
                            int v1 = i;
                            Edge e = new Edge(VertexList[v0], VertexList[v1]);
                            double d = e.Length;
                            if (!table[v1].known && table[v1].distance > d)
                            {
                                table[v1].distance = d;
                                table[v1].predecessor = v0;
                                heap2.Enqueue(v1, d);
                                //heap2.cekPQ();
                                /*pqueue temp1 = new pqueue(v1, d);
                                int j;
                                //Sortingnya O(n) males bikin AVL TREE =P
                                for (j = 0; j < heap1.Count && heap1[j].dist < temp1.dist; j++){}
                                if (j == heap1.Count) heap1.Add(temp1);
                                else heap1.Insert(j, temp1);*/
                                //heap1.Sort(new pqueueCompare());
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < VertexList.Count; i++)
            {
                if (table[i].predecessor != int.MaxValue)
                {
                    int next = table[i].predecessor;
                    Edge e = new Edge(VertexList[i], VertexList[next]);
                    EdgeSolution.Add(e);
                }
            }
            Console.WriteLine((DateTime.Now - Start).TotalMilliseconds + " ms");
            //this.VisitedVertex = VertexList.Count;
        }
示例#13
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);
        }
示例#14
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_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);
                }
            }

            lock (m_presenceUpdatesToSend)
            {
                int numToSend = (int)(numUpdates * PresenceSendPercentage);
                //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 > numToSend ? numToSend : 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)
            {
                int numToSend = (int)(numUpdates * PrimSendPercentage);
                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;
        }
示例#15
0
        /// <summary>
        ///     Enqueues the specified value.
        /// </summary>
        /// <param name = "value">The value.</param>
        /// <param name = "priority">The priority.</param>
        public void Enqueue(TValue value, double priority)
        {
            lock (_lock)
            {
                //add index marker
                if (!_priorityQueue.ContainsKey(priority))
                {
                    PriorityQueueItem <TValue> indexMarker = new PriorityQueueItem <TValue>(default(TValue), priority);
                    indexMarker.IsIndexMarker = true;

                    _priorityQueue.Add(priority, indexMarker);

                    if (priority > _lastIndexMarker.Priority)
                    {
                        do
                        {
                            _lastIndexMarker = _lastIndexMarker.HigherPriorityIndexMarker;
                        } while (_lastIndexMarker.HigherPriorityIndexMarker != null && _lastIndexMarker.Priority < priority);

                        indexMarker.HigherPriorityIndexMarker = _lastIndexMarker;
                        indexMarker.LowerPriorityIndexMarker  = _lastIndexMarker.LowerPriorityIndexMarker;

                        _lastIndexMarker.LowerPriorityIndexMarker.HigherPriorityIndexMarker = indexMarker;
                        _lastIndexMarker.LowerPriorityIndexMarker = indexMarker;
                    }
                    else if (priority < _lastIndexMarker.Priority)
                    {
                        do
                        {
                            _lastIndexMarker = _lastIndexMarker.LowerPriorityIndexMarker;
                        } while (_lastIndexMarker.LowerPriorityIndexMarker != null && _lastIndexMarker.Priority > priority);

                        indexMarker.LowerPriorityIndexMarker  = _lastIndexMarker;
                        indexMarker.HigherPriorityIndexMarker = _lastIndexMarker.HigherPriorityIndexMarker;

                        _lastIndexMarker.HigherPriorityIndexMarker.LowerPriorityIndexMarker = indexMarker;
                        _lastIndexMarker.HigherPriorityIndexMarker = indexMarker;
                    }

                    _lastIndexMarker = indexMarker;
                }

                //update the current index marker
                if (priority > _currentIndexMarker.Priority)
                {
                    _currentIndexMarker = _priorityQueue[priority];
                }

                //manage the list
                PriorityQueueItem <TValue> priorityQueueItem = new PriorityQueueItem <TValue>(value, priority);

                if (_priorityQueue[priority].Previous == null)
                {
                    _priorityQueue[priority].Previous = priorityQueueItem;
                    _priorityQueue[priority].Last     = priorityQueueItem;
                }
                else
                {
                    _priorityQueue[priority].Last.Previous = priorityQueueItem;
                    _priorityQueue[priority].Last          = priorityQueueItem;
                }

                //increment the count
                _count++;
            }
        }
        /// <summary>
        /// Attempts to use the data provided in packetBuilder to recreate something useful. If we don't have enough data
        /// yet that value is set in packetBuilder.
        /// </summary>
        /// <param name="packetBuilder">The <see cref="PacketBuilder"/> containing incoming cached data</param>
        protected void IncomingPacketHandleHandOff(PacketBuilder packetBuilder)
        {
            int loopCounter = 0;

            try
            {
                if (NetworkComms.LoggingEnabled)
                {
                    NetworkComms.Logger.Trace(" ... checking for completed packet with " + packetBuilder.TotalBytesCached.ToString() + " bytes read.");
                }

                if (packetBuilder.TotalPartialPacketCount == 0)
                {
                    throw new Exception("Executing IncomingPacketHandleHandOff when no packets exist in packetbuilder.");
                }

                //Loop until we are finished with this packetBuilder
                while (true)
                {
                    //If we have ended up with a null packet at the front, probably due to some form of concatenation we can pull it off here
                    //It is possible we have concatenation of several null packets along with real data so we loop until the firstByte is greater than 0
                    if (ConnectionInfo.ApplicationLayerProtocol == ApplicationLayerProtocolStatus.Enabled && packetBuilder.FirstByte() == 0)
                    {
                        #region Ignore Null Packet
                        if (NetworkComms.LoggingEnabled)
                        {
                            NetworkComms.Logger.Trace(" ... null packet removed in IncomingPacketHandleHandOff() from " + ConnectionInfo + ", loop index - " + loopCounter.ToString());
                        }

                        packetBuilder.ClearNTopBytes(1);

                        //Reset the expected bytes to 0 so that the next check starts from scratch
                        packetBuilder.TotalBytesExpected = 0;

                        //If we have run out of data completely then we can return immediately
                        if (packetBuilder.TotalBytesCached == 0)
                        {
                            return;
                        }
                        #endregion
                    }
                    else
                    {
                        int          packetHeaderSize = 0;
                        PacketHeader topPacketHeader;

                        #region Set topPacketHeader
                        if (ConnectionInfo.ApplicationLayerProtocol == ApplicationLayerProtocolStatus.Enabled)
                        {
                            //First determine the expected size of a header packet
                            packetHeaderSize = packetBuilder.FirstByte() + 1;

                            //Do we have enough data to build a header?
                            if (packetBuilder.TotalBytesCached < packetHeaderSize)
                            {
                                if (NetworkComms.LoggingEnabled)
                                {
                                    NetworkComms.Logger.Trace("     ... require " + packetHeaderSize + " bytes for packet header, only " + packetBuilder.TotalBytesCached + " bytes cached.");
                                }

                                //Set the expected number of bytes and then return
                                packetBuilder.TotalBytesExpected = packetHeaderSize;
                                return;
                            }

                            if (NetworkComms.LoggingEnabled)
                            {
                                NetworkComms.Logger.Trace("     ... deserializing header using " + packetHeaderSize + " bytes, " + packetBuilder.TotalBytesCached + " bytes cached.");
                            }

                            //We have enough for a header
                            using (MemoryStream headerStream = packetBuilder.ReadDataSection(1, packetHeaderSize - 1))
                                topPacketHeader = new PacketHeader(headerStream, NetworkComms.InternalFixedSendReceiveOptions);
                        }
                        else
                        {
                            topPacketHeader = new PacketHeader(Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged), packetBuilder.TotalBytesCached);
                        }
                        #endregion

                        //Idiot test
                        if (topPacketHeader.PacketType == null)
                        {
                            throw new SerialisationException("packetType value in packetHeader should never be null");
                        }

                        //We can now use the header to establish if we have enough payload data
                        //First case is when we have not yet received enough data
                        if (packetBuilder.TotalBytesCached < packetHeaderSize + topPacketHeader.TotalPayloadSize)
                        {
                            if (NetworkComms.LoggingEnabled)
                            {
                                NetworkComms.Logger.Trace("     ... more data required for complete packet payload. Expecting " + (packetHeaderSize + topPacketHeader.TotalPayloadSize).ToString() + " total packet bytes.");
                            }

                            //Set the expected number of bytes and then return
                            packetBuilder.TotalBytesExpected = packetHeaderSize + topPacketHeader.TotalPayloadSize;
                            return;
                        }
                        //Second case is we have enough data
                        else if (packetBuilder.TotalBytesCached >= packetHeaderSize + topPacketHeader.TotalPayloadSize)
                        {
                            #region Handle Packet
                            //We can either have exactly the right amount or even more than we were expecting
                            //We may have too much data if we are sending high quantities and the packets have been concatenated
                            SendReceiveOptions incomingPacketSendReceiveOptions = IncomingPacketSendReceiveOptions(topPacketHeader);
                            if (NetworkComms.LoggingEnabled)
                            {
                                NetworkComms.Logger.Debug("Received packet of type '" + topPacketHeader.PacketType + "' from " + ConnectionInfo + ", containing " + packetHeaderSize.ToString() + " header bytes and " + topPacketHeader.TotalPayloadSize.ToString() + " payload bytes.");
                            }

                            bool isReservedPacketType = (topPacketHeader.PacketType != Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged) &&
                                                         NetworkComms.ReservedPacketTypeNames.ContainsKey(topPacketHeader.PacketType));

                            //Get the packet sequence number if logging
                            string packetSeqNumStr = "";
                            if (NetworkComms.LoggingEnabled)
                            {
                                packetSeqNumStr = (topPacketHeader.ContainsOption(PacketHeaderLongItems.PacketSequenceNumber) ? ". pSeq#-" + topPacketHeader.GetOption(PacketHeaderLongItems.PacketSequenceNumber).ToString() + "." : "");
                            }

                            //Only reserved packet types get completed inline by default
                            if (isReservedPacketType)
                            {
#if WINDOWS_PHONE || NETFX_CORE
                                QueueItemPriority priority = QueueItemPriority.Normal;
#else
                                QueueItemPriority priority = (QueueItemPriority)Thread.CurrentThread.Priority;
#endif
                                PriorityQueueItem item = new PriorityQueueItem(priority, this, topPacketHeader, packetBuilder.ReadDataSection(packetHeaderSize, topPacketHeader.TotalPayloadSize), incomingPacketSendReceiveOptions);
                                if (NetworkComms.LoggingEnabled)
                                {
                                    NetworkComms.Logger.Trace(" ... handling packet type '" + topPacketHeader.PacketType + "' inline. Loop index - " + loopCounter.ToString() + packetSeqNumStr);
                                }
                                NetworkComms.CompleteIncomingItemTask(item);
                            }
                            else
                            {
                                QueueItemPriority itemPriority = (incomingPacketSendReceiveOptions.Options.ContainsKey("ReceiveHandlePriority") ? (QueueItemPriority)Enum.Parse(typeof(QueueItemPriority), incomingPacketSendReceiveOptions.Options["ReceiveHandlePriority"]) : QueueItemPriority.Normal);
                                PriorityQueueItem item         = new PriorityQueueItem(itemPriority, this, topPacketHeader, packetBuilder.ReadDataSection(packetHeaderSize, topPacketHeader.TotalPayloadSize), incomingPacketSendReceiveOptions);

                                //QueueItemPriority.Highest is the only priority that is executed inline
                                if (itemPriority == QueueItemPriority.Highest)
                                {
                                    if (NetworkComms.LoggingEnabled)
                                    {
                                        NetworkComms.Logger.Trace(" ... handling packet type '" + topPacketHeader.PacketType + "' with priority HIGHEST inline. Loop index - " + loopCounter.ToString() + packetSeqNumStr);
                                    }
                                    NetworkComms.CompleteIncomingItemTask(item);
                                }
                                else
                                {
#if NETFX_CORE
                                    NetworkComms.CommsThreadPool.EnqueueItem(item.Priority, NetworkComms.CompleteIncomingItemTask, item);
                                    if (NetworkComms.LoggingEnabled)
                                    {
                                        NetworkComms.Logger.Trace(" ... added completed " + item.PacketHeader.PacketType + " packet to thread pool (Q:" + NetworkComms.CommsThreadPool.QueueCount.ToString() + ") with priority " + itemPriority.ToString() + ". Loop index=" + loopCounter.ToString() + packetSeqNumStr);
                                    }
#else
                                    int threadId = NetworkComms.CommsThreadPool.EnqueueItem(item.Priority, NetworkComms.CompleteIncomingItemTask, item);
                                    if (NetworkComms.LoggingEnabled)
                                    {
                                        NetworkComms.Logger.Trace(" ... added completed " + item.PacketHeader.PacketType + " packet to thread pool (Q:" + NetworkComms.CommsThreadPool.QueueCount.ToString() + ", T:" + NetworkComms.CommsThreadPool.CurrentNumTotalThreads.ToString() + ", I:" + NetworkComms.CommsThreadPool.CurrentNumIdleThreads.ToString() + ") with priority " + itemPriority.ToString() + (threadId > 0 ? ". Selected threadId=" + threadId.ToString() : "") + ". Loop index=" + loopCounter.ToString() + packetSeqNumStr);
                                    }
#endif
                                }
                            }

                            //We clear the bytes we have just handed off
                            if (NetworkComms.LoggingEnabled)
                            {
                                NetworkComms.Logger.Trace("Removing " + (packetHeaderSize + topPacketHeader.TotalPayloadSize).ToString() + " bytes from incoming packet builder from connection with " + ConnectionInfo + ".");
                            }
                            packetBuilder.ClearNTopBytes(packetHeaderSize + topPacketHeader.TotalPayloadSize);

                            //Reset the expected bytes to 0 so that the next check starts from scratch
                            packetBuilder.TotalBytesExpected = 0;

                            //If we have run out of data completely then we can return immediately
                            if (packetBuilder.TotalBytesCached == 0)
                            {
                                return;
                            }
                            #endregion
                        }
                        else
                        {
                            throw new CommunicationException("This should be impossible!");
                        }
                    }

                    loopCounter++;
                }
            }
            catch (Exception ex)
            {
                //Any error, throw an exception.
                if (NetworkComms.LoggingEnabled)
                {
                    NetworkComms.Logger.Fatal("A fatal exception occurred in IncomingPacketHandleHandOff(), connection with " + ConnectionInfo + " be closed. See log file for more information.");
                }

                if (this is IPConnection)
                {
                    //Log the exception in DOS protection if enabled
                    if (IPConnection.DOSProtection.Enabled && ConnectionInfo.RemoteEndPoint.GetType() == typeof(IPEndPoint))
                    {
                        IPConnection.DOSProtection.LogMalformedData(ConnectionInfo.RemoteIPEndPoint.Address);
                    }
                }

                LogTools.LogException(ex, "CommsError", "A fatal exception occurred in IncomingPacketHandleHandOff(), connection with " + ConnectionInfo + " be closed. Loop counter " + loopCounter.ToString() + ". Packet builder contained " + packetBuilder.TotalBytesCached + " total cached bytes.");
                CloseConnection(true, 45);
            }
        }
示例#17
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;
        }
示例#18
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;
        }
示例#19
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);
        }
示例#20
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;
        }
示例#21
0
 public static int Compare(PriorityQueueItem <EntityUpdate, int> x, PriorityQueueItem <EntityUpdate, int> y)
 {
     return(x._priority.CompareTo(y._priority));
 }
示例#22
0
文件: Graph.cs 项目: junian/NeoGraph
        public void GeneratePrimMst(double[,] matrix)
        {
            int s = 0;

            int n = VertexList.Count;
            ClearSolution();
            Entry[] table = new Entry[n];
            for (int v = 0; v < n; v++)
            {
                table[v] = new Entry(false, int.MaxValue, int.MaxValue);
            }
            table[s].distance = 0;
            PriorityQueue<int, double> heap2 = new PriorityQueue<int, double>();
            heap2.Enqueue(s, 0);

            while (heap2.Count != 0)
            {

                PriorityQueueItem<int, double> pqitem = new PriorityQueueItem<int, double>();
                pqitem = heap2.Dequeue();
                int v0 = pqitem.Value;
                if (!table[v0].known)
                {
                    table[v0].known = true;
                    for (int i = 0; i < VertexList.Count; i++)
                    {
                        if (i != v0 && matrix[v0,i] > 0.0)
                        {
                            int v1 = i;
                            //Edge e = new Edge(VertexList[v0], VertexList[v1]);
                            double d = matrix[v0, i]; //e.Length;
                            if (!table[v1].known && table[v1].distance > d)
                            {
                                table[v1].distance = d;
                                table[v1].predecessor = v0;
                                heap2.Enqueue(v1, d);
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < VertexList.Count; i++)
            {
                if (table[i].predecessor != int.MaxValue)
                {
                    int next = table[i].predecessor;
                    Edge e = new Edge(VertexList[i], VertexList[next]);
                    e.Length = matrix[i, next];
                    EdgeSolution.Add(e);
                }
            }
        }
示例#23
0
文件: Graph.cs 项目: junian/NeoGraph
        public void GenerateEuclideanPrimMst()
        {
            int      s     = 0;
            DateTime Start = DateTime.Now;
            int      n     = VertexList.Count;

            EdgeSolution.Clear();
            Entry[] table = new Entry[n];
            for (int v = 0; v < n; v++)
            {
                table[v] = new Entry(false, int.MaxValue, int.MaxValue);
            }
            table[s].distance = 0;
            PriorityQueue <int, double> heap2 = new PriorityQueue <int, double>();

            heap2.Enqueue(s, 0);

            //List<pqueue> heap1 = new List<pqueue>();
            //pqueue temp = new pqueue(s, 0);
            //heap1.Add(temp);

            //while (heap1.Count != 0)
            while (heap2.Count != 0)
            {
                //int v0 = heap1[0].vtx;
                //heap1.RemoveAt(0);
                PriorityQueueItem <int, double> pqitem = new PriorityQueueItem <int, double>();
                pqitem = heap2.Dequeue();
                int v0 = pqitem.Value;
                if (!table[v0].known)
                {
                    table[v0].known = true;
                    for (int i = 0; i < VertexList.Count; i++)
                    {
                        if (i != v0)
                        {
                            int    v1 = i;
                            Edge   e  = new Edge(VertexList[v0], VertexList[v1]);
                            double d  = e.Length;
                            if (!table[v1].known && table[v1].distance > d)
                            {
                                table[v1].distance    = d;
                                table[v1].predecessor = v0;
                                heap2.Enqueue(v1, d);
                                //heap2.cekPQ();

                                /*pqueue temp1 = new pqueue(v1, d);
                                 * int j;
                                 * //Sortingnya O(n) males bikin AVL TREE =P
                                 * for (j = 0; j < heap1.Count && heap1[j].dist < temp1.dist; j++){}
                                 * if (j == heap1.Count) heap1.Add(temp1);
                                 * else heap1.Insert(j, temp1);*/
                                //heap1.Sort(new pqueueCompare());
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < VertexList.Count; i++)
            {
                if (table[i].predecessor != int.MaxValue)
                {
                    int  next = table[i].predecessor;
                    Edge e    = new Edge(VertexList[i], VertexList[next]);
                    EdgeSolution.Add(e);
                }
            }
            Console.WriteLine((DateTime.Now - Start).TotalMilliseconds + " ms");
            //this.VisitedVertex = VertexList.Count;
        }
示例#24
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();
        }