aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs
diff options
context:
space:
mode:
authorTedd Hansen2008-01-12 14:30:22 +0000
committerTedd Hansen2008-01-12 14:30:22 +0000
commitbacbade369a5244f9bcc611488b59f3bd4c8a564 (patch)
tree2cd909eff401066a69dba96615cbf736fdd73be5 /OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs
parent* Trying something to see if it helps teleports and border crossings (diff)
downloadopensim-SC-bacbade369a5244f9bcc611488b59f3bd4c8a564.zip
opensim-SC-bacbade369a5244f9bcc611488b59f3bd4c8a564.tar.gz
opensim-SC-bacbade369a5244f9bcc611488b59f3bd4c8a564.tar.bz2
opensim-SC-bacbade369a5244f9bcc611488b59f3bd4c8a564.tar.xz
Major reorganizing of DotNetEngine. Moved common script engine parts to ScriptEngine.Common, only .Net-specific code in DotNetEngine. AppDomains, event handling, event execution queue and multithreading, script load/unload queue, etc has been moved to ScriptEngine.Common.
Loads of things has been put into interfaces instead of the specific class. We are now one step closer to ScriptServer, and its very easy to implement new script languages. Just a few lines required to make them a OpenSim script module with all its glory.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs295
1 files changed, 295 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs
new file mode 100644
index 0000000..94241eb
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs
@@ -0,0 +1,295 @@
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 OpenSim 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*/
28
29using System;
30using System.Collections.Generic;
31using System.Threading;
32using libsecondlife;
33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Modules;
35
36namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
37{
38 /// <summary>
39 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
40 /// </summary>
41 public class LSLLongCmdHandler
42 {
43 private Thread cmdHandlerThread;
44 private int cmdHandlerThreadCycleSleepms = 100;
45
46 private ScriptEngine m_ScriptEngine;
47
48 public LSLLongCmdHandler(ScriptEngine _ScriptEngine)
49 {
50 m_ScriptEngine = _ScriptEngine;
51
52 // Start the thread that will be doing the work
53 cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
54 cmdHandlerThread.Name = "CmdHandlerThread";
55 cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
56 cmdHandlerThread.IsBackground = true;
57 cmdHandlerThread.Start();
58 }
59
60 ~LSLLongCmdHandler()
61 {
62 // Shut down thread
63 try
64 {
65 if (cmdHandlerThread != null)
66 {
67 if (cmdHandlerThread.IsAlive == true)
68 {
69 cmdHandlerThread.Abort();
70 cmdHandlerThread.Join();
71 }
72 }
73 }
74 catch
75 {
76 }
77 }
78
79 private void CmdHandlerThreadLoop()
80 {
81 while (true)
82 {
83 // Check timers
84 CheckTimerEvents();
85 Thread.Sleep(25);
86 // Check HttpRequests
87 CheckHttpRequests();
88 Thread.Sleep(25);
89 // Check XMLRPCRequests
90 CheckXMLRPCRequests();
91 Thread.Sleep(25);
92 // Check Listeners
93 CheckListeners();
94 Thread.Sleep(25);
95
96 // Sleep before next cycle
97 //Thread.Sleep(cmdHandlerThreadCycleSleepms);
98 }
99 }
100
101 /// <summary>
102 /// Remove a specific script (and all its pending commands)
103 /// </summary>
104 /// <param name="m_localID"></param>
105 /// <param name="m_itemID"></param>
106 public void RemoveScript(uint localID, LLUUID itemID)
107 {
108 // Remove a specific script
109
110 // Remove from: Timers
111 UnSetTimerEvents(localID, itemID);
112 // Remove from: HttpRequest
113 IHttpRequests iHttpReq =
114 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
115 iHttpReq.StopHttpRequest(localID, itemID);
116 }
117
118 #region TIMER
119
120 //
121 // TIMER
122 //
123 private class TimerClass
124 {
125 public uint localID;
126 public LLUUID itemID;
127 public double interval;
128 public DateTime next;
129 }
130
131 private List<TimerClass> Timers = new List<TimerClass>();
132 private object TimerListLock = new object();
133
134 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
135 {
136 Console.WriteLine("SetTimerEvent");
137
138 // Always remove first, in case this is a re-set
139 UnSetTimerEvents(m_localID, m_itemID);
140 if (sec == 0) // Disabling timer
141 return;
142
143 // Add to timer
144 TimerClass ts = new TimerClass();
145 ts.localID = m_localID;
146 ts.itemID = m_itemID;
147 ts.interval = sec;
148 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
149 lock (TimerListLock)
150 {
151 Timers.Add(ts);
152 }
153 }
154
155 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
156 {
157 // Remove from timer
158 lock (TimerListLock)
159 {
160 List<TimerClass> NewTimers = new List<TimerClass>();
161 foreach (TimerClass ts in Timers)
162 {
163 if (ts.localID != m_localID && ts.itemID != m_itemID)
164 {
165 NewTimers.Add(ts);
166 }
167 }
168 Timers.Clear();
169 Timers = NewTimers;
170 }
171 }
172
173 public void CheckTimerEvents()
174 {
175 // Nothing to do here?
176 if (Timers.Count == 0)
177 return;
178
179 lock (TimerListLock)
180 {
181 // Go through all timers
182 foreach (TimerClass ts in Timers)
183 {
184 // Time has passed?
185 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
186 {
187 // Add it to queue
188 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer",
189 new object[] {});
190 // set next interval
191
192
193 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
194 }
195 }
196 } // lock
197 }
198
199 #endregion
200
201 #region HTTP REQUEST
202
203 public void CheckHttpRequests()
204 {
205 if (m_ScriptEngine.World == null)
206 return;
207
208 IHttpRequests iHttpReq =
209 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
210
211 HttpRequestClass httpInfo = null;
212
213 if (iHttpReq != null)
214 httpInfo = iHttpReq.GetNextCompletedRequest();
215
216 while (httpInfo != null)
217 {
218 //Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status);
219
220 // Deliver data to prim's remote_data handler
221 //
222 // TODO: Returning null for metadata, since the lsl function
223 // only returns the byte for HTTP_BODY_TRUNCATED, which is not
224 // implemented here yet anyway. Should be fixed if/when maxsize
225 // is supported
226
227 object[] resobj = new object[]
228 {
229 httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
230 };
231
232 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
233 httpInfo.localID, httpInfo.itemID, "http_response", resobj
234 );
235
236 httpInfo.Stop();
237 httpInfo = null;
238
239 httpInfo = iHttpReq.GetNextCompletedRequest();
240 }
241 }
242
243 #endregion
244
245 public void CheckXMLRPCRequests()
246 {
247 if (m_ScriptEngine.World == null)
248 return;
249
250 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
251
252 if (xmlrpc != null)
253 {
254 while (xmlrpc.hasRequests())
255 {
256 RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
257 //Console.WriteLine("PICKED REQUEST");
258
259 //Deliver data to prim's remote_data handler
260 object[] resobj = new object[]
261 {
262 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), "",
263 rInfo.GetIntValue(),
264 rInfo.GetStrVal()
265 };
266 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
267 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", resobj
268 );
269 }
270 }
271 }
272
273 public void CheckListeners()
274 {
275 if (m_ScriptEngine.World == null)
276 return;
277 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
278
279 while (comms.HasMessages())
280 {
281 ListenerInfo lInfo = comms.GetNextMessage();
282
283 //Deliver data to prim's listen handler
284 object[] resobj = new object[]
285 {
286 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
287 };
288
289 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
290 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", resobj
291 );
292 }
293 }
294 }
295} \ No newline at end of file