aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandManager.cs
diff options
context:
space:
mode:
authorTedd Hansen2008-02-25 19:53:11 +0000
committerTedd Hansen2008-02-25 19:53:11 +0000
commit366e607608e89ba6ce140c1c49a53593230e1ed8 (patch)
tree7b8175f5bf08f0f00a569bdf35957b6fc7dd3f6c /OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandManager.cs
parentStep 1 in reorganizing AsyncCommandManager (diff)
downloadopensim-SC_OLD-366e607608e89ba6ce140c1c49a53593230e1ed8.zip
opensim-SC_OLD-366e607608e89ba6ce140c1c49a53593230e1ed8.tar.gz
opensim-SC_OLD-366e607608e89ba6ce140c1c49a53593230e1ed8.tar.bz2
opensim-SC_OLD-366e607608e89ba6ce140c1c49a53593230e1ed8.tar.xz
eol
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandManager.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandManager.cs1354
1 files changed, 677 insertions, 677 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandManager.cs
index 1133a8e..e9539e6 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandManager.cs
@@ -1,677 +1,677 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29using System; 29using System;
30using System.Collections; 30using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Threading; 32using System.Threading;
33using libsecondlife; 33using libsecondlife;
34using Axiom.Math; 34using Axiom.Math;
35using OpenSim.Region.Environment.Interfaces; 35using OpenSim.Region.Environment.Interfaces;
36using OpenSim.Region.Environment.Modules; 36using OpenSim.Region.Environment.Modules;
37using OpenSim.Region.Environment.Scenes; 37using OpenSim.Region.Environment.Scenes;
38using OpenSim.Framework; 38using OpenSim.Framework;
39 39
40namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 40namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
41{ 41{
42 /// <summary> 42 /// <summary>
43 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc. 43 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
44 /// </summary> 44 /// </summary>
45 public class AsyncCommandManager : iScriptEngineFunctionModule 45 public class AsyncCommandManager : iScriptEngineFunctionModule
46 { 46 {
47 private static Thread cmdHandlerThread; 47 private static Thread cmdHandlerThread;
48 private static int cmdHandlerThreadCycleSleepms; 48 private static int cmdHandlerThreadCycleSleepms;
49 49
50 private ScriptEngine m_ScriptEngine; 50 private ScriptEngine m_ScriptEngine;
51 51
52 public Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>> SenseEvents = 52 public Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>> SenseEvents =
53 new Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>>(); 53 new Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>>();
54 private Object SenseLock = new Object(); 54 private Object SenseLock = new Object();
55 55
56 public AsyncCommandManager(ScriptEngine _ScriptEngine) 56 public AsyncCommandManager(ScriptEngine _ScriptEngine)
57 { 57 {
58 m_ScriptEngine = _ScriptEngine; 58 m_ScriptEngine = _ScriptEngine;
59 ReadConfig(); 59 ReadConfig();
60 60
61 StartThread(); 61 StartThread();
62 } 62 }
63 63
64 private void StartThread() 64 private void StartThread()
65 { 65 {
66 if (cmdHandlerThread == null) 66 if (cmdHandlerThread == null)
67 { 67 {
68 // Start the thread that will be doing the work 68 // Start the thread that will be doing the work
69 cmdHandlerThread = new Thread(CmdHandlerThreadLoop); 69 cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
70 cmdHandlerThread.Name = "AsyncLSLCmdHandlerThread"; 70 cmdHandlerThread.Name = "AsyncLSLCmdHandlerThread";
71 cmdHandlerThread.Priority = ThreadPriority.BelowNormal; 71 cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
72 cmdHandlerThread.IsBackground = true; 72 cmdHandlerThread.IsBackground = true;
73 cmdHandlerThread.Start(); 73 cmdHandlerThread.Start();
74 OpenSim.Framework.ThreadTracker.Add(cmdHandlerThread); 74 OpenSim.Framework.ThreadTracker.Add(cmdHandlerThread);
75 } 75 }
76 } 76 }
77 77
78 public void ReadConfig() 78 public void ReadConfig()
79 { 79 {
80 cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 100); 80 cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 100);
81 } 81 }
82 82
83 ~AsyncCommandManager() 83 ~AsyncCommandManager()
84 { 84 {
85 // Shut down thread 85 // Shut down thread
86 try 86 try
87 { 87 {
88 if (cmdHandlerThread != null) 88 if (cmdHandlerThread != null)
89 { 89 {
90 if (cmdHandlerThread.IsAlive == true) 90 if (cmdHandlerThread.IsAlive == true)
91 { 91 {
92 cmdHandlerThread.Abort(); 92 cmdHandlerThread.Abort();
93 //cmdHandlerThread.Join(); 93 //cmdHandlerThread.Join();
94 } 94 }
95 } 95 }
96 } 96 }
97 catch 97 catch
98 { 98 {
99 } 99 }
100 } 100 }
101 101
102 private static void CmdHandlerThreadLoop() 102 private static void CmdHandlerThreadLoop()
103 { 103 {
104 while (true) 104 while (true)
105 { 105 {
106 try 106 try
107 { 107 {
108 while (true) 108 while (true)
109 { 109 {
110 Thread.Sleep(cmdHandlerThreadCycleSleepms); 110 Thread.Sleep(cmdHandlerThreadCycleSleepms);
111 //lock (ScriptEngine.ScriptEngines) 111 //lock (ScriptEngine.ScriptEngines)
112 //{ 112 //{
113 foreach (ScriptEngine se in new ArrayList(ScriptEngine.ScriptEngines)) 113 foreach (ScriptEngine se in new ArrayList(ScriptEngine.ScriptEngines))
114 { 114 {
115 se.m_ASYNCLSLCommandManager.DoOneCmdHandlerPass(); 115 se.m_ASYNCLSLCommandManager.DoOneCmdHandlerPass();
116 } 116 }
117 //} 117 //}
118 // Sleep before next cycle 118 // Sleep before next cycle
119 //Thread.Sleep(cmdHandlerThreadCycleSleepms); 119 //Thread.Sleep(cmdHandlerThreadCycleSleepms);
120 } 120 }
121 } 121 }
122 catch 122 catch
123 { 123 {
124 } 124 }
125 } 125 }
126 } 126 }
127 127
128 internal void DoOneCmdHandlerPass() 128 internal void DoOneCmdHandlerPass()
129 { 129 {
130 // Check timers 130 // Check timers
131 CheckTimerEvents(); 131 CheckTimerEvents();
132 // Check HttpRequests 132 // Check HttpRequests
133 CheckHttpRequests(); 133 CheckHttpRequests();
134 // Check XMLRPCRequests 134 // Check XMLRPCRequests
135 CheckXMLRPCRequests(); 135 CheckXMLRPCRequests();
136 // Check Listeners 136 // Check Listeners
137 CheckListeners(); 137 CheckListeners();
138 // Check Sensors 138 // Check Sensors
139 CheckSenseRepeaterEvents(); 139 CheckSenseRepeaterEvents();
140 } 140 }
141 141
142 /// <summary> 142 /// <summary>
143 /// Remove a specific script (and all its pending commands) 143 /// Remove a specific script (and all its pending commands)
144 /// </summary> 144 /// </summary>
145 /// <param name="localID"></param> 145 /// <param name="localID"></param>
146 /// <param name="itemID"></param> 146 /// <param name="itemID"></param>
147 public void RemoveScript(uint localID, LLUUID itemID) 147 public void RemoveScript(uint localID, LLUUID itemID)
148 { 148 {
149 // Remove a specific script 149 // Remove a specific script
150 150
151 // Remove from: Timers 151 // Remove from: Timers
152 UnSetTimerEvents(localID, itemID); 152 UnSetTimerEvents(localID, itemID);
153 // Remove from: HttpRequest 153 // Remove from: HttpRequest
154 IHttpRequests iHttpReq = 154 IHttpRequests iHttpReq =
155 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); 155 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
156 iHttpReq.StopHttpRequest(localID, itemID); 156 iHttpReq.StopHttpRequest(localID, itemID);
157 157
158 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 158 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
159 comms.DeleteListener(itemID); 159 comms.DeleteListener(itemID);
160 160
161 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 161 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
162 xmlrpc.DeleteChannels(itemID); 162 xmlrpc.DeleteChannels(itemID);
163 163
164 xmlrpc.CancelSRDRequests(itemID); 164 xmlrpc.CancelSRDRequests(itemID);
165 165
166 // Remove Sensors 166 // Remove Sensors
167 UnSetSenseRepeaterEvents(localID, itemID); 167 UnSetSenseRepeaterEvents(localID, itemID);
168 168
169 } 169 }
170 170
171 #region TIMER 171 #region TIMER
172 172
173 // 173 //
174 // TIMER 174 // TIMER
175 // 175 //
176 private class TimerClass 176 private class TimerClass
177 { 177 {
178 public uint localID; 178 public uint localID;
179 public LLUUID itemID; 179 public LLUUID itemID;
180 //public double interval; 180 //public double interval;
181 public long interval; 181 public long interval;
182 //public DateTime next; 182 //public DateTime next;
183 public long next; 183 public long next;
184 } 184 }
185 185
186 private List<TimerClass> Timers = new List<TimerClass>(); 186 private List<TimerClass> Timers = new List<TimerClass>();
187 private object TimerListLock = new object(); 187 private object TimerListLock = new object();
188 188
189 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec) 189 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
190 { 190 {
191 Console.WriteLine("SetTimerEvent"); 191 Console.WriteLine("SetTimerEvent");
192 192
193 // Always remove first, in case this is a re-set 193 // Always remove first, in case this is a re-set
194 UnSetTimerEvents(m_localID, m_itemID); 194 UnSetTimerEvents(m_localID, m_itemID);
195 if (sec == 0) // Disabling timer 195 if (sec == 0) // Disabling timer
196 return; 196 return;
197 197
198 // Add to timer 198 // Add to timer
199 TimerClass ts = new TimerClass(); 199 TimerClass ts = new TimerClass();
200 ts.localID = m_localID; 200 ts.localID = m_localID;
201 ts.itemID = m_itemID; 201 ts.itemID = m_itemID;
202 ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait 202 ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait
203 // 2193386136332921 ticks 203 // 2193386136332921 ticks
204 // 219338613 seconds 204 // 219338613 seconds
205 205
206 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 206 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
207 ts.next = DateTime.Now.Ticks + ts.interval; 207 ts.next = DateTime.Now.Ticks + ts.interval;
208 lock (TimerListLock) 208 lock (TimerListLock)
209 { 209 {
210 Timers.Add(ts); 210 Timers.Add(ts);
211 } 211 }
212 } 212 }
213 213
214 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID) 214 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
215 { 215 {
216 // Remove from timer 216 // Remove from timer
217 lock (TimerListLock) 217 lock (TimerListLock)
218 { 218 {
219 foreach (TimerClass ts in new ArrayList(Timers)) 219 foreach (TimerClass ts in new ArrayList(Timers))
220 { 220 {
221 if (ts.localID == m_localID && ts.itemID == m_itemID) 221 if (ts.localID == m_localID && ts.itemID == m_itemID)
222 Timers.Remove(ts); 222 Timers.Remove(ts);
223 } 223 }
224 } 224 }
225 225
226 // Old method: Create new list 226 // Old method: Create new list
227 //List<TimerClass> NewTimers = new List<TimerClass>(); 227 //List<TimerClass> NewTimers = new List<TimerClass>();
228 //foreach (TimerClass ts in Timers) 228 //foreach (TimerClass ts in Timers)
229 //{ 229 //{
230 // if (ts.localID != m_localID && ts.itemID != m_itemID) 230 // if (ts.localID != m_localID && ts.itemID != m_itemID)
231 // { 231 // {
232 // NewTimers.Add(ts); 232 // NewTimers.Add(ts);
233 // } 233 // }
234 //} 234 //}
235 //Timers.Clear(); 235 //Timers.Clear();
236 //Timers = NewTimers; 236 //Timers = NewTimers;
237 //} 237 //}
238 } 238 }
239 239
240 public void CheckTimerEvents() 240 public void CheckTimerEvents()
241 { 241 {
242 // Nothing to do here? 242 // Nothing to do here?
243 if (Timers.Count == 0) 243 if (Timers.Count == 0)
244 return; 244 return;
245 245
246 lock (TimerListLock) 246 lock (TimerListLock)
247 { 247 {
248 // Go through all timers 248 // Go through all timers
249 foreach (TimerClass ts in Timers) 249 foreach (TimerClass ts in Timers)
250 { 250 {
251 // Time has passed? 251 // Time has passed?
252 if (ts.next < DateTime.Now.Ticks) 252 if (ts.next < DateTime.Now.Ticks)
253 { 253 {
254// Console.WriteLine("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 254// Console.WriteLine("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
255 // Add it to queue 255 // Add it to queue
256 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", EventQueueManager.llDetectNull, 256 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", EventQueueManager.llDetectNull,
257 null); 257 null);
258 // set next interval 258 // set next interval
259 259
260 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 260 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
261 ts.next = DateTime.Now.Ticks + ts.interval; 261 ts.next = DateTime.Now.Ticks + ts.interval;
262 } 262 }
263 } 263 }
264 } 264 }
265 } 265 }
266 266
267 #endregion 267 #endregion
268 #region SENSOR 268 #region SENSOR
269 269
270 // 270 //
271 // SenseRepeater and Sensors 271 // SenseRepeater and Sensors
272 // 272 //
273 private class SenseRepeatClass 273 private class SenseRepeatClass
274 { 274 {
275 public uint localID; 275 public uint localID;
276 public LLUUID itemID; 276 public LLUUID itemID;
277 public double interval; 277 public double interval;
278 public DateTime next; 278 public DateTime next;
279 279
280 public string name; 280 public string name;
281 public LLUUID keyID; 281 public LLUUID keyID;
282 public int type; 282 public int type;
283 public double range; 283 public double range;
284 public double arc; 284 public double arc;
285 public SceneObjectPart host; 285 public SceneObjectPart host;
286 } 286 }
287 287
288 private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>(); 288 private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>();
289 private object SenseRepeatListLock = new object(); 289 private object SenseRepeatListLock = new object();
290 290
291 public void SetSenseRepeatEvent(uint m_localID, LLUUID m_itemID, 291 public void SetSenseRepeatEvent(uint m_localID, LLUUID m_itemID,
292 string name, LLUUID keyID, int type, double range, double arc, double sec,SceneObjectPart host) 292 string name, LLUUID keyID, int type, double range, double arc, double sec,SceneObjectPart host)
293 { 293 {
294 Console.WriteLine("SetSensorEvent"); 294 Console.WriteLine("SetSensorEvent");
295 295
296 // Always remove first, in case this is a re-set 296 // Always remove first, in case this is a re-set
297 UnSetSenseRepeaterEvents(m_localID, m_itemID); 297 UnSetSenseRepeaterEvents(m_localID, m_itemID);
298 if (sec == 0) // Disabling timer 298 if (sec == 0) // Disabling timer
299 return; 299 return;
300 300
301 // Add to timer 301 // Add to timer
302 SenseRepeatClass ts = new SenseRepeatClass(); 302 SenseRepeatClass ts = new SenseRepeatClass();
303 ts.localID = m_localID; 303 ts.localID = m_localID;
304 ts.itemID = m_itemID; 304 ts.itemID = m_itemID;
305 ts.interval = sec; 305 ts.interval = sec;
306 ts.name = name; 306 ts.name = name;
307 ts.keyID = keyID; 307 ts.keyID = keyID;
308 ts.type = type; 308 ts.type = type;
309 ts.range = range; 309 ts.range = range;
310 ts.arc = arc; 310 ts.arc = arc;
311 ts.host = host; 311 ts.host = host;
312 312
313 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 313 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
314 lock (SenseRepeatListLock) 314 lock (SenseRepeatListLock)
315 { 315 {
316 SenseRepeaters.Add(ts); 316 SenseRepeaters.Add(ts);
317 } 317 }
318 } 318 }
319 319
320 public void UnSetSenseRepeaterEvents(uint m_localID, LLUUID m_itemID) 320 public void UnSetSenseRepeaterEvents(uint m_localID, LLUUID m_itemID)
321 { 321 {
322 // Remove from timer 322 // Remove from timer
323 lock (SenseRepeatListLock) 323 lock (SenseRepeatListLock)
324 { 324 {
325 List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>(); 325 List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>();
326 foreach (SenseRepeatClass ts in SenseRepeaters) 326 foreach (SenseRepeatClass ts in SenseRepeaters)
327 { 327 {
328 if (ts.localID != m_localID && ts.itemID != m_itemID) 328 if (ts.localID != m_localID && ts.itemID != m_itemID)
329 { 329 {
330 NewSensors.Add(ts); 330 NewSensors.Add(ts);
331 } 331 }
332 } 332 }
333 SenseRepeaters.Clear(); 333 SenseRepeaters.Clear();
334 SenseRepeaters = NewSensors; 334 SenseRepeaters = NewSensors;
335 } 335 }
336 } 336 }
337 337
338 public void CheckSenseRepeaterEvents() 338 public void CheckSenseRepeaterEvents()
339 { 339 {
340 // Nothing to do here? 340 // Nothing to do here?
341 if (SenseRepeaters.Count == 0) 341 if (SenseRepeaters.Count == 0)
342 return; 342 return;
343 343
344 lock (SenseRepeatListLock) 344 lock (SenseRepeatListLock)
345 { 345 {
346 // Go through all timers 346 // Go through all timers
347 foreach (SenseRepeatClass ts in SenseRepeaters) 347 foreach (SenseRepeatClass ts in SenseRepeaters)
348 { 348 {
349 // Time has passed? 349 // Time has passed?
350 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) 350 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
351 { 351 {
352 SensorSweep(ts); 352 SensorSweep(ts);
353 // set next interval 353 // set next interval
354 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 354 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
355 } 355 }
356 } 356 }
357 } // lock 357 } // lock
358 } 358 }
359 359
360 public void SenseOnce(uint m_localID, LLUUID m_itemID, 360 public void SenseOnce(uint m_localID, LLUUID m_itemID,
361 string name, LLUUID keyID, int type, double range, double arc, SceneObjectPart host) 361 string name, LLUUID keyID, int type, double range, double arc, SceneObjectPart host)
362 { 362 {
363 // Add to timer 363 // Add to timer
364 SenseRepeatClass ts = new SenseRepeatClass(); 364 SenseRepeatClass ts = new SenseRepeatClass();
365 ts.localID = m_localID; 365 ts.localID = m_localID;
366 ts.itemID = m_itemID; 366 ts.itemID = m_itemID;
367 ts.interval = 0; 367 ts.interval = 0;
368 ts.name = name; 368 ts.name = name;
369 ts.keyID = keyID; 369 ts.keyID = keyID;
370 ts.type = type; 370 ts.type = type;
371 ts.range = range; 371 ts.range = range;
372 ts.arc = arc; 372 ts.arc = arc;
373 ts.host = host; 373 ts.host = host;
374 SensorSweep(ts); 374 SensorSweep(ts);
375 } 375 }
376 376
377 public LSL_Types.list GetSensorList(uint m_localID, LLUUID m_itemID) 377 public LSL_Types.list GetSensorList(uint m_localID, LLUUID m_itemID)
378 { 378 {
379 lock (SenseLock) 379 lock (SenseLock)
380 { 380 {
381 Dictionary<LLUUID, LSL_Types.list> Obj = null; 381 Dictionary<LLUUID, LSL_Types.list> Obj = null;
382 if (!SenseEvents.TryGetValue(m_localID, out Obj)) 382 if (!SenseEvents.TryGetValue(m_localID, out Obj))
383 { 383 {
384 m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing localID: " + m_localID); 384 m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing localID: " + m_localID);
385 return null; 385 return null;
386 } 386 }
387 lock (Obj) 387 lock (Obj)
388 { 388 {
389 // Get script 389 // Get script
390 LSL_Types.list SenseList = null; 390 LSL_Types.list SenseList = null;
391 if (!Obj.TryGetValue(m_itemID, out SenseList)) 391 if (!Obj.TryGetValue(m_itemID, out SenseList))
392 { 392 {
393 m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing itemID: " + m_itemID); 393 m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing itemID: " + m_itemID);
394 return null; 394 return null;
395 } 395 }
396 return SenseList; 396 return SenseList;
397 } 397 }
398 } 398 }
399 399
400 } 400 }
401 401
402 private void SensorSweep(SenseRepeatClass ts) 402 private void SensorSweep(SenseRepeatClass ts)
403 { 403 {
404 //m_ScriptEngine.Log.Info("[AsyncLSL]:Enter SensorSweep"); 404 //m_ScriptEngine.Log.Info("[AsyncLSL]:Enter SensorSweep");
405 SceneObjectPart SensePoint =ts.host; 405 SceneObjectPart SensePoint =ts.host;
406 406
407 if (SensePoint == null) 407 if (SensePoint == null)
408 { 408 {
409 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep (SensePoint == null) for "+ts.itemID.ToString()); 409 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep (SensePoint == null) for "+ts.itemID.ToString());
410 return; 410 return;
411 } 411 }
412 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep Scan"); 412 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep Scan");
413 413
414 LLVector3 sensorPos = SensePoint.AbsolutePosition; 414 LLVector3 sensorPos = SensePoint.AbsolutePosition;
415 LLVector3 regionPos = new LLVector3(m_ScriptEngine.World.RegionInfo.RegionLocX * Constants.RegionSize, m_ScriptEngine.World.RegionInfo.RegionLocY * Constants.RegionSize, 0); 415 LLVector3 regionPos = new LLVector3(m_ScriptEngine.World.RegionInfo.RegionLocX * Constants.RegionSize, m_ScriptEngine.World.RegionInfo.RegionLocY * Constants.RegionSize, 0);
416 LLVector3 fromRegionPos = sensorPos + regionPos; 416 LLVector3 fromRegionPos = sensorPos + regionPos;
417 417
418 LLQuaternion q = SensePoint.RotationOffset; 418 LLQuaternion q = SensePoint.RotationOffset;
419 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 419 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
420 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 420 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
421 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 421 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
422 422
423 // Here we should do some smart culling ... 423 // Here we should do some smart culling ...
424 // math seems quicker than strings so try that first 424 // math seems quicker than strings so try that first
425 LSL_Types.list SensedObjects = new LSL_Types.list(); 425 LSL_Types.list SensedObjects = new LSL_Types.list();
426 LSL_Types.Vector3 ZeroVector = new LSL_Types.Vector3(0, 0, 0); 426 LSL_Types.Vector3 ZeroVector = new LSL_Types.Vector3(0, 0, 0);
427 427
428 foreach (EntityBase ent in m_ScriptEngine.World.Entities.Values) 428 foreach (EntityBase ent in m_ScriptEngine.World.Entities.Values)
429 { 429 {
430 430
431 LLVector3 toRegionPos = ent.AbsolutePosition + regionPos; 431 LLVector3 toRegionPos = ent.AbsolutePosition + regionPos;
432 double dis = Math.Abs((double) Util.GetDistanceTo(toRegionPos, fromRegionPos)); 432 double dis = Math.Abs((double) Util.GetDistanceTo(toRegionPos, fromRegionPos));
433 if (dis <= ts.range) 433 if (dis <= ts.range)
434 { 434 {
435 // In Range, is it the right Type ? 435 // In Range, is it the right Type ?
436 int objtype = 0; 436 int objtype = 0;
437 437
438 if (m_ScriptEngine.World.GetScenePresence(ent.UUID) != null) objtype |= 0x01; // actor 438 if (m_ScriptEngine.World.GetScenePresence(ent.UUID) != null) objtype |= 0x01; // actor
439 if (ent.Velocity.Equals(ZeroVector)) 439 if (ent.Velocity.Equals(ZeroVector))
440 objtype |= 0x04; // passive non-moving 440 objtype |= 0x04; // passive non-moving
441 else 441 else
442 objtype |= 0x02; // active moving 442 objtype |= 0x02; // active moving
443 if (ent is IScript) objtype |= 0x08; // Scripted. It COULD have one hidden ... 443 if (ent is IScript) objtype |= 0x08; // Scripted. It COULD have one hidden ...
444 444
445 if ( ((ts.type & objtype) != 0 ) ||((ts.type & objtype) == ts.type )) 445 if ( ((ts.type & objtype) != 0 ) ||((ts.type & objtype) == ts.type ))
446 { 446 {
447 // docs claim AGENT|ACTIVE should find agent objects OR active objects 447 // docs claim AGENT|ACTIVE should find agent objects OR active objects
448 // so the bitwise AND with object type should be non-zero 448 // so the bitwise AND with object type should be non-zero
449 449
450 // Right type too, what about the other params , key and name ? 450 // Right type too, what about the other params , key and name ?
451 bool keep = true; 451 bool keep = true;
452 if (ts.arc != Math.PI) 452 if (ts.arc != Math.PI)
453 { 453 {
454 // not omni-directional. Can you see it ? 454 // not omni-directional. Can you see it ?
455 // vec forward_dir = llRot2Fwd(llGetRot()) 455 // vec forward_dir = llRot2Fwd(llGetRot())
456 // vec obj_dir = toRegionPos-fromRegionPos 456 // vec obj_dir = toRegionPos-fromRegionPos
457 // dot=dot(forward_dir,obj_dir) 457 // dot=dot(forward_dir,obj_dir)
458 // mag_fwd = mag(forward_dir) 458 // mag_fwd = mag(forward_dir)
459 // mag_obj = mag(obj_dir) 459 // mag_obj = mag(obj_dir)
460 // ang = acos( dot /(mag_fwd*mag_obj)) 460 // ang = acos( dot /(mag_fwd*mag_obj))
461 double ang_obj = 0; 461 double ang_obj = 0;
462 try 462 try
463 { 463 {
464 LLVector3 diff =toRegionPos - fromRegionPos; 464 LLVector3 diff =toRegionPos - fromRegionPos;
465 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); 465 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
466 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); 466 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
467 double mag_obj = LSL_Types.Vector3.Mag(obj_dir); 467 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
468 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); 468 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
469 } 469 }
470 catch 470 catch
471 { 471 {
472 } 472 }
473 473
474 if (ang_obj > ts.arc) keep = false; 474 if (ang_obj > ts.arc) keep = false;
475 } 475 }
476 476
477 if (keep && (ts.name.Length > 0) && (ts.name != ent.Name)) 477 if (keep && (ts.name.Length > 0) && (ts.name != ent.Name))
478 { 478 {
479 keep = false; 479 keep = false;
480 } 480 }
481 481
482 if (keep && (ts.keyID != null) && (ts.keyID != LLUUID.Zero) && (ts.keyID != ent.UUID)) 482 if (keep && (ts.keyID != null) && (ts.keyID != LLUUID.Zero) && (ts.keyID != ent.UUID))
483 { 483 {
484 keep = false; 484 keep = false;
485 } 485 }
486 if (keep==true) SensedObjects.Add(ent.UUID); 486 if (keep==true) SensedObjects.Add(ent.UUID);
487 } 487 }
488 } 488 }
489 } 489 }
490 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep SenseLock"); 490 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep SenseLock");
491 491
492 lock (SenseLock) 492 lock (SenseLock)
493 { 493 {
494 // Create object if it doesn't exist 494 // Create object if it doesn't exist
495 if (SenseEvents.ContainsKey(ts.localID) == false) 495 if (SenseEvents.ContainsKey(ts.localID) == false)
496 { 496 {
497 SenseEvents.Add(ts.localID, new Dictionary<LLUUID, LSL_Types.list>()); 497 SenseEvents.Add(ts.localID, new Dictionary<LLUUID, LSL_Types.list>());
498 } 498 }
499 // clear if previous traces exist 499 // clear if previous traces exist
500 Dictionary<LLUUID, LSL_Types.list> Obj; 500 Dictionary<LLUUID, LSL_Types.list> Obj;
501 SenseEvents.TryGetValue(ts.localID, out Obj); 501 SenseEvents.TryGetValue(ts.localID, out Obj);
502 if (Obj.ContainsKey(ts.itemID) == true) 502 if (Obj.ContainsKey(ts.itemID) == true)
503 Obj.Remove(ts.itemID); 503 Obj.Remove(ts.itemID);
504 504
505 // note list may be zero length 505 // note list may be zero length
506 Obj.Add(ts.itemID, SensedObjects); 506 Obj.Add(ts.itemID, SensedObjects);
507 507
508 if (SensedObjects.Length == 0) 508 if (SensedObjects.Length == 0)
509 { 509 {
510 // send a "no_sensor" 510 // send a "no_sensor"
511 // Add it to queue 511 // Add it to queue
512 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "no_sensor", EventQueueManager.llDetectNull, 512 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "no_sensor", EventQueueManager.llDetectNull,
513 new object[] {}); 513 new object[] {});
514 } 514 }
515 else 515 else
516 { 516 {
517 517
518 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "sensor", EventQueueManager.llDetectNull, 518 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "sensor", EventQueueManager.llDetectNull,
519 new object[] { SensedObjects.Length }); 519 new object[] { SensedObjects.Length });
520 } 520 }
521 } 521 }
522 } 522 }
523 #endregion 523 #endregion
524 524
525 #region HTTP REQUEST 525 #region HTTP REQUEST
526 526
527 public void CheckHttpRequests() 527 public void CheckHttpRequests()
528 { 528 {
529 if (m_ScriptEngine.World == null) 529 if (m_ScriptEngine.World == null)
530 return; 530 return;
531 531
532 IHttpRequests iHttpReq = 532 IHttpRequests iHttpReq =
533 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); 533 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
534 534
535 HttpRequestClass httpInfo = null; 535 HttpRequestClass httpInfo = null;
536 536
537 if (iHttpReq != null) 537 if (iHttpReq != null)
538 httpInfo = iHttpReq.GetNextCompletedRequest(); 538 httpInfo = iHttpReq.GetNextCompletedRequest();
539 539
540 while (httpInfo != null) 540 while (httpInfo != null)
541 { 541 {
542 //m_ScriptEngine.Log.Info("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status); 542 //m_ScriptEngine.Log.Info("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status);
543 543
544 // Deliver data to prim's remote_data handler 544 // Deliver data to prim's remote_data handler
545 // 545 //
546 // TODO: Returning null for metadata, since the lsl function 546 // TODO: Returning null for metadata, since the lsl function
547 // only returns the byte for HTTP_BODY_TRUNCATED, which is not 547 // only returns the byte for HTTP_BODY_TRUNCATED, which is not
548 // implemented here yet anyway. Should be fixed if/when maxsize 548 // implemented here yet anyway. Should be fixed if/when maxsize
549 // is supported 549 // is supported
550 550
551 if (m_ScriptEngine.m_ScriptManager.GetScript(httpInfo.localID, httpInfo.itemID) != null) 551 if (m_ScriptEngine.m_ScriptManager.GetScript(httpInfo.localID, httpInfo.itemID) != null)
552 { 552 {
553 iHttpReq.RemoveCompletedRequest(httpInfo.reqID); 553 iHttpReq.RemoveCompletedRequest(httpInfo.reqID);
554 object[] resobj = new object[] 554 object[] resobj = new object[]
555 { 555 {
556 httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body 556 httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
557 }; 557 };
558 558
559 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 559 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
560 httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj 560 httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
561 ); 561 );
562 //Thread.Sleep(2500); 562 //Thread.Sleep(2500);
563 } 563 }
564 564
565 httpInfo = iHttpReq.GetNextCompletedRequest(); 565 httpInfo = iHttpReq.GetNextCompletedRequest();
566 } 566 }
567 } 567 }
568 568
569 #endregion 569 #endregion
570 570
571 #region Check llRemoteData channels 571 #region Check llRemoteData channels
572 572
573 public void CheckXMLRPCRequests() 573 public void CheckXMLRPCRequests()
574 { 574 {
575 if (m_ScriptEngine.World == null) 575 if (m_ScriptEngine.World == null)
576 return; 576 return;
577 577
578 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 578 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
579 579
580 if (xmlrpc != null) 580 if (xmlrpc != null)
581 { 581 {
582 RPCRequestInfo rInfo = xmlrpc.GetNextCompletedRequest(); 582 RPCRequestInfo rInfo = xmlrpc.GetNextCompletedRequest();
583 583
584 while (rInfo != null) 584 while (rInfo != null)
585 { 585 {
586 if (m_ScriptEngine.m_ScriptManager.GetScript(rInfo.GetLocalID(), rInfo.GetItemID()) != null) 586 if (m_ScriptEngine.m_ScriptManager.GetScript(rInfo.GetLocalID(), rInfo.GetItemID()) != null)
587 { 587 {
588 xmlrpc.RemoveCompletedRequest(rInfo.GetMessageID()); 588 xmlrpc.RemoveCompletedRequest(rInfo.GetMessageID());
589 589
590 //Deliver data to prim's remote_data handler 590 //Deliver data to prim's remote_data handler
591 object[] resobj = new object[] 591 object[] resobj = new object[]
592 { 592 {
593 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), String.Empty, 593 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), String.Empty,
594 rInfo.GetIntValue(), 594 rInfo.GetIntValue(),
595 rInfo.GetStrVal() 595 rInfo.GetStrVal()
596 }; 596 };
597 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 597 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
598 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj 598 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj
599 ); 599 );
600 } 600 }
601 601
602 rInfo = xmlrpc.GetNextCompletedRequest(); 602 rInfo = xmlrpc.GetNextCompletedRequest();
603 } 603 }
604 604
605 SendRemoteDataRequest srdInfo = xmlrpc.GetNextCompletedSRDRequest(); 605 SendRemoteDataRequest srdInfo = xmlrpc.GetNextCompletedSRDRequest();
606 606
607 while (srdInfo != null) 607 while (srdInfo != null)
608 { 608 {
609 if (m_ScriptEngine.m_ScriptManager.GetScript(srdInfo.m_localID, srdInfo.m_itemID) != null) 609 if (m_ScriptEngine.m_ScriptManager.GetScript(srdInfo.m_localID, srdInfo.m_itemID) != null)
610 { 610 {
611 xmlrpc.RemoveCompletedSRDRequest(srdInfo.GetReqID()); 611 xmlrpc.RemoveCompletedSRDRequest(srdInfo.GetReqID());
612 612
613 //Deliver data to prim's remote_data handler 613 //Deliver data to prim's remote_data handler
614 object[] resobj = new object[] 614 object[] resobj = new object[]
615 { 615 {
616 3, srdInfo.channel.ToString(), srdInfo.GetReqID().ToString(), String.Empty, 616 3, srdInfo.channel.ToString(), srdInfo.GetReqID().ToString(), String.Empty,
617 srdInfo.idata, 617 srdInfo.idata,
618 srdInfo.sdata 618 srdInfo.sdata
619 }; 619 };
620 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 620 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
621 srdInfo.m_localID, srdInfo.m_itemID, "remote_data", EventQueueManager.llDetectNull, resobj 621 srdInfo.m_localID, srdInfo.m_itemID, "remote_data", EventQueueManager.llDetectNull, resobj
622 ); 622 );
623 } 623 }
624 624
625 srdInfo = xmlrpc.GetNextCompletedSRDRequest(); 625 srdInfo = xmlrpc.GetNextCompletedSRDRequest();
626 } 626 }
627 } 627 }
628 } 628 }
629 629
630 #endregion 630 #endregion
631 631
632 #region Check llListeners 632 #region Check llListeners
633 633
634 public void CheckListeners() 634 public void CheckListeners()
635 { 635 {
636 if (m_ScriptEngine.World == null) 636 if (m_ScriptEngine.World == null)
637 return; 637 return;
638 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 638 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
639 639
640 if (comms != null) 640 if (comms != null)
641 { 641 {
642 while (comms.HasMessages()) 642 while (comms.HasMessages())
643 { 643 {
644 if (m_ScriptEngine.m_ScriptManager.GetScript( 644 if (m_ScriptEngine.m_ScriptManager.GetScript(
645 comms.PeekNextMessageLocalID(), comms.PeekNextMessageItemID()) != null) 645 comms.PeekNextMessageLocalID(), comms.PeekNextMessageItemID()) != null)
646 { 646 {
647 ListenerInfo lInfo = comms.GetNextMessage(); 647 ListenerInfo lInfo = comms.GetNextMessage();
648 648
649 //Deliver data to prim's listen handler 649 //Deliver data to prim's listen handler
650 object[] resobj = new object[] 650 object[] resobj = new object[]
651 { 651 {
652 //lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage() 652 //lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
653 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetSourceItemID().ToString(), lInfo.GetMessage() 653 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetSourceItemID().ToString(), lInfo.GetMessage()
654 }; 654 };
655 655
656 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 656 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
657 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj 657 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj
658 ); 658 );
659 } 659 }
660 } 660 }
661 } 661 }
662 } 662 }
663 663
664 #endregion 664 #endregion
665 665
666 /// <summary> 666 /// <summary>
667 /// If set to true then threads and stuff should try to make a graceful exit 667 /// If set to true then threads and stuff should try to make a graceful exit
668 /// </summary> 668 /// </summary>
669 public bool PleaseShutdown 669 public bool PleaseShutdown
670 { 670 {
671 get { return _PleaseShutdown; } 671 get { return _PleaseShutdown; }
672 set { _PleaseShutdown = value; } 672 set { _PleaseShutdown = value; }
673 } 673 }
674 private bool _PleaseShutdown = false; 674 private bool _PleaseShutdown = false;
675 675
676 } 676 }
677} 677}