aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs224
1 files changed, 179 insertions, 45 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 82a2cdd..93fdeef 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -321,11 +321,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
321 321
322 private int m_cachedTextureSerial; 322 private int m_cachedTextureSerial;
323 private Timer m_avatarTerseUpdateTimer; 323 private Timer m_avatarTerseUpdateTimer;
324 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 324 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates_ =
325 new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
325 private Timer m_primTerseUpdateTimer; 326 private Timer m_primTerseUpdateTimer;
326 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 327 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates_ =
328 new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
327 private Timer m_primFullUpdateTimer; 329 private Timer m_primFullUpdateTimer;
328 private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = new List<ObjectUpdatePacket.ObjectDataBlock>(); 330 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates_ =
331 new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>();
329 private int m_moneyBalance; 332 private int m_moneyBalance;
330 private int m_animationSequenceNumber = 1; 333 private int m_animationSequenceNumber = 1;
331 private bool m_SendLogoutPacketWhenClosing = true; 334 private bool m_SendLogoutPacketWhenClosing = true;
@@ -3435,16 +3438,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3435 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = 3438 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock =
3436 CreateAvatarImprovedBlock(localID, position, velocity,rotation); 3439 CreateAvatarImprovedBlock(localID, position, velocity,rotation);
3437 3440
3438 lock (m_avatarTerseUpdates) 3441 lock (m_avatarTerseUpdates_.SyncRoot)
3439 { 3442 {
3440 m_avatarTerseUpdates.Add(terseBlock); 3443 m_avatarTerseUpdates_.Enqueue(DateTime.Now.ToOADate(), terseBlock, localID);
3441 3444
3442 // If packet is full or own movement packet, send it. 3445 // If packet is full or own movement packet, send it.
3443 if (m_avatarTerseUpdates.Count >= m_avatarTerseUpdatesPerPacket) 3446 if (m_avatarTerseUpdates_.Count >= m_avatarTerseUpdatesPerPacket)
3444 { 3447 {
3445 ProcessAvatarTerseUpdates(this, null); 3448 ProcessAvatarTerseUpdates(this, null);
3446 } 3449 }
3447 else if (m_avatarTerseUpdates.Count == 1) 3450 else if (m_avatarTerseUpdates_.Count == 1)
3448 { 3451 {
3449 lock (m_avatarTerseUpdateTimer) 3452 lock (m_avatarTerseUpdateTimer)
3450 m_avatarTerseUpdateTimer.Start(); 3453 m_avatarTerseUpdateTimer.Start();
@@ -3454,7 +3457,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3454 3457
3455 private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) 3458 private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e)
3456 { 3459 {
3457 lock (m_avatarTerseUpdates) 3460 lock (m_avatarTerseUpdates_.SyncRoot)
3458 { 3461 {
3459 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3462 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3460 3463
@@ -3465,8 +3468,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3465 (ushort)(Scene.TimeDilation * ushort.MaxValue); 3468 (ushort)(Scene.TimeDilation * ushort.MaxValue);
3466 3469
3467 int max = m_avatarTerseUpdatesPerPacket; 3470 int max = m_avatarTerseUpdatesPerPacket;
3468 if (max > m_avatarTerseUpdates.Count) 3471 if (max > m_avatarTerseUpdates_.Count)
3469 max = m_avatarTerseUpdates.Count; 3472 max = m_avatarTerseUpdates_.Count;
3470 3473
3471 int count = 0; 3474 int count = 0;
3472 int size = 0; 3475 int size = 0;
@@ -3474,30 +3477,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3474 byte[] zerobuffer = new byte[1024]; 3477 byte[] zerobuffer = new byte[1024];
3475 byte[] blockbuffer = new byte[1024]; 3478 byte[] blockbuffer = new byte[1024];
3476 3479
3480 Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> updates = new Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
3481
3477 for (count = 0 ; count < max ; count++) 3482 for (count = 0 ; count < max ; count++)
3478 { 3483 {
3479 int length = 0; 3484 int length = 0;
3480 m_avatarTerseUpdates[count].ToBytes(blockbuffer, ref length); 3485 m_avatarTerseUpdates_.Peek().ToBytes(blockbuffer, ref length);
3481 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); 3486 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer);
3482 if (size + length > Packet.MTU) 3487 if (size + length > Packet.MTU)
3483 break; 3488 break;
3484 size += length; 3489 size += length;
3490 updates.Enqueue(m_avatarTerseUpdates_.Dequeue());
3485 } 3491 }
3486 3492
3487 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; 3493 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
3488 3494
3489 for (int i = 0 ; i < count ; i++) 3495 for (int i = 0 ; i < count ; i++)
3490 { 3496 terse.ObjectData[i] = updates.Dequeue();
3491 terse.ObjectData[i] = m_avatarTerseUpdates[0];
3492 m_avatarTerseUpdates.RemoveAt(0);
3493 }
3494 3497
3495 terse.Header.Reliable = false; 3498 terse.Header.Reliable = false;
3496 terse.Header.Zerocoded = true; 3499 terse.Header.Zerocoded = true;
3497 // FIXME: Move this to ThrottleOutPacketType.State when the real prioritization code is committed 3500 // FIXME: Move this to ThrottleOutPacketType.State when the real prioritization code is committed
3498 OutPacket(terse, ThrottleOutPacketType.Task); 3501 OutPacket(terse, ThrottleOutPacketType.Task);
3499 3502
3500 if (m_avatarTerseUpdates.Count == 0) 3503 if (m_avatarTerseUpdates_.Count == 0)
3501 { 3504 {
3502 lock (m_avatarTerseUpdateTimer) 3505 lock (m_avatarTerseUpdateTimer)
3503 m_avatarTerseUpdateTimer.Stop(); 3506 m_avatarTerseUpdateTimer.Stop();
@@ -3660,14 +3663,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3660 objectData.TextureAnim = textureanim; 3663 objectData.TextureAnim = textureanim;
3661 } 3664 }
3662 3665
3663 lock (m_primFullUpdates) 3666 lock (m_primFullUpdates_.SyncRoot)
3664 { 3667 {
3665 if (m_primFullUpdates.Count == 0) 3668 if (m_primFullUpdates_.Count == 0)
3666 m_primFullUpdateTimer.Start(); 3669 m_primFullUpdateTimer.Start();
3667 3670
3668 m_primFullUpdates.Add(objectData); 3671 m_primFullUpdates_.Enqueue(DateTime.Now.ToOADate(), objectData, localID);
3669 3672
3670 if (m_primFullUpdates.Count >= m_primFullUpdatesPerPacket) 3673 if (m_primFullUpdates_.Count >= m_primFullUpdatesPerPacket)
3671 ProcessPrimFullUpdates(this, null); 3674 ProcessPrimFullUpdates(this, null);
3672 } 3675 }
3673 } 3676 }
@@ -3690,9 +3693,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3690 3693
3691 void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) 3694 void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e)
3692 { 3695 {
3693 lock (m_primFullUpdates) 3696 lock (m_primFullUpdates_.SyncRoot)
3694 { 3697 {
3695 if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) 3698 if (m_primFullUpdates_.Count == 0 && m_primFullUpdateTimer.Enabled)
3696 { 3699 {
3697 lock (m_primFullUpdateTimer) 3700 lock (m_primFullUpdateTimer)
3698 m_primFullUpdateTimer.Stop(); 3701 m_primFullUpdateTimer.Stop();
@@ -3709,7 +3712,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3709 outPacket.RegionData.TimeDilation = 3712 outPacket.RegionData.TimeDilation =
3710 (ushort)(Scene.TimeDilation * ushort.MaxValue); 3713 (ushort)(Scene.TimeDilation * ushort.MaxValue);
3711 3714
3712 int max = m_primFullUpdates.Count; 3715 int max = m_primFullUpdates_.Count;
3713 if (max > m_primFullUpdatesPerPacket) 3716 if (max > m_primFullUpdatesPerPacket)
3714 max = m_primFullUpdatesPerPacket; 3717 max = m_primFullUpdatesPerPacket;
3715 3718
@@ -3719,29 +3722,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3719 byte[] zerobuffer = new byte[1024]; 3722 byte[] zerobuffer = new byte[1024];
3720 byte[] blockbuffer = new byte[1024]; 3723 byte[] blockbuffer = new byte[1024];
3721 3724
3725 Queue<ObjectUpdatePacket.ObjectDataBlock> updates = new Queue<ObjectUpdatePacket.ObjectDataBlock>();
3726
3722 for (count = 0 ; count < max ; count++) 3727 for (count = 0 ; count < max ; count++)
3723 { 3728 {
3724 int length = 0; 3729 int length = 0;
3725 m_primFullUpdates[count].ToBytes(blockbuffer, ref length); 3730 m_primFullUpdates_.Peek().ToBytes(blockbuffer, ref length);
3726 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); 3731 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer);
3727 if (size + length > Packet.MTU) 3732 if (size + length > Packet.MTU)
3728 break; 3733 break;
3729 size += length; 3734 size += length;
3735 updates.Enqueue(m_primFullUpdates_.Dequeue());
3730 } 3736 }
3731 3737
3732 outPacket.ObjectData = 3738 outPacket.ObjectData =
3733 new ObjectUpdatePacket.ObjectDataBlock[count]; 3739 new ObjectUpdatePacket.ObjectDataBlock[count];
3734 3740
3735 for (int index = 0 ; index < count ; index++) 3741 for (int index = 0 ; index < count ; index++)
3736 { 3742 outPacket.ObjectData[index] = updates.Dequeue();
3737 outPacket.ObjectData[index] = m_primFullUpdates[0];
3738 m_primFullUpdates.RemoveAt(0);
3739 }
3740 3743
3741 outPacket.Header.Zerocoded = true; 3744 outPacket.Header.Zerocoded = true;
3742 OutPacket(outPacket, ThrottleOutPacketType.State); 3745 OutPacket(outPacket, ThrottleOutPacketType.State);
3743 3746
3744 if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) 3747 if (m_primFullUpdates_.Count == 0 && m_primFullUpdateTimer.Enabled)
3745 lock (m_primFullUpdateTimer) 3748 lock (m_primFullUpdateTimer)
3746 m_primFullUpdateTimer.Stop(); 3749 m_primFullUpdateTimer.Stop();
3747 } 3750 }
@@ -3763,23 +3766,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3763 CreatePrimImprovedBlock(localID, position, rotation, 3766 CreatePrimImprovedBlock(localID, position, rotation,
3764 velocity, rotationalvelocity, state); 3767 velocity, rotationalvelocity, state);
3765 3768
3766 lock (m_primTerseUpdates) 3769 lock (m_primTerseUpdates_.SyncRoot)
3767 { 3770 {
3768 if (m_primTerseUpdates.Count == 0) 3771 if (m_primTerseUpdates_.Count == 0)
3769 m_primTerseUpdateTimer.Start(); 3772 m_primTerseUpdateTimer.Start();
3770 3773
3771 m_primTerseUpdates.Add(objectData); 3774 m_primTerseUpdates_.Enqueue(DateTime.Now.ToOADate(), objectData, localID);
3772 3775
3773 if (m_primTerseUpdates.Count >= m_primTerseUpdatesPerPacket) 3776 if (m_primTerseUpdates_.Count >= m_primTerseUpdatesPerPacket)
3774 ProcessPrimTerseUpdates(this, null); 3777 ProcessPrimTerseUpdates(this, null);
3775 } 3778 }
3776 } 3779 }
3777 3780
3778 void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) 3781 void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e)
3779 { 3782 {
3780 lock (m_primTerseUpdates) 3783 lock (m_primTerseUpdates_.SyncRoot)
3781 { 3784 {
3782 if (m_primTerseUpdates.Count == 0) 3785 if (m_primTerseUpdates_.Count == 0)
3783 { 3786 {
3784 lock (m_primTerseUpdateTimer) 3787 lock (m_primTerseUpdateTimer)
3785 m_primTerseUpdateTimer.Stop(); 3788 m_primTerseUpdateTimer.Stop();
@@ -3797,7 +3800,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3797 outPacket.RegionData.TimeDilation = 3800 outPacket.RegionData.TimeDilation =
3798 (ushort)(Scene.TimeDilation * ushort.MaxValue); 3801 (ushort)(Scene.TimeDilation * ushort.MaxValue);
3799 3802
3800 int max = m_primTerseUpdates.Count; 3803 int max = m_primTerseUpdates_.Count;
3801 if (max > m_primTerseUpdatesPerPacket) 3804 if (max > m_primTerseUpdatesPerPacket)
3802 max = m_primTerseUpdatesPerPacket; 3805 max = m_primTerseUpdatesPerPacket;
3803 3806
@@ -3807,14 +3810,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3807 byte[] zerobuffer = new byte[1024]; 3810 byte[] zerobuffer = new byte[1024];
3808 byte[] blockbuffer = new byte[1024]; 3811 byte[] blockbuffer = new byte[1024];
3809 3812
3813 Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> updates = new Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
3814
3810 for (count = 0 ; count < max ; count++) 3815 for (count = 0 ; count < max ; count++)
3811 { 3816 {
3812 int length = 0; 3817 int length = 0;
3813 m_primTerseUpdates[count].ToBytes(blockbuffer, ref length); 3818 m_primTerseUpdates_.Peek().ToBytes(blockbuffer, ref length);
3814 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); 3819 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer);
3815 if (size + length > Packet.MTU) 3820 if (size + length > Packet.MTU)
3816 break; 3821 break;
3817 size += length; 3822 size += length;
3823 updates.Enqueue(m_primTerseUpdates_.Dequeue());
3818 } 3824 }
3819 3825
3820 outPacket.ObjectData = 3826 outPacket.ObjectData =
@@ -3822,16 +3828,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3822 ObjectDataBlock[count]; 3828 ObjectDataBlock[count];
3823 3829
3824 for (int index = 0 ; index < count ; index++) 3830 for (int index = 0 ; index < count ; index++)
3825 { 3831 outPacket.ObjectData[index] = updates.Dequeue();
3826 outPacket.ObjectData[index] = m_primTerseUpdates[0];
3827 m_primTerseUpdates.RemoveAt(0);
3828 }
3829 3832
3830 outPacket.Header.Reliable = false; 3833 outPacket.Header.Reliable = false;
3831 outPacket.Header.Zerocoded = true; 3834 outPacket.Header.Zerocoded = true;
3832 OutPacket(outPacket, ThrottleOutPacketType.State); 3835 OutPacket(outPacket, ThrottleOutPacketType.State);
3833 3836
3834 if (m_primTerseUpdates.Count == 0) 3837 if (m_primTerseUpdates_.Count == 0)
3835 lock (m_primTerseUpdateTimer) 3838 lock (m_primTerseUpdateTimer)
3836 m_primTerseUpdateTimer.Stop(); 3839 m_primTerseUpdateTimer.Stop();
3837 } 3840 }
@@ -3839,15 +3842,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3839 3842
3840 public void FlushPrimUpdates() 3843 public void FlushPrimUpdates()
3841 { 3844 {
3842 while (m_primFullUpdates.Count > 0) 3845 while (m_primFullUpdates_.Count > 0)
3843 { 3846 {
3844 ProcessPrimFullUpdates(this, null); 3847 ProcessPrimFullUpdates(this, null);
3845 } 3848 }
3846 while (m_primTerseUpdates.Count > 0) 3849 while (m_primTerseUpdates_.Count > 0)
3847 { 3850 {
3848 ProcessPrimTerseUpdates(this, null); 3851 ProcessPrimTerseUpdates(this, null);
3849 } 3852 }
3850 while (m_avatarTerseUpdates.Count > 0) 3853 while (m_avatarTerseUpdates_.Count > 0)
3851 { 3854 {
3852 ProcessAvatarTerseUpdates(this, null); 3855 ProcessAvatarTerseUpdates(this, null);
3853 } 3856 }
@@ -10578,5 +10581,136 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10578 pack.TextureData.TextureID = textureID; 10581 pack.TextureData.TextureID = textureID;
10579 OutPacket(pack, ThrottleOutPacketType.Task); 10582 OutPacket(pack, ThrottleOutPacketType.Task);
10580 } 10583 }
10584
10585 #region PriorityQueue
10586 private class PriorityQueue<TPriority, TValue>
10587 {
10588 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1];
10589 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>();
10590 private Comparison<TPriority> comparison;
10591 private object sync_root = new object();
10592
10593 internal PriorityQueue() :
10594 this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<TPriority>.Default) { }
10595 internal PriorityQueue(int capacity) :
10596 this(capacity, Comparer<TPriority>.Default) { }
10597 internal PriorityQueue(IComparer<TPriority> comparer) :
10598 this(new Comparison<TPriority>(comparer.Compare)) { }
10599 internal PriorityQueue(Comparison<TPriority> comparison) :
10600 this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, comparison) { }
10601 internal PriorityQueue(int capacity, IComparer<TPriority> comparer) :
10602 this(capacity, new Comparison<TPriority>(comparer.Compare)) { }
10603 internal PriorityQueue(int capacity, Comparison<TPriority> comparison)
10604 {
10605 for (int i = 0; i < heaps.Length; ++i)
10606 heaps[i] = new MinHeap<MinHeapItem>(capacity);
10607 this.comparison = comparison;
10608 }
10609
10610 internal object SyncRoot { get { return this.sync_root; } }
10611 internal int Count
10612 {
10613 get
10614 {
10615 int count = 0;
10616 for (int i = 0; i < heaps.Length; ++i)
10617 count = heaps[i].Count;
10618 return count;
10619 }
10620 }
10621
10622 internal bool Enqueue(TPriority priority, TValue value, uint local_id)
10623 {
10624 LookupItem item;
10625
10626 if (lookup_table.TryGetValue(local_id, out item))
10627 {
10628 item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.comparison);
10629 return false;
10630 }
10631 else
10632 {
10633 item.Heap = heaps[0];
10634 item.Heap.Add(new MinHeapItem(priority, value, local_id, this.comparison), ref item.Handle);
10635 lookup_table.Add(local_id, item);
10636 return true;
10637 }
10638 }
10639
10640 internal TValue Peek()
10641 {
10642 for (int i = 0; i < heaps.Length; ++i)
10643 if (heaps[i].Count > 0)
10644 return heaps[i].Min().Value;
10645 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
10646 }
10647
10648 internal TValue Dequeue()
10649 {
10650 for (int i = 0; i < heaps.Length; ++i)
10651 {
10652 if (heaps[i].Count > 0)
10653 {
10654 MinHeapItem item = heaps[i].RemoveMin();
10655 lookup_table.Remove(item.LocalID);
10656 return item.Value;
10657 }
10658 }
10659 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
10660 }
10661
10662 #region MinHeapItem
10663 private struct MinHeapItem : IComparable<MinHeapItem>
10664 {
10665 private TPriority priority;
10666 private TValue value;
10667 private uint local_id;
10668 private Comparison<TPriority> comparison;
10669
10670 internal MinHeapItem(TPriority priority, TValue value, uint local_id) :
10671 this(priority, value, local_id, Comparer<TPriority>.Default) { }
10672 internal MinHeapItem(TPriority priority, TValue value, uint local_id, IComparer<TPriority> comparer) :
10673 this(priority, value, local_id, new Comparison<TPriority>(comparer.Compare)) { }
10674 internal MinHeapItem(TPriority priority, TValue value, uint local_id, Comparison<TPriority> comparison)
10675 {
10676 this.priority = priority;
10677 this.value = value;
10678 this.local_id = local_id;
10679 this.comparison = comparison;
10680 }
10681
10682 internal TPriority Priority { get { return this.priority; } }
10683 internal TValue Value { get { return this.value; } }
10684 internal uint LocalID { get { return this.local_id; } }
10685
10686 public override string ToString()
10687 {
10688 StringBuilder sb = new StringBuilder();
10689 sb.Append("[");
10690 if (this.priority != null)
10691 sb.Append(this.priority.ToString());
10692 sb.Append(",");
10693 if (this.value != null)
10694 sb.Append(this.value.ToString());
10695 sb.Append("]");
10696 return sb.ToString();
10697 }
10698
10699 public int CompareTo(MinHeapItem other)
10700 {
10701 return this.comparison(this.priority, other.priority);
10702 }
10703 }
10704 #endregion
10705
10706 #region LookupItem
10707 private struct LookupItem {
10708 internal MinHeap<MinHeapItem> Heap;
10709 internal IHandle Handle;
10710 }
10711 #endregion
10712 }
10713 #endregion
10714
10581 } 10715 }
10582} 10716}