diff options
author | UbitUmarov | 2018-02-23 14:52:34 +0000 |
---|---|---|
committer | UbitUmarov | 2018-02-23 14:52:34 +0000 |
commit | 2129d941acbc5f83aca4dc4c30a62d3226888136 (patch) | |
tree | e12f2391978c923ef780f558ee5a32d857ee9124 /OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs | |
parent | Merge branch 'master' into httptests (diff) | |
download | opensim-SC-2129d941acbc5f83aca4dc4c30a62d3226888136.zip opensim-SC-2129d941acbc5f83aca4dc4c30a62d3226888136.tar.gz opensim-SC-2129d941acbc5f83aca4dc4c30a62d3226888136.tar.bz2 opensim-SC-2129d941acbc5f83aca4dc4c30a62d3226888136.tar.xz |
rename XMREngine as Yengine (still not all done), big mess source formating changes, move state files to proper folder, fix a source file locking on errors, more changes for cross platform including from Mike,... yes yes i know a messy commit
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs (renamed from OpenSim/Region/ScriptEngine/XMREngine/XMRArray.cs) | 384 |
1 files changed, 223 insertions, 161 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRArray.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs index 36d95d3..b797224 100644 --- a/OpenSim/Region/ScriptEngine/XMREngine/XMRArray.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs | |||
@@ -40,12 +40,13 @@ using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | |||
40 | 40 | ||
41 | // This class exists in the main app domain | 41 | // This class exists in the main app domain |
42 | // | 42 | // |
43 | namespace OpenSim.Region.ScriptEngine.XMREngine | 43 | namespace OpenSim.Region.ScriptEngine.Yengine |
44 | { | 44 | { |
45 | /** | 45 | /** |
46 | * @brief Array objects. | 46 | * @brief Array objects. |
47 | */ | 47 | */ |
48 | public class XMR_Array { | 48 | public class XMR_Array |
49 | { | ||
49 | private const int EMPTYHEAP = 64; | 50 | private const int EMPTYHEAP = 64; |
50 | private const int ENTRYHEAP = 24; | 51 | private const int ENTRYHEAP = 24; |
51 | 52 | ||
@@ -53,36 +54,40 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
53 | // false: array[0..arrayValid-1] is all there is | 54 | // false: array[0..arrayValid-1] is all there is |
54 | private SortedDictionary<object, object> dnary; | 55 | private SortedDictionary<object, object> dnary; |
55 | private SortedDictionary<object, object>.Enumerator enumr; | 56 | private SortedDictionary<object, object>.Enumerator enumr; |
56 | // enumerator used to fill 'array' past arrayValid to end of dictionary | 57 | // enumerator used to fill 'array' past arrayValid to end of dictionary |
57 | private int arrayValid; // number of elements in 'array' that have been filled in | 58 | private int arrayValid; // number of elements in 'array' that have been filled in |
58 | private KeyValuePair<object, object>[] array; // list of kvp's that have been returned by ForEach() since last modification | 59 | private KeyValuePair<object, object>[] array; // list of kvp's that have been returned by ForEach() since last modification |
59 | private XMRInstAbstract inst; // script instance debited with heap use | 60 | private XMRInstAbstract inst; // script instance debited with heap use |
60 | private int heapUse; // current heap use debit amount | 61 | private int heapUse; // current heap use debit amount |
61 | 62 | ||
62 | public static TokenTypeSDTypeDelegate countDelegate = new TokenTypeSDTypeDelegate (new TokenTypeInt (null), new TokenType[0]); | 63 | public static TokenTypeSDTypeDelegate countDelegate = new TokenTypeSDTypeDelegate(new TokenTypeInt(null), new TokenType[0]); |
63 | public static TokenTypeSDTypeDelegate clearDelegate = new TokenTypeSDTypeDelegate (new TokenTypeVoid (null), new TokenType[0]); | 64 | public static TokenTypeSDTypeDelegate clearDelegate = new TokenTypeSDTypeDelegate(new TokenTypeVoid(null), new TokenType[0]); |
64 | public static TokenTypeSDTypeDelegate indexDelegate = new TokenTypeSDTypeDelegate (new TokenTypeObject (null), new TokenType[] { new TokenTypeInt (null) }); | 65 | public static TokenTypeSDTypeDelegate indexDelegate = new TokenTypeSDTypeDelegate(new TokenTypeObject(null), new TokenType[] { new TokenTypeInt(null) }); |
65 | public static TokenTypeSDTypeDelegate valueDelegate = new TokenTypeSDTypeDelegate (new TokenTypeObject (null), new TokenType[] { new TokenTypeInt (null) }); | 66 | public static TokenTypeSDTypeDelegate valueDelegate = new TokenTypeSDTypeDelegate(new TokenTypeObject(null), new TokenType[] { new TokenTypeInt(null) }); |
66 | 67 | ||
67 | public XMR_Array (XMRInstAbstract inst) | 68 | public XMR_Array(XMRInstAbstract inst) |
68 | { | 69 | { |
69 | this.inst = inst; | 70 | this.inst = inst; |
70 | dnary = new SortedDictionary<object, object> (XMRArrayKeyComparer.singleton); | 71 | dnary = new SortedDictionary<object, object>(XMRArrayKeyComparer.singleton); |
71 | heapUse = inst.UpdateHeapUse (0, EMPTYHEAP); | 72 | heapUse = inst.UpdateHeapUse(0, EMPTYHEAP); |
72 | } | 73 | } |
73 | 74 | ||
74 | ~XMR_Array () | 75 | ~XMR_Array() |
75 | { | 76 | { |
76 | heapUse = inst.UpdateHeapUse (heapUse, 0); | 77 | heapUse = inst.UpdateHeapUse(heapUse, 0); |
77 | } | 78 | } |
78 | 79 | ||
79 | public static TokenType GetRValType (TokenName name) | 80 | public static TokenType GetRValType(TokenName name) |
80 | { | 81 | { |
81 | if (name.val == "count") return new TokenTypeInt (name); | 82 | if(name.val == "count") |
82 | if (name.val == "clear") return clearDelegate; | 83 | return new TokenTypeInt(name); |
83 | if (name.val == "index") return indexDelegate; | 84 | if(name.val == "clear") |
84 | if (name.val == "value") return valueDelegate; | 85 | return clearDelegate; |
85 | return new TokenTypeVoid (name); | 86 | if(name.val == "index") |
87 | return indexDelegate; | ||
88 | if(name.val == "value") | ||
89 | return valueDelegate; | ||
90 | return new TokenTypeVoid(name); | ||
86 | } | 91 | } |
87 | 92 | ||
88 | /** | 93 | /** |
@@ -93,44 +98,51 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
93 | public object GetByKey(object key) | 98 | public object GetByKey(object key) |
94 | { | 99 | { |
95 | object val; | 100 | object val; |
96 | key = FixKey (key); | 101 | key = FixKey(key); |
97 | if (!dnary.TryGetValue (key, out val)) val = null; | 102 | if(!dnary.TryGetValue(key, out val)) |
103 | val = null; | ||
98 | return val; | 104 | return val; |
99 | } | 105 | } |
100 | 106 | ||
101 | public void SetByKey(object key, object value) | 107 | public void SetByKey(object key, object value) |
102 | { | 108 | { |
103 | key = FixKey (key); | 109 | key = FixKey(key); |
104 | 110 | ||
105 | /* | 111 | /* |
106 | * Update heap use throwing an exception on failure | 112 | * Update heap use throwing an exception on failure |
107 | * before making any changes to the array. | 113 | * before making any changes to the array. |
108 | */ | 114 | */ |
109 | int keysize = HeapTrackerObject.Size (key); | 115 | int keysize = HeapTrackerObject.Size(key); |
110 | int newheapuse = heapUse; | 116 | int newheapuse = heapUse; |
111 | object oldval; | 117 | object oldval; |
112 | if (dnary.TryGetValue (key, out oldval)) { | 118 | if(dnary.TryGetValue(key, out oldval)) |
113 | newheapuse -= keysize + HeapTrackerObject.Size (oldval); | 119 | { |
120 | newheapuse -= keysize + HeapTrackerObject.Size(oldval); | ||
114 | } | 121 | } |
115 | if (value != null) { | 122 | if(value != null) |
116 | newheapuse += keysize + HeapTrackerObject.Size (value); | 123 | { |
124 | newheapuse += keysize + HeapTrackerObject.Size(value); | ||
117 | } | 125 | } |
118 | heapUse = inst.UpdateHeapUse (heapUse, newheapuse); | 126 | heapUse = inst.UpdateHeapUse(heapUse, newheapuse); |
119 | 127 | ||
120 | /* | 128 | /* |
121 | * Save new value in array, replacing one of same key if there. | 129 | * Save new value in array, replacing one of same key if there. |
122 | * null means remove the value, ie, script did array[key] = undef. | 130 | * null means remove the value, ie, script did array[key] = undef. |
123 | */ | 131 | */ |
124 | if (value != null) { | 132 | if(value != null) |
133 | { | ||
125 | dnary[key] = value; | 134 | dnary[key] = value; |
126 | } else { | 135 | } |
127 | dnary.Remove (key); | 136 | else |
137 | { | ||
138 | dnary.Remove(key); | ||
128 | 139 | ||
129 | /* | 140 | /* |
130 | * Shrink the enumeration array, but always leave at least one element. | 141 | * Shrink the enumeration array, but always leave at least one element. |
131 | */ | 142 | */ |
132 | if ((array != null) && (dnary.Count < array.Length / 2)) { | 143 | if((array != null) && (dnary.Count < array.Length / 2)) |
133 | Array.Resize<KeyValuePair<object, object>> (ref array, array.Length / 2); | 144 | { |
145 | Array.Resize<KeyValuePair<object, object>>(ref array, array.Length / 2); | ||
134 | } | 146 | } |
135 | } | 147 | } |
136 | 148 | ||
@@ -148,44 +160,48 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
148 | * the C# runtime can't convert a null to a value type, and throws an exception. | 160 | * the C# runtime can't convert a null to a value type, and throws an exception. |
149 | * But for any reference type (array, key, etc) we must manually check for null. | 161 | * But for any reference type (array, key, etc) we must manually check for null. |
150 | */ | 162 | */ |
151 | public static XMR_Array Obj2Array (object obj) | 163 | public static XMR_Array Obj2Array(object obj) |
152 | { | 164 | { |
153 | if (obj == null) throw new NullReferenceException (); | 165 | if(obj == null) |
166 | throw new NullReferenceException(); | ||
154 | return (XMR_Array)obj; | 167 | return (XMR_Array)obj; |
155 | } | 168 | } |
156 | public static LSL_Key Obj2Key (object obj) | 169 | public static LSL_Key Obj2Key(object obj) |
157 | { | 170 | { |
158 | if (obj == null) throw new NullReferenceException (); | 171 | if(obj == null) |
172 | throw new NullReferenceException(); | ||
159 | return (LSL_Key)obj; | 173 | return (LSL_Key)obj; |
160 | } | 174 | } |
161 | public static LSL_List Obj2List (object obj) | 175 | public static LSL_List Obj2List(object obj) |
162 | { | 176 | { |
163 | if (obj == null) throw new NullReferenceException (); | 177 | if(obj == null) |
178 | throw new NullReferenceException(); | ||
164 | return (LSL_List)obj; | 179 | return (LSL_List)obj; |
165 | } | 180 | } |
166 | public static LSL_String Obj2String (object obj) | 181 | public static LSL_String Obj2String(object obj) |
167 | { | 182 | { |
168 | if (obj == null) throw new NullReferenceException (); | 183 | if(obj == null) |
169 | return obj.ToString (); | 184 | throw new NullReferenceException(); |
185 | return obj.ToString(); | ||
170 | } | 186 | } |
171 | 187 | ||
172 | /** | 188 | /** |
173 | * @brief remove all elements from the array. | 189 | * @brief remove all elements from the array. |
174 | * sets everything to its 'just constructed' state. | 190 | * sets everything to its 'just constructed' state. |
175 | */ | 191 | */ |
176 | public void __pub_clear () | 192 | public void __pub_clear() |
177 | { | 193 | { |
178 | heapUse = inst.UpdateHeapUse (heapUse, EMPTYHEAP); | 194 | heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP); |
179 | dnary.Clear (); | 195 | dnary.Clear(); |
180 | enumrValid = false; | 196 | enumrValid = false; |
181 | arrayValid = 0; | 197 | arrayValid = 0; |
182 | array = null; | 198 | array = null; |
183 | } | 199 | } |
184 | 200 | ||
185 | /** | 201 | /** |
186 | * @brief return number of elements in the array. | 202 | * @brief return number of elements in the array. |
187 | */ | 203 | */ |
188 | public int __pub_count () | 204 | public int __pub_count() |
189 | { | 205 | { |
190 | return dnary.Count; | 206 | return dnary.Count; |
191 | } | 207 | } |
@@ -196,9 +212,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
196 | * @returns null: array doesn't have that many elements | 212 | * @returns null: array doesn't have that many elements |
197 | * else: index (key) for that element | 213 | * else: index (key) for that element |
198 | */ | 214 | */ |
199 | public object __pub_index (int number) | 215 | public object __pub_index(int number) |
200 | { | 216 | { |
201 | return ForEach (number) ? UnfixKey (array[number].Key) : null; | 217 | return ForEach(number) ? UnfixKey(array[number].Key) : null; |
202 | } | 218 | } |
203 | 219 | ||
204 | /** | 220 | /** |
@@ -207,9 +223,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
207 | * @returns null: array doesn't have that many elements | 223 | * @returns null: array doesn't have that many elements |
208 | * else: value for that element | 224 | * else: value for that element |
209 | */ | 225 | */ |
210 | public object __pub_value (int number) | 226 | public object __pub_value(int number) |
211 | { | 227 | { |
212 | return ForEach (number) ? array[number].Value : null; | 228 | return ForEach(number) ? array[number].Value : null; |
213 | } | 229 | } |
214 | 230 | ||
215 | /** | 231 | /** |
@@ -218,14 +234,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
218 | * @returns false: element does not exist | 234 | * @returns false: element does not exist |
219 | * true: element exists | 235 | * true: element exists |
220 | */ | 236 | */ |
221 | private bool ForEach (int number) | 237 | private bool ForEach(int number) |
222 | { | 238 | { |
223 | /* | 239 | /* |
224 | * If we don't have any array, we can't have ever done | 240 | * If we don't have any array, we can't have ever done |
225 | * any calls here before, so allocate an array big enough | 241 | * any calls here before, so allocate an array big enough |
226 | * and set everything else to the beginning. | 242 | * and set everything else to the beginning. |
227 | */ | 243 | */ |
228 | if (array == null) { | 244 | if(array == null) |
245 | { | ||
229 | array = new KeyValuePair<object, object>[dnary.Count]; | 246 | array = new KeyValuePair<object, object>[dnary.Count]; |
230 | arrayValid = 0; | 247 | arrayValid = 0; |
231 | } | 248 | } |
@@ -233,17 +250,20 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
233 | /* | 250 | /* |
234 | * If dictionary modified since last enumeration, get a new enumerator. | 251 | * If dictionary modified since last enumeration, get a new enumerator. |
235 | */ | 252 | */ |
236 | if (arrayValid == 0) { | 253 | if(arrayValid == 0) |
237 | enumr = dnary.GetEnumerator (); | 254 | { |
255 | enumr = dnary.GetEnumerator(); | ||
238 | enumrValid = true; | 256 | enumrValid = true; |
239 | } | 257 | } |
240 | 258 | ||
241 | /* | 259 | /* |
242 | * Make sure we have filled the array up enough for requested element. | 260 | * Make sure we have filled the array up enough for requested element. |
243 | */ | 261 | */ |
244 | while ((arrayValid <= number) && enumrValid && enumr.MoveNext ()) { | 262 | while((arrayValid <= number) && enumrValid && enumr.MoveNext()) |
245 | if (arrayValid >= array.Length) { | 263 | { |
246 | Array.Resize<KeyValuePair<object, object>> (ref array, dnary.Count); | 264 | if(arrayValid >= array.Length) |
265 | { | ||
266 | Array.Resize<KeyValuePair<object, object>>(ref array, dnary.Count); | ||
247 | } | 267 | } |
248 | array[arrayValid++] = enumr.Current; | 268 | array[arrayValid++] = enumr.Current; |
249 | } | 269 | } |
@@ -258,17 +278,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
258 | * @brief Transmit array out in such a way that it can be reconstructed, | 278 | * @brief Transmit array out in such a way that it can be reconstructed, |
259 | * including any in-progress ForEach() enumerations. | 279 | * including any in-progress ForEach() enumerations. |
260 | */ | 280 | */ |
261 | public delegate void SendArrayObjDelegate (object graph); | 281 | public delegate void SendArrayObjDelegate(object graph); |
262 | public void SendArrayObj (SendArrayObjDelegate sendObj) | 282 | public void SendArrayObj(SendArrayObjDelegate sendObj) |
263 | { | 283 | { |
264 | /* | 284 | /* |
265 | * Set the count then the elements themselves. | 285 | * Set the count then the elements themselves. |
266 | * UnfixKey() because sendObj doesn't handle XMRArrayListKeys. | 286 | * UnfixKey() because sendObj doesn't handle XMRArrayListKeys. |
267 | */ | 287 | */ |
268 | sendObj (dnary.Count); | 288 | sendObj(dnary.Count); |
269 | foreach (KeyValuePair<object, object> kvp in dnary) { | 289 | foreach(KeyValuePair<object, object> kvp in dnary) |
270 | sendObj (UnfixKey (kvp.Key)); | 290 | { |
271 | sendObj (kvp.Value); | 291 | sendObj(UnfixKey(kvp.Key)); |
292 | sendObj(kvp.Value); | ||
272 | } | 293 | } |
273 | } | 294 | } |
274 | 295 | ||
@@ -278,10 +299,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
278 | * at the exact spot and in the exact same order as they | 299 | * at the exact spot and in the exact same order as they |
279 | * were in on the sending side. | 300 | * were in on the sending side. |
280 | */ | 301 | */ |
281 | public delegate object RecvArrayObjDelegate (); | 302 | public delegate object RecvArrayObjDelegate(); |
282 | public void RecvArrayObj (RecvArrayObjDelegate recvObj) | 303 | public void RecvArrayObj(RecvArrayObjDelegate recvObj) |
283 | { | 304 | { |
284 | heapUse = inst.UpdateHeapUse (heapUse, EMPTYHEAP); | 305 | heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP); |
285 | 306 | ||
286 | /* | 307 | /* |
287 | * Cause any enumeration to refill the array from the sorted dictionary. | 308 | * Cause any enumeration to refill the array from the sorted dictionary. |
@@ -294,14 +315,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
294 | /* | 315 | /* |
295 | * Fill dictionary. | 316 | * Fill dictionary. |
296 | */ | 317 | */ |
297 | dnary.Clear (); | 318 | dnary.Clear(); |
298 | int count = (int)recvObj (); | 319 | int count = (int)recvObj(); |
299 | while (-- count >= 0) { | 320 | while(--count >= 0) |
300 | object key = FixKey (recvObj ()); | 321 | { |
301 | object val = recvObj (); | 322 | object key = FixKey(recvObj()); |
302 | int htuse = HeapTrackerObject.Size (key) + HeapTrackerObject.Size (val); | 323 | object val = recvObj(); |
303 | heapUse = inst.UpdateHeapUse (heapUse, heapUse + htuse); | 324 | int htuse = HeapTrackerObject.Size(key) + HeapTrackerObject.Size(val); |
304 | dnary.Add (key, val); | 325 | heapUse = inst.UpdateHeapUse(heapUse, heapUse + htuse); |
326 | dnary.Add(key, val); | ||
305 | } | 327 | } |
306 | } | 328 | } |
307 | 329 | ||
@@ -310,16 +332,22 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
310 | * So strip off any LSL-ness from the types. | 332 | * So strip off any LSL-ness from the types. |
311 | * We also deep-strip any given lists used as keys (multi-dimensional arrays). | 333 | * We also deep-strip any given lists used as keys (multi-dimensional arrays). |
312 | */ | 334 | */ |
313 | public static object FixKey (object key) | 335 | public static object FixKey(object key) |
314 | { | 336 | { |
315 | if (key is LSL_Integer) return (int)(LSL_Integer)key; | 337 | if(key is LSL_Integer) |
316 | if (key is LSL_Float) return (double)(LSL_Float)key; | 338 | return (int)(LSL_Integer)key; |
317 | if (key is LSL_Key) return (string)(LSL_Key)key; | 339 | if(key is LSL_Float) |
318 | if (key is LSL_String) return (string)(LSL_String)key; | 340 | return (double)(LSL_Float)key; |
319 | if (key is LSL_List) { | 341 | if(key is LSL_Key) |
342 | return (string)(LSL_Key)key; | ||
343 | if(key is LSL_String) | ||
344 | return (string)(LSL_String)key; | ||
345 | if(key is LSL_List) | ||
346 | { | ||
320 | object[] data = ((LSL_List)key).Data; | 347 | object[] data = ((LSL_List)key).Data; |
321 | if (data.Length == 1) return FixKey (data[0]); | 348 | if(data.Length == 1) |
322 | return new XMRArrayListKey ((LSL_List)key); | 349 | return FixKey(data[0]); |
350 | return new XMRArrayListKey((LSL_List)key); | ||
323 | } | 351 | } |
324 | return key; // int, double, string, LSL_Vector, LSL_Rotation, etc are ok as is | 352 | return key; // int, double, string, LSL_Vector, LSL_Rotation, etc are ok as is |
325 | } | 353 | } |
@@ -329,99 +357,119 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
329 | * LSL_List, not the sanitized one, as the script compiler expects an LSL_List. | 357 | * LSL_List, not the sanitized one, as the script compiler expects an LSL_List. |
330 | * Any other sanitized types can remain as is (int, string, etc). | 358 | * Any other sanitized types can remain as is (int, string, etc). |
331 | */ | 359 | */ |
332 | private static object UnfixKey (object key) | 360 | private static object UnfixKey(object key) |
333 | { | 361 | { |
334 | if (key is XMRArrayListKey) key = ((XMRArrayListKey)key).GetOriginal (); | 362 | if(key is XMRArrayListKey) |
363 | key = ((XMRArrayListKey)key).GetOriginal(); | ||
335 | return key; | 364 | return key; |
336 | } | 365 | } |
337 | } | 366 | } |
338 | 367 | ||
339 | public class XMRArrayKeyComparer : IComparer<object> { | 368 | public class XMRArrayKeyComparer: IComparer<object> |
369 | { | ||
340 | 370 | ||
341 | public static XMRArrayKeyComparer singleton = new XMRArrayKeyComparer (); | 371 | public static XMRArrayKeyComparer singleton = new XMRArrayKeyComparer(); |
342 | 372 | ||
343 | /** | 373 | /** |
344 | * @brief Compare two keys | 374 | * @brief Compare two keys |
345 | */ | 375 | */ |
346 | public int Compare (object x, object y) // IComparer<object> | 376 | public int Compare(object x, object y) // IComparer<object> |
347 | { | 377 | { |
348 | /* | 378 | /* |
349 | * Use short type name (eg, String, Int32, XMRArrayListKey) as most significant part of key. | 379 | * Use short type name (eg, String, Int32, XMRArrayListKey) as most significant part of key. |
350 | */ | 380 | */ |
351 | string xtn = x.GetType ().Name; | 381 | string xtn = x.GetType().Name; |
352 | string ytn = y.GetType ().Name; | 382 | string ytn = y.GetType().Name; |
353 | int ctn = String.CompareOrdinal (xtn, ytn); | 383 | int ctn = String.CompareOrdinal(xtn, ytn); |
354 | if (ctn != 0) return ctn; | 384 | if(ctn != 0) |
385 | return ctn; | ||
355 | 386 | ||
356 | ComparerDelegate cd; | 387 | ComparerDelegate cd; |
357 | if (!comparers.TryGetValue (xtn, out cd)) { | 388 | if(!comparers.TryGetValue(xtn, out cd)) |
358 | throw new Exception ("unsupported key type " + xtn); | 389 | { |
390 | throw new Exception("unsupported key type " + xtn); | ||
359 | } | 391 | } |
360 | return cd (x, y); | 392 | return cd(x, y); |
361 | } | 393 | } |
362 | 394 | ||
363 | private delegate int ComparerDelegate (object a, object b); | 395 | private delegate int ComparerDelegate(object a, object b); |
364 | 396 | ||
365 | private static Dictionary<string, ComparerDelegate> comparers = BuildComparers (); | 397 | private static Dictionary<string, ComparerDelegate> comparers = BuildComparers(); |
366 | 398 | ||
367 | private static Dictionary<string, ComparerDelegate> BuildComparers () | 399 | private static Dictionary<string, ComparerDelegate> BuildComparers() |
368 | { | 400 | { |
369 | Dictionary<string, ComparerDelegate> cmps = new Dictionary<string, ComparerDelegate> (); | 401 | Dictionary<string, ComparerDelegate> cmps = new Dictionary<string, ComparerDelegate>(); |
370 | cmps.Add (typeof (double).Name, MyFloatComparer); | 402 | cmps.Add(typeof(double).Name, MyFloatComparer); |
371 | cmps.Add (typeof (int).Name, MyIntComparer); | 403 | cmps.Add(typeof(int).Name, MyIntComparer); |
372 | cmps.Add (typeof (XMRArrayListKey).Name, MyListKeyComparer); | 404 | cmps.Add(typeof(XMRArrayListKey).Name, MyListKeyComparer); |
373 | cmps.Add (typeof (LSL_Rotation).Name, MyRotationComparer); | 405 | cmps.Add(typeof(LSL_Rotation).Name, MyRotationComparer); |
374 | cmps.Add (typeof (string).Name, MyStringComparer); | 406 | cmps.Add(typeof(string).Name, MyStringComparer); |
375 | cmps.Add (typeof (LSL_Vector).Name, MyVectorComparer); | 407 | cmps.Add(typeof(LSL_Vector).Name, MyVectorComparer); |
376 | return cmps; | 408 | return cmps; |
377 | } | 409 | } |
378 | 410 | ||
379 | private static int MyFloatComparer (object a, object b) | 411 | private static int MyFloatComparer(object a, object b) |
380 | { | 412 | { |
381 | double af = (double)a; | 413 | double af = (double)a; |
382 | double bf = (double)b; | 414 | double bf = (double)b; |
383 | if (af < bf) return -1; | 415 | if(af < bf) |
384 | if (af > bf) return 1; | 416 | return -1; |
417 | if(af > bf) | ||
418 | return 1; | ||
385 | return 0; | 419 | return 0; |
386 | } | 420 | } |
387 | private static int MyIntComparer (object a, object b) | 421 | private static int MyIntComparer(object a, object b) |
388 | { | 422 | { |
389 | return (int)a - (int)b; | 423 | return (int)a - (int)b; |
390 | } | 424 | } |
391 | private static int MyListKeyComparer (object a, object b) | 425 | private static int MyListKeyComparer(object a, object b) |
392 | { | 426 | { |
393 | XMRArrayListKey alk = (XMRArrayListKey)a; | 427 | XMRArrayListKey alk = (XMRArrayListKey)a; |
394 | XMRArrayListKey blk = (XMRArrayListKey)b; | 428 | XMRArrayListKey blk = (XMRArrayListKey)b; |
395 | return XMRArrayListKey.Compare (alk, blk); | 429 | return XMRArrayListKey.Compare(alk, blk); |
396 | } | 430 | } |
397 | private static int MyRotationComparer (object a, object b) | 431 | private static int MyRotationComparer(object a, object b) |
398 | { | 432 | { |
399 | LSL_Rotation ar = (LSL_Rotation)a; | 433 | LSL_Rotation ar = (LSL_Rotation)a; |
400 | LSL_Rotation br = (LSL_Rotation)b; | 434 | LSL_Rotation br = (LSL_Rotation)b; |
401 | if (ar.x < br.x) return -1; | 435 | if(ar.x < br.x) |
402 | if (ar.x > br.x) return 1; | 436 | return -1; |
403 | if (ar.y < br.y) return -1; | 437 | if(ar.x > br.x) |
404 | if (ar.y > br.y) return 1; | 438 | return 1; |
405 | if (ar.z < br.z) return -1; | 439 | if(ar.y < br.y) |
406 | if (ar.z > br.z) return 1; | 440 | return -1; |
407 | if (ar.s < br.s) return -1; | 441 | if(ar.y > br.y) |
408 | if (ar.s > br.s) return 1; | 442 | return 1; |
443 | if(ar.z < br.z) | ||
444 | return -1; | ||
445 | if(ar.z > br.z) | ||
446 | return 1; | ||
447 | if(ar.s < br.s) | ||
448 | return -1; | ||
449 | if(ar.s > br.s) | ||
450 | return 1; | ||
409 | return 0; | 451 | return 0; |
410 | } | 452 | } |
411 | private static int MyStringComparer (object a, object b) | 453 | private static int MyStringComparer(object a, object b) |
412 | { | 454 | { |
413 | return String.CompareOrdinal ((string)a, (string)b); | 455 | return String.CompareOrdinal((string)a, (string)b); |
414 | } | 456 | } |
415 | private static int MyVectorComparer (object a, object b) | 457 | private static int MyVectorComparer(object a, object b) |
416 | { | 458 | { |
417 | LSL_Vector av = (LSL_Vector)a; | 459 | LSL_Vector av = (LSL_Vector)a; |
418 | LSL_Vector bv = (LSL_Vector)b; | 460 | LSL_Vector bv = (LSL_Vector)b; |
419 | if (av.x < bv.x) return -1; | 461 | if(av.x < bv.x) |
420 | if (av.x > bv.x) return 1; | 462 | return -1; |
421 | if (av.y < bv.y) return -1; | 463 | if(av.x > bv.x) |
422 | if (av.y > bv.y) return 1; | 464 | return 1; |
423 | if (av.z < bv.z) return -1; | 465 | if(av.y < bv.y) |
424 | if (av.z > bv.z) return 1; | 466 | return -1; |
467 | if(av.y > bv.y) | ||
468 | return 1; | ||
469 | if(av.z < bv.z) | ||
470 | return -1; | ||
471 | if(av.z > bv.z) | ||
472 | return 1; | ||
425 | return 0; | 473 | return 0; |
426 | } | 474 | } |
427 | } | 475 | } |
@@ -433,7 +481,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
433 | * Note that just like LSL_Lists, we consider these objects to be immutable, so they can be directly used as keys in | 481 | * Note that just like LSL_Lists, we consider these objects to be immutable, so they can be directly used as keys in |
434 | * the dictionary as they don't ever change. | 482 | * the dictionary as they don't ever change. |
435 | */ | 483 | */ |
436 | public class XMRArrayListKey { | 484 | public class XMRArrayListKey |
485 | { | ||
437 | private LSL_List original; | 486 | private LSL_List original; |
438 | private object[] cleaned; | 487 | private object[] cleaned; |
439 | private int length; | 488 | private int length; |
@@ -443,18 +492,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
443 | * @brief Construct a sanitized object[] from a list. | 492 | * @brief Construct a sanitized object[] from a list. |
444 | * Also save the original list in case we need it later. | 493 | * Also save the original list in case we need it later. |
445 | */ | 494 | */ |
446 | public XMRArrayListKey (LSL_List key) | 495 | public XMRArrayListKey(LSL_List key) |
447 | { | 496 | { |
448 | original = key; | 497 | original = key; |
449 | object[] given = key.Data; | 498 | object[] given = key.Data; |
450 | int len = given.Length; | 499 | int len = given.Length; |
451 | length = len; | 500 | length = len; |
452 | cleaned = new object[len]; | 501 | cleaned = new object[len]; |
453 | int hc = len; | 502 | int hc = len; |
454 | for (int i = 0; i < len; i ++) { | 503 | for(int i = 0; i < len; i++) |
455 | object v = XMR_Array.FixKey (given[i]); | 504 | { |
456 | hc += hc + ((hc < 0) ? 1 : 0); | 505 | object v = XMR_Array.FixKey(given[i]); |
457 | hc ^= v.GetHashCode (); | 506 | hc += hc + ((hc < 0) ? 1 : 0); |
507 | hc ^= v.GetHashCode(); | ||
458 | cleaned[i] = v; | 508 | cleaned[i] = v; |
459 | } | 509 | } |
460 | hashCode = hc; | 510 | hashCode = hc; |
@@ -463,8 +513,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
463 | /** | 513 | /** |
464 | * @brief Get heap tracking size. | 514 | * @brief Get heap tracking size. |
465 | */ | 515 | */ |
466 | public int Size { | 516 | public int Size |
467 | get { | 517 | { |
518 | get | ||
519 | { | ||
468 | return original.Size; | 520 | return original.Size; |
469 | } | 521 | } |
470 | } | 522 | } |
@@ -472,15 +524,20 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
472 | /** | 524 | /** |
473 | * @brief See if the given object is an XMRArrayListKey and every value is equal to our own. | 525 | * @brief See if the given object is an XMRArrayListKey and every value is equal to our own. |
474 | */ | 526 | */ |
475 | public override bool Equals (object o) | 527 | public override bool Equals(object o) |
476 | { | 528 | { |
477 | if (!(o is XMRArrayListKey)) return false; | 529 | if(!(o is XMRArrayListKey)) |
530 | return false; | ||
478 | XMRArrayListKey a = (XMRArrayListKey)o; | 531 | XMRArrayListKey a = (XMRArrayListKey)o; |
479 | int len = a.length; | 532 | int len = a.length; |
480 | if (len != length) return false; | 533 | if(len != length) |
481 | if (a.hashCode != hashCode) return false; | 534 | return false; |
482 | for (int i = 0; i < len; i ++) { | 535 | if(a.hashCode != hashCode) |
483 | if (!cleaned[i].Equals (a.cleaned[i])) return false; | 536 | return false; |
537 | for(int i = 0; i < len; i++) | ||
538 | { | ||
539 | if(!cleaned[i].Equals(a.cleaned[i])) | ||
540 | return false; | ||
484 | } | 541 | } |
485 | return true; | 542 | return true; |
486 | } | 543 | } |
@@ -488,7 +545,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
488 | /** | 545 | /** |
489 | * @brief Get an hash code. | 546 | * @brief Get an hash code. |
490 | */ | 547 | */ |
491 | public override int GetHashCode () | 548 | public override int GetHashCode() |
492 | { | 549 | { |
493 | return hashCode; | 550 | return hashCode; |
494 | } | 551 | } |
@@ -496,15 +553,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
496 | /** | 553 | /** |
497 | * @brief Compare for key sorting. | 554 | * @brief Compare for key sorting. |
498 | */ | 555 | */ |
499 | public static int Compare (XMRArrayListKey x, XMRArrayListKey y) | 556 | public static int Compare(XMRArrayListKey x, XMRArrayListKey y) |
500 | { | 557 | { |
501 | int j = x.length - y.length; | 558 | int j = x.length - y.length; |
502 | if (j == 0) { | 559 | if(j == 0) |
503 | for (int i = 0; i < x.length; i ++) { | 560 | { |
561 | for(int i = 0; i < x.length; i++) | ||
562 | { | ||
504 | object xo = x.cleaned[i]; | 563 | object xo = x.cleaned[i]; |
505 | object yo = y.cleaned[i]; | 564 | object yo = y.cleaned[i]; |
506 | j = XMRArrayKeyComparer.singleton.Compare (xo, yo); | 565 | j = XMRArrayKeyComparer.singleton.Compare(xo, yo); |
507 | if (j != 0) break; | 566 | if(j != 0) |
567 | break; | ||
508 | } | 568 | } |
509 | } | 569 | } |
510 | return j; | 570 | return j; |
@@ -513,7 +573,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
513 | /** | 573 | /** |
514 | * @brief Get the original LSL_List we were built from. | 574 | * @brief Get the original LSL_List we were built from. |
515 | */ | 575 | */ |
516 | public LSL_List GetOriginal () | 576 | public LSL_List GetOriginal() |
517 | { | 577 | { |
518 | return original; | 578 | return original; |
519 | } | 579 | } |
@@ -521,14 +581,16 @@ namespace OpenSim.Region.ScriptEngine.XMREngine | |||
521 | /** | 581 | /** |
522 | * @brief Debugging | 582 | * @brief Debugging |
523 | */ | 583 | */ |
524 | public override string ToString () | 584 | public override string ToString() |
525 | { | 585 | { |
526 | StringBuilder sb = new StringBuilder (); | 586 | StringBuilder sb = new StringBuilder(); |
527 | for (int i = 0; i < length; i ++) { | 587 | for(int i = 0; i < length; i++) |
528 | if (i > 0) sb.Append (','); | 588 | { |
529 | sb.Append (cleaned[i].ToString ()); | 589 | if(i > 0) |
590 | sb.Append(','); | ||
591 | sb.Append(cleaned[i].ToString()); | ||
530 | } | 592 | } |
531 | return sb.ToString (); | 593 | return sb.ToString(); |
532 | } | 594 | } |
533 | } | 595 | } |
534 | } | 596 | } |