aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs')
-rw-r--r--OpenSim/Grid/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs321
1 files changed, 321 insertions, 0 deletions
diff --git a/OpenSim/Grid/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs b/OpenSim/Grid/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs
new file mode 100644
index 0000000..5b92ff0
--- /dev/null
+++ b/OpenSim/Grid/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs
@@ -0,0 +1,321 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5using libsecondlife;
6using OpenSim.Region.ScriptEngine.Common;
7using OpenSim.Region.Environment.Modules;
8using OpenSim.Region.Environment.Interfaces;
9
10namespace OpenSim.Region.ScriptEngine.DotNetEngine
11{
12 /// <summary>
13 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
14 /// </summary>
15 class LSLLongCmdHandler
16 {
17 private Thread cmdHandlerThread;
18 private int cmdHandlerThreadCycleSleepms = 100;
19
20 private ScriptEngine m_ScriptEngine;
21 public LSLLongCmdHandler(ScriptEngine _ScriptEngine)
22 {
23 m_ScriptEngine = _ScriptEngine;
24
25 // Start the thread that will be doing the work
26 cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
27 cmdHandlerThread.Name = "CmdHandlerThread";
28 cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
29 cmdHandlerThread.IsBackground = true;
30 cmdHandlerThread.Start();
31
32 }
33 ~LSLLongCmdHandler()
34 {
35 // Shut down thread
36 try
37 {
38 if (cmdHandlerThread != null)
39 {
40 if (cmdHandlerThread.IsAlive == true)
41 {
42 cmdHandlerThread.Abort();
43 cmdHandlerThread.Join();
44 }
45 }
46 }
47 catch { }
48 }
49
50 private void CmdHandlerThreadLoop()
51 {
52 while (true)
53 {
54 // Check timers
55 CheckTimerEvents();
56 Thread.Sleep(25);
57 // Check HttpRequests
58 CheckHttpRequests();
59 Thread.Sleep(25);
60 // Check XMLRPCRequests
61 CheckXMLRPCRequests();
62 Thread.Sleep(25);
63 // Check Listeners
64 CheckListeners();
65 Thread.Sleep(25);
66
67 // Sleep before next cycle
68 //Thread.Sleep(cmdHandlerThreadCycleSleepms);
69 }
70 }
71
72 /// <summary>
73 /// Remove a specific script (and all its pending commands)
74 /// </summary>
75 /// <param name="m_localID"></param>
76 /// <param name="m_itemID"></param>
77 public void RemoveScript(uint localID, LLUUID itemID)
78 {
79 // Remove a specific script
80
81 // Remove from: Timers
82 UnSetTimerEvents(localID, itemID);
83 // Remove from: HttpRequest
84 StopHttpRequest(localID, itemID);
85 }
86
87 #region TIMER
88
89 //
90 // TIMER
91 //
92 private class TimerClass
93 {
94 public uint localID;
95 public LLUUID itemID;
96 public double interval;
97 public DateTime next;
98 }
99 private List<TimerClass> Timers = new List<TimerClass>();
100 private object TimerListLock = new object();
101 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
102 {
103 Console.WriteLine("SetTimerEvent");
104
105 // Always remove first, in case this is a re-set
106 UnSetTimerEvents(m_localID, m_itemID);
107 if (sec == 0) // Disabling timer
108 return;
109
110 // Add to timer
111 TimerClass ts = new TimerClass();
112 ts.localID = m_localID;
113 ts.itemID = m_itemID;
114 ts.interval = sec;
115 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
116 lock (TimerListLock)
117 {
118 Timers.Add(ts);
119 }
120 }
121 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
122 {
123 // Remove from timer
124 lock (TimerListLock)
125 {
126 List<TimerClass> NewTimers = new List<TimerClass>();
127 foreach (TimerClass ts in Timers)
128 {
129 if (ts.localID != m_localID && ts.itemID != m_itemID)
130 {
131 NewTimers.Add(ts);
132 }
133 }
134 Timers.Clear();
135 Timers = NewTimers;
136 }
137 }
138 public void CheckTimerEvents()
139 {
140 // Nothing to do here?
141 if (Timers.Count == 0)
142 return;
143
144 lock (TimerListLock)
145 {
146
147 // Go through all timers
148 foreach (TimerClass ts in Timers)
149 {
150 // Time has passed?
151 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
152 {
153 // Add it to queue
154 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", new object[] { });
155 // set next interval
156
157
158 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
159 }
160 }
161 } // lock
162 }
163 #endregion
164
165 #region HTTP REQUEST
166
167 //
168 // HTTP REAQUEST
169 //
170 private class HttpClass
171 {
172 public uint localID;
173 public LLUUID itemID;
174 public string url;
175 public List<string> parameters;
176 public string body;
177 public DateTime next;
178
179 public string response_request_id;
180 public int response_status;
181 public List<string> response_metadata;
182 public string response_body;
183
184 public void SendRequest()
185 {
186 // TODO: SEND REQUEST!!!
187 }
188 public void Stop()
189 {
190 // TODO: Cancel any ongoing request
191 }
192 public bool CheckResponse()
193 {
194 // TODO: Check if we got a response yet, return true if so -- false if not
195 return true;
196
197 // TODO: If we got a response, set the following then return true
198 //response_request_id
199 //response_status
200 //response_metadata
201 //response_body
202
203 }
204 }
205 private List<HttpClass> HttpRequests = new List<HttpClass>();
206 private object HttpListLock = new object();
207 public void StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body)
208 {
209 Console.WriteLine("StartHttpRequest");
210
211 HttpClass htc = new HttpClass();
212 htc.localID = localID;
213 htc.itemID = itemID;
214 htc.url = url;
215 htc.parameters = parameters;
216 htc.body = body;
217 lock (HttpListLock)
218 {
219
220 //ADD REQUEST
221 HttpRequests.Add(htc);
222 }
223 }
224 public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
225 {
226 // Remove from list
227 lock (HttpListLock)
228 {
229 List<HttpClass> NewHttpList = new List<HttpClass>();
230 foreach (HttpClass ts in HttpRequests)
231 {
232 if (ts.localID != m_localID && ts.itemID != m_itemID)
233 {
234 // Keeping this one
235 NewHttpList.Add(ts);
236 }
237 else
238 {
239 // Shutting this one down
240 ts.Stop();
241 }
242 }
243 HttpRequests.Clear();
244 HttpRequests = NewHttpList;
245 }
246 }
247 public void CheckHttpRequests()
248 {
249 // Nothing to do here?
250 if (HttpRequests.Count == 0)
251 return;
252
253 lock (HttpListLock)
254 {
255 foreach (HttpClass ts in HttpRequests)
256 {
257
258 if (ts.CheckResponse() == true)
259 {
260 // Add it to event queue
261 //key request_id, integer status, list metadata, string body
262 object[] resobj = new object[] { ts.response_request_id, ts.response_status, ts.response_metadata, ts.response_body };
263 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "http_response", resobj);
264 // Now stop it
265 StopHttpRequest(ts.localID, ts.itemID);
266 }
267 }
268 } // lock
269 }
270 #endregion
271
272 public void CheckXMLRPCRequests()
273 {
274
275 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
276
277 while (xmlrpc.hasRequests())
278 {
279 RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
280 System.Console.WriteLine("PICKED REQUEST");
281
282 //Deliver data to prim's remote_data handler
283 object[] resobj = new object[] {
284 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), "", rInfo.GetIntValue(), rInfo.GetStrVal()
285 };
286 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
287 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", resobj
288 );
289
290 }
291
292 }
293
294 public void CheckListeners()
295 {
296
297 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
298
299 while (comms.HasMessages())
300 {
301 ListenerInfo lInfo = comms.GetNextMessage();
302 System.Console.WriteLine("PICKED LISTENER");
303
304 //Deliver data to prim's listen handler
305 object[] resobj = new object[] {
306 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
307 };
308
309 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
310 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", resobj
311 );
312
313 }
314
315 }
316
317
318
319
320 }
321}