aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/IClientAPI.cs254
-rwxr-xr-xOpenSim/Framework/MinHeap.cs375
-rw-r--r--OpenSim/Framework/Util.cs23
3 files changed, 627 insertions, 25 deletions
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 9fd043c..9aa3af1 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -517,6 +517,233 @@ namespace OpenSim.Framework
517 public float dwell; 517 public float dwell;
518 } 518 }
519 519
520 public struct SendAvatarData
521 {
522 private ulong m_regionHandle;
523 private string m_firstName;
524 private string m_lastName;
525 private string m_grouptitle;
526 private UUID m_avatarID;
527 private uint m_avatarLocalID;
528 private Vector3 m_Pos;
529 private byte[] m_textureEntry;
530 private uint m_parentID;
531 private Quaternion m_rotation;
532
533 public SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID,
534 uint avatarLocalID,
535 Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation)
536 {
537 this.m_regionHandle = regionHandle;
538 this.m_firstName = firstName;
539 this.m_lastName = lastName;
540 this.m_grouptitle = grouptitle;
541 this.m_avatarID = avatarID;
542 this.m_avatarLocalID = avatarLocalID;
543 this.m_Pos = Pos;
544 this.m_textureEntry = textureEntry;
545 this.m_parentID = parentID;
546 this.m_rotation = rotation;
547 }
548
549 public ulong regionHandle { get { return this.m_regionHandle; } }
550 public string firstName { get { return this.m_firstName; } }
551 public string lastName { get { return this.m_lastName; } }
552 public string grouptitle { get { return this.m_grouptitle; } }
553 public UUID avatarID { get { return this.m_avatarID; } }
554 public uint avatarLocalID { get { return this.m_avatarLocalID; } }
555 public Vector3 Pos { get { return this.m_Pos; } }
556 public byte[] textureEntry { get { return this.m_textureEntry; } }
557 public uint parentID { get { return this.m_parentID; } }
558 public Quaternion rotation { get { return this.m_rotation; } }
559 }
560
561 public struct SendAvatarTerseData
562 {
563 private ulong m_regionHandle;
564 private ushort m_timeDilation;
565 private uint m_localID;
566 private Vector3 m_position;
567 private Vector3 m_velocity;
568 private Quaternion m_rotation;
569 private UUID m_agentid;
570 private double m_priority;
571
572 public SendAvatarTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
573 Vector3 velocity, Quaternion rotation, UUID agentid, double priority)
574 {
575 this.m_regionHandle = regionHandle;
576 this.m_timeDilation = timeDilation;
577 this.m_localID = localID;
578 this.m_position = position;
579 this.m_velocity = velocity;
580 this.m_rotation = rotation;
581 this.m_agentid = agentid;
582 this.m_priority = priority;
583 }
584
585 public ulong regionHandle { get { return this.m_regionHandle; } }
586 public ushort timeDilation { get { return this.m_timeDilation; } }
587 public uint localID { get { return this.m_localID; } }
588 public Vector3 position { get { return this.m_position; } }
589 public Vector3 velocity { get { return this.m_velocity; } }
590 public Quaternion rotation { get { return this.m_rotation; } }
591 public UUID agentid { get { return this.m_agentid; } }
592 public double priority { get { return this.m_priority; } }
593 }
594
595 public struct SendPrimitiveTerseData
596 {
597 private ulong m_regionHandle;
598 private ushort m_timeDilation;
599 private uint m_localID;
600 private Vector3 m_position;
601 private Quaternion m_rotation;
602 private Vector3 m_velocity;
603 private Vector3 m_rotationalvelocity;
604 private byte m_state;
605 private UUID m_AssetId;
606 private UUID m_owner;
607 private int m_attachPoint;
608 private double m_priority;
609
610 public SendPrimitiveTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
611 Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state,
612 UUID AssetId, UUID owner, int attachPoint, double priority)
613 {
614 this.m_regionHandle = regionHandle;
615 this.m_timeDilation = timeDilation;
616 this.m_localID = localID;
617 this.m_position = position;
618 this.m_rotation = rotation;
619 this.m_velocity = velocity;
620 this.m_rotationalvelocity = rotationalvelocity;
621 this.m_state = state;
622 this.m_AssetId = AssetId;
623 this.m_owner = owner;
624 this.m_attachPoint = attachPoint;
625 this.m_priority = priority;
626 }
627
628 public ulong regionHandle { get { return this.m_regionHandle; } }
629 public ushort timeDilation { get { return this.m_timeDilation; } }
630 public uint localID { get { return this.m_localID; } }
631 public Vector3 position { get { return this.m_position; } }
632 public Quaternion rotation { get { return this.m_rotation; } }
633 public Vector3 velocity { get { return this.m_velocity; } }
634 public Vector3 rotationalvelocity { get { return this.m_rotationalvelocity; } }
635 public byte state { get { return this.m_state; } }
636 public UUID AssetId { get { return this.m_AssetId; } }
637 public UUID owner { get { return this.m_owner; } }
638 public int attachPoint { get { return this.m_attachPoint; } }
639 public double priority { get { return this.m_priority; } }
640 }
641
642 public struct SendPrimitiveData
643 {
644 private ulong m_regionHandle;
645 private ushort m_timeDilation;
646 private uint m_localID;
647 private PrimitiveBaseShape m_primShape;
648 private Vector3 m_pos;
649 private Vector3 m_vel;
650 private Vector3 m_acc;
651 private Quaternion m_rotation;
652 private Vector3 m_rvel;
653 private uint m_flags;
654 private UUID m_objectID;
655 private UUID m_ownerID;
656 private string m_text;
657 private byte[] m_color;
658 private uint m_parentID;
659 private byte[] m_particleSystem;
660 private byte m_clickAction;
661 private byte m_material;
662 private byte[] m_textureanim;
663 private bool m_attachment;
664 private uint m_AttachPoint;
665 private UUID m_AssetId;
666 private UUID m_SoundId;
667 private double m_SoundVolume;
668 private byte m_SoundFlags;
669 private double m_SoundRadius;
670 private double m_priority;
671
672 public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
673 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
674 uint flags, UUID objectID, UUID ownerID, string text, byte[] color,
675 uint parentID, byte[] particleSystem, byte clickAction, byte material, double priority) :
676 this(regionHandle, timeDilation, localID, primShape, pos, vel, acc, rotation, rvel, flags, objectID,
677 ownerID, text, color, parentID, particleSystem, clickAction, material, new byte[0], false, 0, UUID.Zero,
678 UUID.Zero, 0, 0, 0, priority) { }
679
680 public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
681 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
682 uint flags,
683 UUID objectID, UUID ownerID, string text, byte[] color, uint parentID,
684 byte[] particleSystem,
685 byte clickAction, byte material, byte[] textureanim, bool attachment,
686 uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags,
687 double SoundRadius, double priority)
688 {
689 this.m_regionHandle = regionHandle;
690 this.m_timeDilation = timeDilation;
691 this.m_localID = localID;
692 this.m_primShape = primShape;
693 this.m_pos = pos;
694 this.m_vel = vel;
695 this.m_acc = acc;
696 this.m_rotation = rotation;
697 this.m_rvel = rvel;
698 this.m_flags = flags;
699 this.m_objectID = objectID;
700 this.m_ownerID = ownerID;
701 this.m_text = text;
702 this.m_color = color;
703 this.m_parentID = parentID;
704 this.m_particleSystem = particleSystem;
705 this.m_clickAction = clickAction;
706 this.m_material = material;
707 this.m_textureanim = textureanim;
708 this.m_attachment = attachment;
709 this.m_AttachPoint = AttachPoint;
710 this.m_AssetId = AssetId;
711 this.m_SoundId = SoundId;
712 this.m_SoundVolume = SoundVolume;
713 this.m_SoundFlags = SoundFlags;
714 this.m_SoundRadius = SoundRadius;
715 this.m_priority = priority;
716 }
717
718 public ulong regionHandle { get { return this.m_regionHandle; } }
719 public ushort timeDilation { get { return this.m_timeDilation; } }
720 public uint localID { get { return this.m_localID; } }
721 public PrimitiveBaseShape primShape { get { return this.m_primShape; } }
722 public Vector3 pos { get { return this.m_pos; } }
723 public Vector3 vel { get { return this.m_vel; } }
724 public Vector3 acc { get { return this.m_acc; } }
725 public Quaternion rotation { get { return this.m_rotation; } }
726 public Vector3 rvel { get { return this.m_rvel; } }
727 public uint flags { get { return this.m_flags; } }
728 public UUID objectID { get { return this.m_objectID; } }
729 public UUID ownerID { get { return this.m_ownerID; } }
730 public string text { get { return this.m_text; } }
731 public byte[] color { get { return this.m_color; } }
732 public uint parentID { get { return this.m_parentID; } }
733 public byte[] particleSystem { get { return this.m_particleSystem; } }
734 public byte clickAction { get { return this.m_clickAction; } }
735 public byte material { get { return this.m_material; } }
736 public byte[] textureanim { get { return this.m_textureanim; } }
737 public bool attachment { get { return this.m_attachment; } }
738 public uint AttachPoint { get { return this.m_AttachPoint; } }
739 public UUID AssetId { get { return this.m_AssetId; } }
740 public UUID SoundId { get { return this.m_SoundId; } }
741 public double SoundVolume { get { return this.m_SoundVolume; } }
742 public byte SoundFlags { get { return this.m_SoundFlags; } }
743 public double SoundRadius { get { return this.m_SoundRadius; } }
744 public double priority { get { return this.m_priority; } }
745 }
746
520 public interface IClientAPI 747 public interface IClientAPI
521 { 748 {
522 Vector3 StartPos { get; set; } 749 Vector3 StartPos { get; set; }
@@ -878,37 +1105,18 @@ namespace OpenSim.Framework
878 void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance); 1105 void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance);
879 void SendPayPrice(UUID objectID, int[] payPrice); 1106 void SendPayPrice(UUID objectID, int[] payPrice);
880 1107
881 void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, 1108 void SendAvatarData(SendAvatarData data);
882 uint avatarLocalID,
883 Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation);
884 1109
885 void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, 1110 void SendAvatarTerseUpdate(SendAvatarTerseData data);
886 Vector3 velocity, Quaternion rotation, UUID agentid);
887 1111
888 void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations); 1112 void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations);
889 1113
890 void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID); 1114 void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID);
891 void SetChildAgentThrottle(byte[] throttle); 1115 void SetChildAgentThrottle(byte[] throttle);
892 1116
893 void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, 1117 void SendPrimitiveToClient(SendPrimitiveData data);
894 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
895 uint flags,
896 UUID objectID, UUID ownerID, string text, byte[] color, uint parentID,
897 byte[] particleSystem,
898 byte clickAction, byte material, byte[] textureanim, bool attachment,
899 uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags,
900 double SoundRadius);
901
902 1118
903 void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, 1119 void SendPrimTerseUpdate(SendPrimitiveTerseData data);
904 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
905 uint flags, UUID objectID, UUID ownerID, string text, byte[] color,
906 uint parentID, byte[] particleSystem, byte clickAction, byte material);
907
908
909 void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
910 Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state,
911 UUID AssetId, UUID owner, int attachPoint);
912 1120
913 void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, 1121 void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
914 List<InventoryFolderBase> folders, bool fetchFolders, 1122 List<InventoryFolderBase> folders, bool fetchFolders,
diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs
new file mode 100755
index 0000000..ad39bbc
--- /dev/null
+++ b/OpenSim/Framework/MinHeap.cs
@@ -0,0 +1,375 @@
1using System;
2using System.Threading;
3using System.Collections;
4using System.Collections.Generic;
5using System.Runtime.InteropServices;
6
7namespace OpenSim.Framework
8{
9 public interface IHandle { }
10
11 [Serializable, ComVisible(false)]
12 public class MinHeap<T> : ICollection<T>, ICollection
13 {
14 private class Handle : IHandle
15 {
16 internal int index = -1;
17 internal MinHeap<T> heap = null;
18
19 internal void Clear()
20 {
21 this.index = -1;
22 this.heap = null;
23 }
24 }
25
26 private struct HeapItem
27 {
28 internal T value;
29 internal Handle handle;
30
31 internal HeapItem(T value, Handle handle)
32 {
33 this.value = value;
34 this.handle = handle;
35 }
36
37 internal void Clear()
38 {
39 this.value = default(T);
40 if (this.handle != null)
41 {
42 this.handle.Clear();
43 this.handle = null;
44 }
45 }
46 }
47
48 public const int DEFAULT_CAPACITY = 4;
49
50 private HeapItem[] items;
51 private int size;
52 private object sync_root;
53 private int version;
54
55 private Comparison<T> comparison;
56
57 public MinHeap() : this(DEFAULT_CAPACITY, Comparer<T>.Default) { }
58 public MinHeap(int capacity) : this(capacity, Comparer<T>.Default) { }
59 public MinHeap(IComparer<T> comparer) : this(DEFAULT_CAPACITY, comparer) { }
60 public MinHeap(int capacity, IComparer<T> comparer) :
61 this(capacity, new Comparison<T>(comparer.Compare)) { }
62 public MinHeap(Comparison<T> comparison) : this(DEFAULT_CAPACITY, comparison) { }
63 public MinHeap(int capacity, Comparison<T> comparison)
64 {
65 this.items = new HeapItem[capacity];
66 this.comparison = comparison;
67 this.size = this.version = 0;
68 }
69
70 public int Count { get { return this.size; } }
71
72 public bool IsReadOnly { get { return false; } }
73
74 public bool IsSynchronized { get { return false; } }
75
76 public T this[IHandle key]
77 {
78 get
79 {
80 Handle handle = ValidateThisHandle(key);
81 return this.items[handle.index].value;
82 }
83
84 set
85 {
86 Handle handle = ValidateThisHandle(key);
87 this.items[handle.index].value = value;
88 if (!BubbleUp(handle.index))
89 BubbleDown(handle.index);
90 }
91 }
92
93 public object SyncRoot
94 {
95 get
96 {
97 if (this.sync_root == null)
98 Interlocked.CompareExchange<object>(ref this.sync_root, new object(), null);
99 return this.sync_root;
100 }
101 }
102
103 private Handle ValidateHandle(IHandle ihandle)
104 {
105 if (ihandle == null)
106 throw new ArgumentNullException("handle");
107 Handle handle = ihandle as Handle;
108 if (handle == null)
109 throw new InvalidOperationException("handle is not valid");
110 return handle;
111 }
112
113 private Handle ValidateThisHandle(IHandle ihandle)
114 {
115 Handle handle = ValidateHandle(ihandle);
116 if (!object.ReferenceEquals(handle.heap, this))
117 throw new InvalidOperationException("handle is not valid for this heap");
118 if (handle.index < 0)
119 throw new InvalidOperationException("handle is not associated to a value");
120 return handle;
121 }
122
123 private void Set(HeapItem item, int index)
124 {
125 this.items[index] = item;
126 if (item.handle != null)
127 item.handle.index = index;
128 }
129
130 private bool BubbleUp(int index)
131 {
132 HeapItem item = this.items[index];
133 int current, parent;
134
135 for (current = index, parent = (current - 1) / 2;
136 (current > 0) && (this.comparison(this.items[parent].value, item.value)) > 0;
137 current = parent, parent = (current - 1) / 2)
138 {
139 Set(this.items[parent], current);
140 }
141
142 if (current != index)
143 {
144 Set(item, current);
145 ++this.version;
146 return true;
147 }
148 return false;
149 }
150
151 private void BubbleDown(int index)
152 {
153 HeapItem item = this.items[index];
154 int current, child;
155
156 for (current = index, child = (2 * current) + 1;
157 current < this.size / 2;
158 current = child, child = (2 * current) + 1)
159 {
160 if ((child < this.size - 1) && this.comparison(this.items[child].value, this.items[child + 1].value) > 0)
161 ++child;
162 if (this.comparison(this.items[child].value, item.value) >= 0)
163 break;
164 Set(this.items[child], current);
165 }
166
167 if (current != index)
168 {
169 Set(item, current);
170 ++this.version;
171 }
172 }
173
174 public bool TryGetValue(IHandle key, out T value)
175 {
176 Handle handle = ValidateHandle(key);
177 if (handle.index > -1)
178 {
179 value = this.items[handle.index].value;
180 return true;
181 }
182 value = default(T);
183 return false;
184 }
185
186 public bool ContainsHandle(IHandle ihandle)
187 {
188 Handle handle = ValidateHandle(ihandle);
189 return object.ReferenceEquals(handle.heap, this) && handle.index > -1;
190 }
191
192 public void Add(T value, ref IHandle handle)
193 {
194 if (handle == null)
195 handle = new Handle();
196 Add(value, handle);
197 }
198
199 public void Add(T value, IHandle ihandle)
200 {
201 if (this.size == this.items.Length)
202 {
203 int capacity = (int)((this.items.Length * 200L) / 100L);
204 if (capacity < (this.items.Length + DEFAULT_CAPACITY))
205 capacity = this.items.Length + DEFAULT_CAPACITY;
206 Array.Resize<HeapItem>(ref this.items, capacity);
207 }
208
209 Handle handle = null;
210 if (ihandle != null)
211 {
212 handle = ValidateHandle(ihandle);
213 handle.heap = this;
214 }
215
216 HeapItem item = new MinHeap<T>.HeapItem(value, handle);
217
218 Set(item, this.size);
219 BubbleUp(this.size++);
220 }
221
222 public void Add(T value)
223 {
224 Add(value, null);
225 }
226
227 public T Min()
228 {
229 if (this.size == 0)
230 throw new InvalidOperationException("Heap is empty");
231
232 return this.items[0].value;
233 }
234
235 public void Clear()
236 {
237 for (int index = 0; index < this.size; ++index)
238 this.items[index].Clear();
239 this.size = 0;
240 ++this.version;
241 }
242
243 public void TrimExcess()
244 {
245 int length = (int)(this.items.Length * 0.9);
246 if (this.size < length)
247 Array.Resize<HeapItem>(ref this.items, Math.Min(this.size, DEFAULT_CAPACITY));
248 }
249
250 private void RemoveAt(int index)
251 {
252 if (this.size == 0)
253 throw new InvalidOperationException("Heap is empty");
254 if (index >= this.size)
255 throw new ArgumentOutOfRangeException("index");
256
257 this.items[index].Clear();
258 if (--this.size > 0 && index != this.size)
259 {
260 Set(this.items[this.size], index);
261 if (!BubbleUp(index))
262 BubbleDown(index);
263 }
264 }
265
266 public T RemoveMin()
267 {
268 if (this.size == 0)
269 throw new InvalidOperationException("Heap is empty");
270
271 HeapItem item = this.items[0];
272 RemoveAt(0);
273 return item.value;
274 }
275
276 public T Remove(IHandle ihandle)
277 {
278 Handle handle = ValidateThisHandle(ihandle);
279 HeapItem item = this.items[handle.index];
280 RemoveAt(handle.index);
281 return item.value;
282 }
283
284 private int GetIndex(T value)
285 {
286 EqualityComparer<T> comparer = EqualityComparer<T>.Default;
287 int index;
288
289 for (index = 0; index < this.size; ++index)
290 {
291 if (comparer.Equals(this.items[index].value, value))
292 return index;
293 }
294 return -1;
295 }
296
297 public bool Contains(T value)
298 {
299 return GetIndex(value) != -1;
300 }
301
302 public bool Remove(T value)
303 {
304 int index = GetIndex(value);
305 if (index != -1)
306 {
307 RemoveAt(index);
308 return true;
309 }
310 return false;
311 }
312
313 public void CopyTo(T[] array, int index)
314 {
315 if (array == null)
316 throw new ArgumentNullException("array");
317 if (array.Rank != 1)
318 throw new ArgumentException("Multidimensional array not supported");
319 if (array.GetLowerBound(0) != 0)
320 throw new ArgumentException("Non-zero lower bound array not supported");
321
322 int length = array.Length;
323 if ((index < 0) || (index > length))
324 throw new ArgumentOutOfRangeException("index");
325 if ((length - index) < this.size)
326 throw new ArgumentException("Not enough space available in array starting at index");
327
328 for (int i = 0; i < this.size; ++i)
329 array[index + i] = this.items[i].value;
330 }
331
332 public void CopyTo(Array array, int index)
333 {
334 if (array == null)
335 throw new ArgumentNullException("array");
336 if (array.Rank != 1)
337 throw new ArgumentException("Multidimensional array not supported");
338 if (array.GetLowerBound(0) != 0)
339 throw new ArgumentException("Non-zero lower bound array not supported");
340
341 int length = array.Length;
342 if ((index < 0) || (index > length))
343 throw new ArgumentOutOfRangeException("index");
344 if ((length - index) < this.size)
345 throw new ArgumentException("Not enough space available in array starting at index");
346
347 try
348 {
349 for (int i = 0; i < this.size; ++i)
350 array.SetValue(this.items[i].value, index + i);
351 }
352 catch (ArrayTypeMismatchException)
353 {
354 throw new ArgumentException("Invalid array type");
355 }
356 }
357
358 public IEnumerator<T> GetEnumerator()
359 {
360 int version = this.version;
361
362 for (int index = 0; index < this.size; ++index)
363 {
364 if (version != this.version)
365 throw new InvalidOperationException("Heap was modified while enumerating");
366 yield return this.items[index].value;
367 }
368 }
369
370 IEnumerator IEnumerable.GetEnumerator()
371 {
372 return GetEnumerator();
373 }
374 }
375}
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 38729c6..3203fc1 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -44,6 +44,7 @@ using System.Xml;
44using log4net; 44using log4net;
45using Nini.Config; 45using Nini.Config;
46using Nwc.XmlRpc; 46using Nwc.XmlRpc;
47using BclExtras;
47using OpenMetaverse; 48using OpenMetaverse;
48using OpenMetaverse.StructuredData; 49using OpenMetaverse.StructuredData;
49 50
@@ -1269,14 +1270,32 @@ namespace OpenSim.Framework
1269 1270
1270 #region FireAndForget Threading Pattern 1271 #region FireAndForget Threading Pattern
1271 1272
1273 /// <summary>
1274 /// Created to work around a limitation in Mono with nested delegates
1275 /// </summary>
1276 private class FireAndForgetWrapper
1277 {
1278 public void FireAndForget(System.Threading.WaitCallback callback)
1279 {
1280 callback.BeginInvoke(null, EndFireAndForget, callback);
1281 }
1282
1283 public void FireAndForget(System.Threading.WaitCallback callback, object obj)
1284 {
1285 callback.BeginInvoke(obj, EndFireAndForget, callback);
1286 }
1287 }
1288
1272 public static void FireAndForget(System.Threading.WaitCallback callback) 1289 public static void FireAndForget(System.Threading.WaitCallback callback)
1273 { 1290 {
1274 callback.BeginInvoke(null, EndFireAndForget, callback); 1291 FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>();
1292 wrapper.FireAndForget(callback);
1275 } 1293 }
1276 1294
1277 public static void FireAndForget(System.Threading.WaitCallback callback, object obj) 1295 public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
1278 { 1296 {
1279 callback.BeginInvoke(obj, EndFireAndForget, callback); 1297 FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>();
1298 wrapper.FireAndForget(callback, obj);
1280 } 1299 }
1281 1300
1282 private static void EndFireAndForget(IAsyncResult ar) 1301 private static void EndFireAndForget(IAsyncResult ar)