aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs547
1 files changed, 547 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs
new file mode 100644
index 0000000..ea306c8
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs
@@ -0,0 +1,547 @@
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
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using System.Text;
34using System.Threading;
35
36using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
37using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
38using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
39using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
40using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
43
44namespace OpenSim.Region.ScriptEngine.Yengine
45{
46 public partial class Yengine
47 {
48
49 private void XmrTestLs(string[] args, int indx)
50 {
51 bool flagFull = false;
52 bool flagQueues = false;
53 bool flagTopCPU = false;
54 int maxScripts = 0x7FFFFFFF;
55 int numScripts = 0;
56 string outName = null;
57 XMRInstance[] instances;
58
59 // Decode command line options.
60 for(int i = indx; i < args.Length; i++)
61 {
62 if(args[i] == "-full")
63 {
64 flagFull = true;
65 continue;
66 }
67 if(args[i] == "-help")
68 {
69 m_log.Info("[YEngine]: yeng ls -full -max=<number> -out=<filename> -queues -topcpu");
70 return;
71 }
72 if(args[i].StartsWith("-max="))
73 {
74 try
75 {
76 maxScripts = Convert.ToInt32(args[i].Substring(5));
77 }
78 catch(Exception e)
79 {
80 m_log.Error("[YEngine]: bad max " + args[i].Substring(5) + ": " + e.Message);
81 return;
82 }
83 continue;
84 }
85 if(args[i].StartsWith("-out="))
86 {
87 outName = args[i].Substring(5);
88 continue;
89 }
90 if(args[i] == "-queues")
91 {
92 flagQueues = true;
93 continue;
94 }
95 if(args[i] == "-topcpu")
96 {
97 flagTopCPU = true;
98 continue;
99 }
100 if(args[i][0] == '-')
101 {
102 m_log.Error("[YEngine]: unknown option " + args[i] + ", try 'yeng ls -help'");
103 return;
104 }
105 }
106
107 TextWriter outFile = null;
108 if(outName != null)
109 {
110 try
111 {
112 outFile = File.CreateText(outName);
113 }
114 catch(Exception e)
115 {
116 m_log.Error("[YEngine]: error creating " + outName + ": " + e.Message);
117 return;
118 }
119 }
120 else
121 {
122 outFile = new LogInfoTextWriter(m_log);
123 }
124
125 try
126 {
127 // Scan instance list to find those that match selection criteria.
128 if(!Monitor.TryEnter(m_InstancesDict, 100))
129 {
130 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
131 return;
132 }
133 try
134 {
135 instances = new XMRInstance[m_InstancesDict.Count];
136 foreach(XMRInstance ins in m_InstancesDict.Values)
137 {
138 if(InstanceMatchesArgs(ins, args, indx))
139 {
140 instances[numScripts++] = ins;
141 }
142 }
143 }
144 finally
145 {
146 Monitor.Exit(m_InstancesDict);
147 }
148
149 // Maybe sort by descending CPU time.
150 if(flagTopCPU)
151 {
152 Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime);
153 }
154
155 // Print the entries.
156 if(!flagFull)
157 {
158 outFile.WriteLine(" ItemID" +
159 " CPU(ms)" +
160 " NumEvents" +
161 " Status " +
162 " World Position " +
163 " <Part>:<Item>");
164 }
165 for(int i = 0; (i < numScripts) && (i < maxScripts); i++)
166 {
167 outFile.WriteLine(instances[i].RunTestLs(flagFull));
168 }
169
170 // Print number of scripts that match selection criteria,
171 // even if we were told to print fewer.
172 outFile.WriteLine("total of {0} script(s)", numScripts);
173
174 // If -queues given, print out queue contents too.
175 if(flagQueues)
176 {
177 LsQueue(outFile, "start", m_StartQueue, args, indx);
178 LsQueue(outFile, "sleep", m_SleepQueue, args, indx);
179 LsQueue(outFile, "yield", m_YieldQueue, args, indx);
180 }
181 }
182 finally
183 {
184 outFile.Close();
185 }
186 }
187
188 private void XmrTestPev(string[] args, int indx)
189 {
190 bool flagAll = false;
191 int numScripts = 0;
192 XMRInstance[] instances;
193
194 // Decode command line options.
195 int i, j;
196 List<string> selargs = new List<string>(args.Length);
197 MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods();
198 MethodInfo eventmethod;
199 for(i = indx; i < args.Length; i++)
200 {
201 string arg = args[i];
202 if(arg == "-all")
203 {
204 flagAll = true;
205 continue;
206 }
207 if(arg == "-help")
208 {
209 m_log.Info("[YEngine]: yeng pev -all | <part-of-script-name> <event-name> <params...>");
210 return;
211 }
212 if(arg[0] == '-')
213 {
214 m_log.Error("[YEngine]: unknown option " + arg + ", try 'yeng pev -help'");
215 return;
216 }
217 for(j = 0; j < eventmethods.Length; j++)
218 {
219 eventmethod = eventmethods[j];
220 if(eventmethod.Name == arg)
221 goto gotevent;
222 }
223 selargs.Add(arg);
224 }
225 m_log.Error("[YEngine]: missing <event-name> <params...>, try 'yeng pev -help'");
226 return;
227 gotevent:
228 string eventname = eventmethod.Name;
229 StringBuilder sourcesb = new StringBuilder();
230 while(++i < args.Length)
231 {
232 sourcesb.Append(' ');
233 sourcesb.Append(args[i]);
234 }
235 string sourcest = sourcesb.ToString();
236 string sourcehash;
237 youveanerror = false;
238 Token t = TokenBegin.Construct("", null, ErrorMsg, sourcest, out sourcehash);
239 if(youveanerror)
240 return;
241 ParameterInfo[] paraminfos = eventmethod.GetParameters();
242 object[] paramvalues = new object[paraminfos.Length];
243 i = 0;
244 while(!((t = t.nextToken) is TokenEnd))
245 {
246 if(i >= paramvalues.Length)
247 {
248 ErrorMsg(t, "extra parameter(s)");
249 return;
250 }
251 paramvalues[i] = ParseParamValue(ref t);
252 if(paramvalues[i] == null)
253 return;
254 i++;
255 }
256 OpenSim.Region.ScriptEngine.Shared.EventParams eps =
257 new OpenSim.Region.ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams);
258
259 // Scan instance list to find those that match selection criteria.
260 if(!Monitor.TryEnter(m_InstancesDict, 100))
261 {
262 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
263 return;
264 }
265
266 try
267 {
268 instances = new XMRInstance[m_InstancesDict.Count];
269 foreach(XMRInstance ins in m_InstancesDict.Values)
270 {
271 if(flagAll || InstanceMatchesArgs(ins, selargs.ToArray(), 0))
272 {
273 instances[numScripts++] = ins;
274 }
275 }
276 }
277 finally
278 {
279 Monitor.Exit(m_InstancesDict);
280 }
281
282 // Post event to the matching instances.
283 for(i = 0; i < numScripts; i++)
284 {
285 XMRInstance inst = instances[i];
286 m_log.Info("[YEngine]: post " + eventname + " to " + inst.m_DescName);
287 inst.PostEvent(eps);
288 }
289 }
290
291 private object ParseParamValue(ref Token token)
292 {
293 if(token is TokenFloat)
294 {
295 return new LSL_Float(((TokenFloat)token).val);
296 }
297 if(token is TokenInt)
298 {
299 return new LSL_Integer(((TokenInt)token).val);
300 }
301 if(token is TokenStr)
302 {
303 return new LSL_String(((TokenStr)token).val);
304 }
305 if(token is TokenKwCmpLT)
306 {
307 List<double> valuelist = new List<double>();
308 while(!((token = token.nextToken) is TokenKwCmpGT))
309 {
310 if(!(token is TokenKwComma))
311 {
312 object value = ParseParamValue(ref token);
313 if(value == null)
314 return null;
315 if(value is int)
316 value = (double)(int)value;
317 if(!(value is double))
318 {
319 ErrorMsg(token, "must be float or integer constant");
320 return null;
321 }
322 valuelist.Add((double)value);
323 }
324 else if(token.prevToken is TokenKwComma)
325 {
326 ErrorMsg(token, "missing constant");
327 return null;
328 }
329 }
330 double[] values = valuelist.ToArray();
331 switch(values.Length)
332 {
333 case 3:
334 {
335 return new LSL_Vector(values[0], values[1], values[2]);
336 }
337 case 4:
338 {
339 return new LSL_Rotation(values[0], values[1], values[2], values[3]);
340 }
341 default:
342 {
343 ErrorMsg(token, "not rotation or vector");
344 return null;
345 }
346 }
347 }
348 if(token is TokenKwBrkOpen)
349 {
350 List<object> valuelist = new List<object>();
351 while(!((token = token.nextToken) is TokenKwBrkClose))
352 {
353 if(!(token is TokenKwComma))
354 {
355 object value = ParseParamValue(ref token);
356 if(value == null)
357 return null;
358 valuelist.Add(value);
359 }
360 else if(token.prevToken is TokenKwComma)
361 {
362 ErrorMsg(token, "missing constant");
363 return null;
364 }
365 }
366 return new LSL_List(valuelist.ToArray());
367 }
368 if(token is TokenName)
369 {
370 FieldInfo field = typeof(OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass).GetField(((TokenName)token).val);
371 if((field != null) && field.IsPublic && (field.IsLiteral || (field.IsStatic && field.IsInitOnly)))
372 {
373 return field.GetValue(null);
374 }
375 }
376 ErrorMsg(token, "invalid constant");
377 return null;
378 }
379
380 private bool youveanerror;
381 private void ErrorMsg(Token token, string message)
382 {
383 youveanerror = true;
384 m_log.Info("[YEngine]: " + token.posn + " " + message);
385 }
386
387 private void XmrTestReset(string[] args, int indx)
388 {
389 bool flagAll = false;
390 int numScripts = 0;
391 XMRInstance[] instances;
392
393 if(args.Length <= indx)
394 {
395 m_log.Error("[YEngine]: must specify part of script name or -all for all scripts");
396 return;
397 }
398
399 // Decode command line options.
400 for(int i = indx; i < args.Length; i++)
401 {
402 if(args[i] == "-all")
403 {
404 flagAll = true;
405 continue;
406 }
407 if(args[i] == "-help")
408 {
409 m_log.Info("[YEngine]: yeng reset -all | <part-of-script-name>");
410 return;
411 }
412 if(args[i][0] == '-')
413 {
414 m_log.Error("[YEngine]: unknown option " + args[i] + ", try 'yeng reset -help'");
415 return;
416 }
417 }
418
419 // Scan instance list to find those that match selection criteria.
420 if(!Monitor.TryEnter(m_InstancesDict, 100))
421 {
422 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
423 return;
424 }
425
426 try
427 {
428 instances = new XMRInstance[m_InstancesDict.Count];
429 foreach(XMRInstance ins in m_InstancesDict.Values)
430 {
431 if(flagAll || InstanceMatchesArgs(ins, args, indx))
432 {
433 instances[numScripts++] = ins;
434 }
435 }
436 }
437 finally
438 {
439 Monitor.Exit(m_InstancesDict);
440 }
441
442 // Reset the instances as if someone clicked their "Reset" button.
443 for(int i = 0; i < numScripts; i++)
444 {
445 XMRInstance inst = instances[i];
446 m_log.Info("[YEngine]: resetting " + inst.m_DescName);
447 inst.Reset();
448 }
449 }
450
451 private static int CompareInstancesByCPUTime(XMRInstance a, XMRInstance b)
452 {
453 if(a == null)
454 {
455 return (b == null) ? 0 : 1;
456 }
457 if(b == null)
458 {
459 return -1;
460 }
461 if(b.m_CPUTime < a.m_CPUTime)
462 return -1;
463 if(b.m_CPUTime > a.m_CPUTime)
464 return 1;
465 return 0;
466 }
467
468 private void LsQueue(TextWriter outFile, string name, XMRInstQueue queue, string[] args, int indx)
469 {
470 outFile.WriteLine("Queue " + name + ":");
471 lock(queue)
472 {
473 for(XMRInstance inst = queue.PeekHead(); inst != null; inst = inst.m_NextInst)
474 {
475 try
476 {
477 // Try to print instance name.
478 if(InstanceMatchesArgs(inst, args, indx))
479 {
480 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName);
481 }
482 }
483 catch(Exception e)
484 {
485 // Sometimes there are instances in the queue that are disposed.
486 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message);
487 }
488 }
489 }
490 }
491
492 private bool InstanceMatchesArgs(XMRInstance ins, string[] args, int indx)
493 {
494 bool hadSomethingToCompare = false;
495
496 for(int i = indx; i < args.Length; i++)
497 {
498 if(args[i][0] != '-')
499 {
500 hadSomethingToCompare = true;
501 if(ins.m_DescName.Contains(args[i]))
502 return true;
503 if(ins.ItemID.ToString().Contains(args[i]))
504 return true;
505 if(ins.AssetID.ToString().Contains(args[i]))
506 return true;
507 }
508 }
509 return !hadSomethingToCompare;
510 }
511 }
512
513 /**
514 * @brief Make m_log.Info look like a text writer.
515 */
516 public class LogInfoTextWriter: TextWriter
517 {
518 private StringBuilder sb = new StringBuilder();
519 private ILog m_log;
520 public LogInfoTextWriter(ILog m_log)
521 {
522 this.m_log = m_log;
523 }
524 public override void Write(char c)
525 {
526 if(c == '\n')
527 {
528 m_log.Info("[YEngine]: " + sb.ToString());
529 sb.Remove(0, sb.Length);
530 }
531 else
532 {
533 sb.Append(c);
534 }
535 }
536 public override void Close()
537 {
538 }
539 public override Encoding Encoding
540 {
541 get
542 {
543 return Encoding.UTF8;
544 }
545 }
546 }
547}