diff options
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r-- | OpenSim/Framework/AgentCircuitData.cs | 69 | ||||
-rw-r--r-- | OpenSim/Framework/ChildAgentDataUpdate.cs | 57 | ||||
-rw-r--r-- | OpenSim/Framework/ClientInfo.cs | 3 | ||||
-rw-r--r-- | OpenSim/Framework/Console/CommandConsole.cs | 4 | ||||
-rw-r--r-- | OpenSim/Framework/IClientAPI.cs | 59 | ||||
-rw-r--r-- | OpenSim/Framework/PriorityQueue.cs | 323 | ||||
-rw-r--r-- | OpenSim/Framework/RegionInfo.cs | 17 | ||||
-rw-r--r-- | OpenSim/Framework/Servers/VersionInfo.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/Tests/MundaneFrameworkTests.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/Util.cs | 17 |
10 files changed, 460 insertions, 93 deletions
diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 3dbc215..dbd47d3 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs | |||
@@ -152,27 +152,6 @@ namespace OpenSim.Framework | |||
152 | } | 152 | } |
153 | 153 | ||
154 | /// <summary> | 154 | /// <summary> |
155 | /// Create AgentCircuitData from a Serializable AgentCircuitData | ||
156 | /// </summary> | ||
157 | /// <param name="cAgent"></param> | ||
158 | public AgentCircuitData(sAgentCircuitData cAgent) | ||
159 | { | ||
160 | AgentID = new UUID(cAgent.AgentID); | ||
161 | SessionID = new UUID(cAgent.SessionID); | ||
162 | SecureSessionID = new UUID(cAgent.SecureSessionID); | ||
163 | startpos = new Vector3(cAgent.startposx, cAgent.startposy, cAgent.startposz); | ||
164 | firstname = cAgent.firstname; | ||
165 | lastname = cAgent.lastname; | ||
166 | circuitcode = cAgent.circuitcode; | ||
167 | child = cAgent.child; | ||
168 | InventoryFolder = new UUID(cAgent.InventoryFolder); | ||
169 | BaseFolder = new UUID(cAgent.BaseFolder); | ||
170 | CapsPath = cAgent.CapsPath; | ||
171 | ChildrenCapSeeds = cAgent.ChildrenCapSeeds; | ||
172 | Viewer = cAgent.Viewer; | ||
173 | } | ||
174 | |||
175 | /// <summary> | ||
176 | /// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json | 155 | /// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json |
177 | /// </summary> | 156 | /// </summary> |
178 | /// <returns>map of the agent circuit data</returns> | 157 | /// <returns>map of the agent circuit data</returns> |
@@ -369,52 +348,4 @@ namespace OpenSim.Framework | |||
369 | } | 348 | } |
370 | 349 | ||
371 | 350 | ||
372 | /// <summary> | ||
373 | /// Serializable Agent Circuit Data | ||
374 | /// </summary> | ||
375 | [Serializable] | ||
376 | public class sAgentCircuitData | ||
377 | { | ||
378 | public Guid AgentID; | ||
379 | public Guid BaseFolder; | ||
380 | public string CapsPath = String.Empty; | ||
381 | public Dictionary<ulong, string> ChildrenCapSeeds; | ||
382 | public bool child; | ||
383 | public uint circuitcode; | ||
384 | public string firstname; | ||
385 | public Guid InventoryFolder; | ||
386 | public string lastname; | ||
387 | public Guid SecureSessionID; | ||
388 | public Guid SessionID; | ||
389 | public float startposx; | ||
390 | public float startposy; | ||
391 | public float startposz; | ||
392 | public string Viewer; | ||
393 | public string Channel; | ||
394 | public string Mac; | ||
395 | public string Id0; | ||
396 | |||
397 | public sAgentCircuitData() | ||
398 | { | ||
399 | } | ||
400 | |||
401 | public sAgentCircuitData(AgentCircuitData cAgent) | ||
402 | { | ||
403 | AgentID = cAgent.AgentID.Guid; | ||
404 | SessionID = cAgent.SessionID.Guid; | ||
405 | SecureSessionID = cAgent.SecureSessionID.Guid; | ||
406 | startposx = cAgent.startpos.X; | ||
407 | startposy = cAgent.startpos.Y; | ||
408 | startposz = cAgent.startpos.Z; | ||
409 | firstname = cAgent.firstname; | ||
410 | lastname = cAgent.lastname; | ||
411 | circuitcode = cAgent.circuitcode; | ||
412 | child = cAgent.child; | ||
413 | InventoryFolder = cAgent.InventoryFolder.Guid; | ||
414 | BaseFolder = cAgent.BaseFolder.Guid; | ||
415 | CapsPath = cAgent.CapsPath; | ||
416 | ChildrenCapSeeds = cAgent.ChildrenCapSeeds; | ||
417 | Viewer = cAgent.Viewer; | ||
418 | } | ||
419 | } | ||
420 | } | 351 | } |
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index ce0b2fb..a626b82 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs | |||
@@ -62,7 +62,7 @@ namespace OpenSim.Framework | |||
62 | UUID AgentID { get; set; } | 62 | UUID AgentID { get; set; } |
63 | 63 | ||
64 | OSDMap Pack(); | 64 | OSDMap Pack(); |
65 | void Unpack(OSDMap map); | 65 | void Unpack(OSDMap map, IScene scene); |
66 | } | 66 | } |
67 | 67 | ||
68 | /// <summary> | 68 | /// <summary> |
@@ -122,7 +122,7 @@ namespace OpenSim.Framework | |||
122 | return args; | 122 | return args; |
123 | } | 123 | } |
124 | 124 | ||
125 | public void Unpack(OSDMap args) | 125 | public void Unpack(OSDMap args, IScene scene) |
126 | { | 126 | { |
127 | if (args.ContainsKey("region_handle")) | 127 | if (args.ContainsKey("region_handle")) |
128 | UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); | 128 | UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); |
@@ -329,6 +329,10 @@ namespace OpenSim.Framework | |||
329 | 329 | ||
330 | public string CallbackURI; | 330 | public string CallbackURI; |
331 | 331 | ||
332 | // These two must have the same Count | ||
333 | public List<ISceneObject> AttachmentObjects; | ||
334 | public List<string> AttachmentObjectStates; | ||
335 | |||
332 | public virtual OSDMap Pack() | 336 | public virtual OSDMap Pack() |
333 | { | 337 | { |
334 | m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); | 338 | m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); |
@@ -441,7 +445,30 @@ namespace OpenSim.Framework | |||
441 | if ((CallbackURI != null) && (!CallbackURI.Equals(""))) | 445 | if ((CallbackURI != null) && (!CallbackURI.Equals(""))) |
442 | args["callback_uri"] = OSD.FromString(CallbackURI); | 446 | args["callback_uri"] = OSD.FromString(CallbackURI); |
443 | 447 | ||
448 | // Attachment objects for fatpack messages | ||
449 | if (AttachmentObjects != null) | ||
450 | { | ||
451 | int i = 0; | ||
452 | OSDArray attObjs = new OSDArray(AttachmentObjects.Count); | ||
453 | foreach (ISceneObject so in AttachmentObjects) | ||
454 | { | ||
455 | OSDMap info = new OSDMap(4); | ||
456 | info["sog"] = OSD.FromString(so.ToXml2()); | ||
457 | info["extra"] = OSD.FromString(so.ExtraToXmlString()); | ||
458 | info["modified"] = OSD.FromBoolean(so.HasGroupChanged); | ||
459 | try | ||
460 | { | ||
461 | info["state"] = OSD.FromString(AttachmentObjectStates[i++]); | ||
462 | } | ||
463 | catch (IndexOutOfRangeException e) | ||
464 | { | ||
465 | m_log.WarnFormat("[CHILD AGENT DATA]: scrtips list is shorter than object list."); | ||
466 | } | ||
444 | 467 | ||
468 | attObjs.Add(info); | ||
469 | } | ||
470 | args["attach_objects"] = attObjs; | ||
471 | } | ||
445 | return args; | 472 | return args; |
446 | } | 473 | } |
447 | 474 | ||
@@ -450,7 +477,7 @@ namespace OpenSim.Framework | |||
450 | /// Avoiding reflection makes it painful to write, but that's the price! | 477 | /// Avoiding reflection makes it painful to write, but that's the price! |
451 | /// </summary> | 478 | /// </summary> |
452 | /// <param name="hash"></param> | 479 | /// <param name="hash"></param> |
453 | public virtual void Unpack(OSDMap args) | 480 | public virtual void Unpack(OSDMap args, IScene scene) |
454 | { | 481 | { |
455 | m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); | 482 | m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); |
456 | 483 | ||
@@ -628,6 +655,26 @@ namespace OpenSim.Framework | |||
628 | 655 | ||
629 | if (args["callback_uri"] != null) | 656 | if (args["callback_uri"] != null) |
630 | CallbackURI = args["callback_uri"].AsString(); | 657 | CallbackURI = args["callback_uri"].AsString(); |
658 | |||
659 | // Attachment objects | ||
660 | if (args["attach_objects"] != null && args["attach_objects"].Type == OSDType.Array) | ||
661 | { | ||
662 | OSDArray attObjs = (OSDArray)(args["attach_objects"]); | ||
663 | AttachmentObjects = new List<ISceneObject>(); | ||
664 | AttachmentObjectStates = new List<string>(); | ||
665 | foreach (OSD o in attObjs) | ||
666 | { | ||
667 | if (o.Type == OSDType.Map) | ||
668 | { | ||
669 | OSDMap info = (OSDMap)o; | ||
670 | ISceneObject so = scene.DeserializeObject(info["sog"].AsString()); | ||
671 | so.ExtraFromXmlString(info["extra"].AsString()); | ||
672 | so.HasGroupChanged = info["modified"].AsBoolean(); | ||
673 | AttachmentObjects.Add(so); | ||
674 | AttachmentObjectStates.Add(info["state"].AsString()); | ||
675 | } | ||
676 | } | ||
677 | } | ||
631 | } | 678 | } |
632 | 679 | ||
633 | public AgentData() | 680 | public AgentData() |
@@ -655,9 +702,9 @@ namespace OpenSim.Framework | |||
655 | return base.Pack(); | 702 | return base.Pack(); |
656 | } | 703 | } |
657 | 704 | ||
658 | public override void Unpack(OSDMap map) | 705 | public override void Unpack(OSDMap map, IScene scene) |
659 | { | 706 | { |
660 | base.Unpack(map); | 707 | base.Unpack(map, scene); |
661 | } | 708 | } |
662 | } | 709 | } |
663 | } | 710 | } |
diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs index fbd18b5..62acb70 100644 --- a/OpenSim/Framework/ClientInfo.cs +++ b/OpenSim/Framework/ClientInfo.cs | |||
@@ -31,10 +31,9 @@ using System.Net; | |||
31 | 31 | ||
32 | namespace OpenSim.Framework | 32 | namespace OpenSim.Framework |
33 | { | 33 | { |
34 | [Serializable] | ||
35 | public class ClientInfo | 34 | public class ClientInfo |
36 | { | 35 | { |
37 | public sAgentCircuitData agentcircuit; | 36 | public AgentCircuitData agentcircuit; |
38 | 37 | ||
39 | public Dictionary<uint, byte[]> needAck; | 38 | public Dictionary<uint, byte[]> needAck; |
40 | 39 | ||
diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index 52bcd55..be36cf2 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs | |||
@@ -592,9 +592,7 @@ namespace OpenSim.Framework.Console | |||
592 | string line = ReadLine(m_defaultPrompt + "# ", true, true); | 592 | string line = ReadLine(m_defaultPrompt + "# ", true, true); |
593 | 593 | ||
594 | if (line != String.Empty) | 594 | if (line != String.Empty) |
595 | { | 595 | Output("Invalid command"); |
596 | m_log.Info("[CONSOLE] Invalid command"); | ||
597 | } | ||
598 | } | 596 | } |
599 | 597 | ||
600 | public void RunCommand(string cmd) | 598 | public void RunCommand(string cmd) |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index f573c32..069987b 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -572,34 +572,69 @@ namespace OpenSim.Framework | |||
572 | 572 | ||
573 | public class IEntityUpdate | 573 | public class IEntityUpdate |
574 | { | 574 | { |
575 | public ISceneEntity Entity; | 575 | private ISceneEntity m_entity; |
576 | public uint Flags; | 576 | private uint m_flags; |
577 | private int m_updateTime; | ||
578 | |||
579 | public ISceneEntity Entity | ||
580 | { | ||
581 | get { return m_entity; } | ||
582 | } | ||
583 | |||
584 | public uint Flags | ||
585 | { | ||
586 | get { return m_flags; } | ||
587 | } | ||
588 | |||
589 | public int UpdateTime | ||
590 | { | ||
591 | get { return m_updateTime; } | ||
592 | } | ||
577 | 593 | ||
578 | public virtual void Update(IEntityUpdate update) | 594 | public virtual void Update(IEntityUpdate update) |
579 | { | 595 | { |
580 | this.Flags |= update.Flags; | 596 | m_flags |= update.Flags; |
597 | |||
598 | // Use the older of the updates as the updateTime | ||
599 | if (Util.EnvironmentTickCountCompare(UpdateTime, update.UpdateTime) > 0) | ||
600 | m_updateTime = update.UpdateTime; | ||
581 | } | 601 | } |
582 | 602 | ||
583 | public IEntityUpdate(ISceneEntity entity, uint flags) | 603 | public IEntityUpdate(ISceneEntity entity, uint flags) |
584 | { | 604 | { |
585 | Entity = entity; | 605 | m_entity = entity; |
586 | Flags = flags; | 606 | m_flags = flags; |
607 | m_updateTime = Util.EnvironmentTickCount(); | ||
608 | } | ||
609 | |||
610 | public IEntityUpdate(ISceneEntity entity, uint flags, Int32 updateTime) | ||
611 | { | ||
612 | m_entity = entity; | ||
613 | m_flags = flags; | ||
614 | m_updateTime = updateTime; | ||
587 | } | 615 | } |
588 | } | 616 | } |
589 | |||
590 | 617 | ||
591 | public class EntityUpdate : IEntityUpdate | 618 | public class EntityUpdate : IEntityUpdate |
592 | { | 619 | { |
593 | // public ISceneEntity Entity; | 620 | private float m_timeDilation; |
594 | // public PrimUpdateFlags Flags; | 621 | |
595 | public float TimeDilation; | 622 | public float TimeDilation |
623 | { | ||
624 | get { return m_timeDilation; } | ||
625 | } | ||
596 | 626 | ||
597 | public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) | 627 | public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) |
598 | : base(entity,(uint)flags) | 628 | : base(entity, (uint)flags) |
599 | { | 629 | { |
600 | //Entity = entity; | ||
601 | // Flags = flags; | 630 | // Flags = flags; |
602 | TimeDilation = timedilation; | 631 | m_timeDilation = timedilation; |
632 | } | ||
633 | |||
634 | public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation, Int32 updateTime) | ||
635 | : base(entity,(uint)flags,updateTime) | ||
636 | { | ||
637 | m_timeDilation = timedilation; | ||
603 | } | 638 | } |
604 | } | 639 | } |
605 | 640 | ||
diff --git a/OpenSim/Framework/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs new file mode 100644 index 0000000..3e6fdaa --- /dev/null +++ b/OpenSim/Framework/PriorityQueue.cs | |||
@@ -0,0 +1,323 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Client; | ||
35 | using log4net; | ||
36 | |||
37 | namespace OpenSim.Framework | ||
38 | { | ||
39 | public class PriorityQueue | ||
40 | { | ||
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
42 | |||
43 | public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); | ||
44 | |||
45 | /// <summary> | ||
46 | /// Total number of queues (priorities) available | ||
47 | /// </summary> | ||
48 | public const uint NumberOfQueues = 12; | ||
49 | |||
50 | /// <summary> | ||
51 | /// Number of queuest (priorities) that are processed immediately | ||
52 | /// </summary. | ||
53 | public const uint NumberOfImmediateQueues = 2; | ||
54 | |||
55 | private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[NumberOfQueues]; | ||
56 | private Dictionary<uint, LookupItem> m_lookupTable; | ||
57 | |||
58 | // internal state used to ensure the deqeues are spread across the priority | ||
59 | // queues "fairly". queuecounts is the amount to pull from each queue in | ||
60 | // each pass. weighted towards the higher priority queues | ||
61 | private uint m_nextQueue = 0; | ||
62 | private uint m_countFromQueue = 0; | ||
63 | private uint[] m_queueCounts = { 8, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1 }; | ||
64 | |||
65 | // next request is a counter of the number of updates queued, it provides | ||
66 | // a total ordering on the updates coming through the queue and is more | ||
67 | // lightweight (and more discriminating) than tick count | ||
68 | private UInt64 m_nextRequest = 0; | ||
69 | |||
70 | /// <summary> | ||
71 | /// Lock for enqueue and dequeue operations on the priority queue | ||
72 | /// </summary> | ||
73 | private object m_syncRoot = new object(); | ||
74 | public object SyncRoot { | ||
75 | get { return this.m_syncRoot; } | ||
76 | } | ||
77 | |||
78 | #region constructor | ||
79 | public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { } | ||
80 | |||
81 | public PriorityQueue(int capacity) | ||
82 | { | ||
83 | m_lookupTable = new Dictionary<uint, LookupItem>(capacity); | ||
84 | |||
85 | for (int i = 0; i < m_heaps.Length; ++i) | ||
86 | m_heaps[i] = new MinHeap<MinHeapItem>(capacity); | ||
87 | |||
88 | m_nextQueue = NumberOfImmediateQueues; | ||
89 | m_countFromQueue = m_queueCounts[m_nextQueue]; | ||
90 | } | ||
91 | #endregion Constructor | ||
92 | |||
93 | #region PublicMethods | ||
94 | /// <summary> | ||
95 | /// Return the number of items in the queues | ||
96 | /// </summary> | ||
97 | public int Count | ||
98 | { | ||
99 | get | ||
100 | { | ||
101 | int count = 0; | ||
102 | for (int i = 0; i < m_heaps.Length; ++i) | ||
103 | count += m_heaps[i].Count; | ||
104 | |||
105 | return count; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /// <summary> | ||
110 | /// Enqueue an item into the specified priority queue | ||
111 | /// </summary> | ||
112 | public bool Enqueue(uint pqueue, IEntityUpdate value) | ||
113 | { | ||
114 | LookupItem lookup; | ||
115 | |||
116 | uint localid = value.Entity.LocalId; | ||
117 | UInt64 entry = m_nextRequest++; | ||
118 | if (m_lookupTable.TryGetValue(localid, out lookup)) | ||
119 | { | ||
120 | entry = lookup.Heap[lookup.Handle].EntryOrder; | ||
121 | value.Update(lookup.Heap[lookup.Handle].Value); | ||
122 | lookup.Heap.Remove(lookup.Handle); | ||
123 | } | ||
124 | |||
125 | pqueue = Util.Clamp<uint>(pqueue, 0, NumberOfQueues - 1); | ||
126 | lookup.Heap = m_heaps[pqueue]; | ||
127 | lookup.Heap.Add(new MinHeapItem(pqueue, entry, value), ref lookup.Handle); | ||
128 | m_lookupTable[localid] = lookup; | ||
129 | |||
130 | return true; | ||
131 | } | ||
132 | |||
133 | /// <summary> | ||
134 | /// Remove an item from one of the queues. Specifically, it removes the | ||
135 | /// oldest item from the next queue in order to provide fair access to | ||
136 | /// all of the queues | ||
137 | /// </summary> | ||
138 | public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) | ||
139 | { | ||
140 | // If there is anything in priority queue 0, return it first no | ||
141 | // matter what else. Breaks fairness. But very useful. | ||
142 | for (int iq = 0; iq < NumberOfImmediateQueues; iq++) | ||
143 | { | ||
144 | if (m_heaps[iq].Count > 0) | ||
145 | { | ||
146 | MinHeapItem item = m_heaps[iq].RemoveMin(); | ||
147 | m_lookupTable.Remove(item.Value.Entity.LocalId); | ||
148 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); | ||
149 | value = item.Value; | ||
150 | |||
151 | return true; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | // To get the fair queing, we cycle through each of the | ||
156 | // queues when finding an element to dequeue. | ||
157 | // We pull (NumberOfQueues - QueueIndex) items from each queue in order | ||
158 | // to give lower numbered queues a higher priority and higher percentage | ||
159 | // of the bandwidth. | ||
160 | |||
161 | // Check for more items to be pulled from the current queue | ||
162 | if (m_heaps[m_nextQueue].Count > 0 && m_countFromQueue > 0) | ||
163 | { | ||
164 | m_countFromQueue--; | ||
165 | |||
166 | MinHeapItem item = m_heaps[m_nextQueue].RemoveMin(); | ||
167 | m_lookupTable.Remove(item.Value.Entity.LocalId); | ||
168 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); | ||
169 | value = item.Value; | ||
170 | |||
171 | return true; | ||
172 | } | ||
173 | |||
174 | // Find the next non-immediate queue with updates in it | ||
175 | for (int i = 0; i < NumberOfQueues; ++i) | ||
176 | { | ||
177 | m_nextQueue = (uint)((m_nextQueue + 1) % NumberOfQueues); | ||
178 | m_countFromQueue = m_queueCounts[m_nextQueue]; | ||
179 | |||
180 | // if this is one of the immediate queues, just skip it | ||
181 | if (m_nextQueue < NumberOfImmediateQueues) | ||
182 | continue; | ||
183 | |||
184 | if (m_heaps[m_nextQueue].Count > 0) | ||
185 | { | ||
186 | m_countFromQueue--; | ||
187 | |||
188 | MinHeapItem item = m_heaps[m_nextQueue].RemoveMin(); | ||
189 | m_lookupTable.Remove(item.Value.Entity.LocalId); | ||
190 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); | ||
191 | value = item.Value; | ||
192 | |||
193 | return true; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | timeinqueue = 0; | ||
198 | value = default(IEntityUpdate); | ||
199 | return false; | ||
200 | } | ||
201 | |||
202 | /// <summary> | ||
203 | /// Reapply the prioritization function to each of the updates currently | ||
204 | /// stored in the priority queues. | ||
205 | /// </summary | ||
206 | public void Reprioritize(UpdatePriorityHandler handler) | ||
207 | { | ||
208 | MinHeapItem item; | ||
209 | foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values)) | ||
210 | { | ||
211 | if (lookup.Heap.TryGetValue(lookup.Handle, out item)) | ||
212 | { | ||
213 | uint pqueue = item.PriorityQueue; | ||
214 | uint localid = item.Value.Entity.LocalId; | ||
215 | |||
216 | if (handler(ref pqueue, item.Value.Entity)) | ||
217 | { | ||
218 | // unless the priority queue has changed, there is no need to modify | ||
219 | // the entry | ||
220 | pqueue = Util.Clamp<uint>(pqueue, 0, NumberOfQueues - 1); | ||
221 | if (pqueue != item.PriorityQueue) | ||
222 | { | ||
223 | lookup.Heap.Remove(lookup.Handle); | ||
224 | |||
225 | LookupItem litem = lookup; | ||
226 | litem.Heap = m_heaps[pqueue]; | ||
227 | litem.Heap.Add(new MinHeapItem(pqueue, item), ref litem.Handle); | ||
228 | m_lookupTable[localid] = litem; | ||
229 | } | ||
230 | } | ||
231 | else | ||
232 | { | ||
233 | // m_log.WarnFormat("[PQUEUE]: UpdatePriorityHandler returned false for {0}",item.Value.Entity.UUID); | ||
234 | lookup.Heap.Remove(lookup.Handle); | ||
235 | this.m_lookupTable.Remove(localid); | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /// <summary> | ||
242 | /// </summary> | ||
243 | public override string ToString() | ||
244 | { | ||
245 | string s = ""; | ||
246 | for (int i = 0; i < NumberOfQueues; i++) | ||
247 | s += String.Format("{0,7} ",m_heaps[i].Count); | ||
248 | return s; | ||
249 | } | ||
250 | |||
251 | #endregion PublicMethods | ||
252 | |||
253 | #region MinHeapItem | ||
254 | private struct MinHeapItem : IComparable<MinHeapItem> | ||
255 | { | ||
256 | private IEntityUpdate value; | ||
257 | internal IEntityUpdate Value { | ||
258 | get { | ||
259 | return this.value; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | private uint pqueue; | ||
264 | internal uint PriorityQueue { | ||
265 | get { | ||
266 | return this.pqueue; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | private Int32 entrytime; | ||
271 | internal Int32 EntryTime { | ||
272 | get { | ||
273 | return this.entrytime; | ||
274 | } | ||
275 | } | ||
276 | |||
277 | private UInt64 entryorder; | ||
278 | internal UInt64 EntryOrder | ||
279 | { | ||
280 | get { | ||
281 | return this.entryorder; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | internal MinHeapItem(uint pqueue, MinHeapItem other) | ||
286 | { | ||
287 | this.entrytime = other.entrytime; | ||
288 | this.entryorder = other.entryorder; | ||
289 | this.value = other.value; | ||
290 | this.pqueue = pqueue; | ||
291 | } | ||
292 | |||
293 | internal MinHeapItem(uint pqueue, UInt64 entryorder, IEntityUpdate value) | ||
294 | { | ||
295 | this.entrytime = Util.EnvironmentTickCount(); | ||
296 | this.entryorder = entryorder; | ||
297 | this.value = value; | ||
298 | this.pqueue = pqueue; | ||
299 | } | ||
300 | |||
301 | public override string ToString() | ||
302 | { | ||
303 | return String.Format("[{0},{1},{2}]",pqueue,entryorder,value.Entity.LocalId); | ||
304 | } | ||
305 | |||
306 | public int CompareTo(MinHeapItem other) | ||
307 | { | ||
308 | // I'm assuming that the root part of an SOG is added to the update queue | ||
309 | // before the component parts | ||
310 | return Comparer<UInt64>.Default.Compare(this.EntryOrder, other.EntryOrder); | ||
311 | } | ||
312 | } | ||
313 | #endregion | ||
314 | |||
315 | #region LookupItem | ||
316 | private struct LookupItem | ||
317 | { | ||
318 | internal MinHeap<MinHeapItem> Heap; | ||
319 | internal IHandle Handle; | ||
320 | } | ||
321 | #endregion | ||
322 | } | ||
323 | } | ||
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index daf0a25..239ce3d 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs | |||
@@ -369,6 +369,7 @@ namespace OpenSim.Framework | |||
369 | private int m_physPrimMax = 0; | 369 | private int m_physPrimMax = 0; |
370 | private bool m_clampPrimSize = false; | 370 | private bool m_clampPrimSize = false; |
371 | private int m_objectCapacity = 0; | 371 | private int m_objectCapacity = 0; |
372 | private int m_agentCapacity = 0; | ||
372 | private string m_regionType = String.Empty; | 373 | private string m_regionType = String.Empty; |
373 | private RegionLightShareData m_windlight = new RegionLightShareData(); | 374 | private RegionLightShareData m_windlight = new RegionLightShareData(); |
374 | protected uint m_httpPort; | 375 | protected uint m_httpPort; |
@@ -547,6 +548,11 @@ namespace OpenSim.Framework | |||
547 | get { return m_objectCapacity; } | 548 | get { return m_objectCapacity; } |
548 | } | 549 | } |
549 | 550 | ||
551 | public int AgentCapacity | ||
552 | { | ||
553 | get { return m_agentCapacity; } | ||
554 | } | ||
555 | |||
550 | public byte AccessLevel | 556 | public byte AccessLevel |
551 | { | 557 | { |
552 | get { return (byte)Util.ConvertMaturityToAccessLevel((uint)RegionSettings.Maturity); } | 558 | get { return (byte)Util.ConvertMaturityToAccessLevel((uint)RegionSettings.Maturity); } |
@@ -821,6 +827,8 @@ namespace OpenSim.Framework | |||
821 | 827 | ||
822 | m_objectCapacity = config.GetInt("MaxPrims", 15000); | 828 | m_objectCapacity = config.GetInt("MaxPrims", 15000); |
823 | 829 | ||
830 | m_agentCapacity = config.GetInt("MaxAgents", 100); | ||
831 | |||
824 | 832 | ||
825 | // Multi-tenancy | 833 | // Multi-tenancy |
826 | // | 834 | // |
@@ -857,6 +865,9 @@ namespace OpenSim.Framework | |||
857 | if (m_objectCapacity != 0) | 865 | if (m_objectCapacity != 0) |
858 | config.Set("MaxPrims", m_objectCapacity); | 866 | config.Set("MaxPrims", m_objectCapacity); |
859 | 867 | ||
868 | if (m_agentCapacity != 0) | ||
869 | config.Set("MaxAgents", m_agentCapacity); | ||
870 | |||
860 | if (ScopeID != UUID.Zero) | 871 | if (ScopeID != UUID.Zero) |
861 | config.Set("ScopeID", ScopeID.ToString()); | 872 | config.Set("ScopeID", ScopeID.ToString()); |
862 | 873 | ||
@@ -943,6 +954,9 @@ namespace OpenSim.Framework | |||
943 | configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, | 954 | configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, |
944 | "Max objects this sim will hold", m_objectCapacity.ToString(), true); | 955 | "Max objects this sim will hold", m_objectCapacity.ToString(), true); |
945 | 956 | ||
957 | configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, | ||
958 | "Max avatars this sim will hold", m_agentCapacity.ToString(), true); | ||
959 | |||
946 | configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID, | 960 | configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID, |
947 | "Scope ID for this region", ScopeID.ToString(), true); | 961 | "Scope ID for this region", ScopeID.ToString(), true); |
948 | 962 | ||
@@ -1055,6 +1069,9 @@ namespace OpenSim.Framework | |||
1055 | case "object_capacity": | 1069 | case "object_capacity": |
1056 | m_objectCapacity = (int)configuration_result; | 1070 | m_objectCapacity = (int)configuration_result; |
1057 | break; | 1071 | break; |
1072 | case "agent_capacity": | ||
1073 | m_agentCapacity = (int)configuration_result; | ||
1074 | break; | ||
1058 | case "scope_id": | 1075 | case "scope_id": |
1059 | ScopeID = (UUID)configuration_result; | 1076 | ScopeID = (UUID)configuration_result; |
1060 | break; | 1077 | break; |
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index c9d4c93..53a3f17 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs | |||
@@ -29,7 +29,7 @@ namespace OpenSim | |||
29 | { | 29 | { |
30 | public class VersionInfo | 30 | public class VersionInfo |
31 | { | 31 | { |
32 | private const string VERSION_NUMBER = "0.7.1"; | 32 | private const string VERSION_NUMBER = "0.7.2"; |
33 | private const Flavour VERSION_FLAVOUR = Flavour.Dev; | 33 | private const Flavour VERSION_FLAVOUR = Flavour.Dev; |
34 | 34 | ||
35 | public enum Flavour | 35 | public enum Flavour |
diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs index e7f8bfc..76de6be 100644 --- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs +++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs | |||
@@ -115,7 +115,7 @@ namespace OpenSim.Framework.Tests | |||
115 | position2 = new AgentPosition(); | 115 | position2 = new AgentPosition(); |
116 | 116 | ||
117 | Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition"); | 117 | Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition"); |
118 | position2.Unpack(position1.Pack()); | 118 | position2.Unpack(position1.Pack(), null); |
119 | 119 | ||
120 | Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed"); | 120 | Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed"); |
121 | Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed"); | 121 | Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed"); |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 5a5046e..aaa2724 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -1537,6 +1537,23 @@ namespace OpenSim.Framework | |||
1537 | return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); | 1537 | return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); |
1538 | } | 1538 | } |
1539 | 1539 | ||
1540 | // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount | ||
1541 | // Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount(). | ||
1542 | // A positive return value indicates A occured later than B | ||
1543 | public static Int32 EnvironmentTickCountCompare(Int32 tcA, Int32 tcB) | ||
1544 | { | ||
1545 | // A, B and TC are all between 0 and 0x3fffffff | ||
1546 | int tc = EnvironmentTickCount(); | ||
1547 | |||
1548 | if (tc - tcA >= 0) | ||
1549 | tcA += EnvironmentTickCountMask + 1; | ||
1550 | |||
1551 | if (tc - tcB >= 0) | ||
1552 | tcB += EnvironmentTickCountMask + 1; | ||
1553 | |||
1554 | return tcA - tcB; | ||
1555 | } | ||
1556 | |||
1540 | /// <summary> | 1557 | /// <summary> |
1541 | /// Prints the call stack at any given point. Useful for debugging. | 1558 | /// Prints the call stack at any given point. Useful for debugging. |
1542 | /// </summary> | 1559 | /// </summary> |