diff options
author | Tedd Hansen | 2008-01-12 14:30:22 +0000 |
---|---|---|
committer | Tedd Hansen | 2008-01-12 14:30:22 +0000 |
commit | bacbade369a5244f9bcc611488b59f3bd4c8a564 (patch) | |
tree | 2cd909eff401066a69dba96615cbf736fdd73be5 /OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs | |
parent | * Trying something to see if it helps teleports and border crossings (diff) | |
download | opensim-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/DotNetEngine/ScriptManager.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs | 438 |
1 files changed, 72 insertions, 366 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs index 223bb8f..0c28ac7 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs | |||
@@ -35,421 +35,127 @@ using System.Threading; | |||
35 | using libsecondlife; | 35 | using libsecondlife; |
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Region.Environment.Scenes; | 37 | using OpenSim.Region.Environment.Scenes; |
38 | using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler; | 38 | using OpenSim.Region.ScriptEngine.Common; |
39 | using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL; | 39 | using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL; |
40 | 40 | ||
41 | namespace OpenSim.Region.ScriptEngine.DotNetEngine | 41 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
42 | { | 42 | { |
43 | /// <summary> | 43 | public class ScriptManager : OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptManager |
44 | /// Loads scripts | ||
45 | /// Compiles them if necessary | ||
46 | /// Execute functions for EventQueueManager (Sends them to script on other AppDomain for execution) | ||
47 | /// </summary> | ||
48 | /// | ||
49 | |||
50 | // This class is as close as you get to the script without being inside script class. It handles all the dirty work for other classes. | ||
51 | // * Keeps track of running scripts | ||
52 | // * Compiles script if necessary (through "Compiler") | ||
53 | // * Loads script (through "AppDomainManager" called from for example "EventQueueManager") | ||
54 | // * Executes functions inside script (called from for example "EventQueueManager" class) | ||
55 | // * Unloads script (through "AppDomainManager" called from for example "EventQueueManager") | ||
56 | // * Dedicated load/unload thread, and queues loading/unloading. | ||
57 | // This so that scripts starting or stopping will not slow down other theads or whole system. | ||
58 | // | ||
59 | [Serializable] | ||
60 | public class ScriptManager | ||
61 | { | 44 | { |
62 | #region Declares | 45 | public ScriptManager(Common.ScriptEngineBase.ScriptEngine scriptEngine) |
63 | 46 | : base(scriptEngine) | |
64 | private Thread scriptLoadUnloadThread; | ||
65 | private int scriptLoadUnloadThread_IdleSleepms = 100; | ||
66 | private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); | ||
67 | |||
68 | |||
69 | // Load/Unload structure | ||
70 | private struct LUStruct | ||
71 | { | 47 | { |
72 | public uint localID; | 48 | base.m_scriptEngine = scriptEngine; |
73 | public LLUUID itemID; | ||
74 | public string script; | ||
75 | public LUType Action; | ||
76 | } | ||
77 | |||
78 | private enum LUType | ||
79 | { | ||
80 | Unknown = 0, | ||
81 | Load = 1, | ||
82 | Unload = 2 | ||
83 | } | ||
84 | 49 | ||
85 | // Object<string, Script<string, script>> | ||
86 | // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. | ||
87 | // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! | ||
88 | internal Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>> Scripts = | ||
89 | new Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>>(); | ||
90 | |||
91 | public Scene World | ||
92 | { | ||
93 | get { return m_scriptEngine.World; } | ||
94 | } | 50 | } |
95 | 51 | ||
96 | #endregion | 52 | // KEEP TRACK OF SCRIPTS <int id, whatever script> |
97 | 53 | //internal Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>> Scripts = new Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>>(); | |
98 | #region Object init/shutdown | 54 | // LOAD SCRIPT |
99 | 55 | // UNLOAD SCRIPT | |
100 | private ScriptEngine m_scriptEngine; | 56 | // PROVIDE SCRIPT WITH ITS INTERFACE TO OpenSim |
101 | 57 | ||
102 | public ScriptManager(ScriptEngine scriptEngine) | 58 | private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler(); |
103 | { | ||
104 | m_scriptEngine = scriptEngine; | ||
105 | AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); | ||
106 | scriptLoadUnloadThread = new Thread(ScriptLoadUnloadThreadLoop); | ||
107 | scriptLoadUnloadThread.Name = "ScriptLoadUnloadThread"; | ||
108 | scriptLoadUnloadThread.IsBackground = true; | ||
109 | scriptLoadUnloadThread.Priority = ThreadPriority.BelowNormal; | ||
110 | scriptLoadUnloadThread.Start(); | ||
111 | } | ||
112 | 59 | ||
113 | ~ScriptManager() | 60 | public override void _StartScript(uint localID, LLUUID itemID, string Script) |
114 | { | 61 | { |
115 | // Abort load/unload thread | 62 | //IScriptHost root = host.GetRoot(); |
116 | try | 63 | Console.WriteLine("ScriptManager StartScript: localID: " + localID + ", itemID: " + itemID); |
117 | { | ||
118 | if (scriptLoadUnloadThread != null) | ||
119 | { | ||
120 | if (scriptLoadUnloadThread.IsAlive == true) | ||
121 | { | ||
122 | scriptLoadUnloadThread.Abort(); | ||
123 | scriptLoadUnloadThread.Join(); | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | catch | ||
128 | { | ||
129 | } | ||
130 | } | ||
131 | 64 | ||
132 | #endregion | 65 | // We will initialize and start the script. |
66 | // It will be up to the script itself to hook up the correct events. | ||
67 | string ScriptSource = ""; | ||
133 | 68 | ||
134 | #region Load / Unload scripts (Thread loop) | 69 | SceneObjectPart m_host = World.GetSceneObjectPart(localID); |
135 | 70 | ||
136 | private void ScriptLoadUnloadThreadLoop() | ||
137 | { | ||
138 | try | 71 | try |
139 | { | 72 | { |
140 | while (true) | 73 | // Compile (We assume LSL) |
141 | { | 74 | ScriptSource = LSLCompiler.CompileFromLSLText(Script); |
142 | if (LUQueue.Count == 0) | ||
143 | Thread.Sleep(scriptLoadUnloadThread_IdleSleepms); | ||
144 | if (LUQueue.Count > 0) | ||
145 | { | ||
146 | LUStruct item = LUQueue.Dequeue(); | ||
147 | if (item.Action == LUType.Unload) | ||
148 | _StopScript(item.localID, item.itemID); | ||
149 | if (item.Action == LUType.Load) | ||
150 | _StartScript(item.localID, item.itemID, item.script); | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | catch (ThreadAbortException tae) | ||
155 | { | ||
156 | string a = tae.ToString(); | ||
157 | a = ""; | ||
158 | // Expected | ||
159 | } | ||
160 | } | ||
161 | |||
162 | #endregion | ||
163 | |||
164 | #region Helper functions | ||
165 | |||
166 | private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) | ||
167 | { | ||
168 | //Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name); | ||
169 | return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null; | ||
170 | } | ||
171 | |||
172 | #endregion | ||
173 | |||
174 | #region Internal functions to keep track of script | ||
175 | |||
176 | internal Dictionary<LLUUID, LSL_BaseClass>.KeyCollection GetScriptKeys(uint localID) | ||
177 | { | ||
178 | if (Scripts.ContainsKey(localID) == false) | ||
179 | return null; | ||
180 | |||
181 | Dictionary<LLUUID, LSL_BaseClass> Obj; | ||
182 | Scripts.TryGetValue(localID, out Obj); | ||
183 | |||
184 | return Obj.Keys; | ||
185 | } | ||
186 | |||
187 | internal LSL_BaseClass GetScript(uint localID, LLUUID itemID) | ||
188 | { | ||
189 | if (Scripts.ContainsKey(localID) == false) | ||
190 | return null; | ||
191 | |||
192 | Dictionary<LLUUID, LSL_BaseClass> Obj; | ||
193 | Scripts.TryGetValue(localID, out Obj); | ||
194 | if (Obj.ContainsKey(itemID) == false) | ||
195 | return null; | ||
196 | |||
197 | // Get script | ||
198 | LSL_BaseClass Script; | ||
199 | Obj.TryGetValue(itemID, out Script); | ||
200 | |||
201 | return Script; | ||
202 | } | ||
203 | |||
204 | internal void SetScript(uint localID, LLUUID itemID, LSL_BaseClass Script) | ||
205 | { | ||
206 | // Create object if it doesn't exist | ||
207 | if (Scripts.ContainsKey(localID) == false) | ||
208 | { | ||
209 | Scripts.Add(localID, new Dictionary<LLUUID, LSL_BaseClass>()); | ||
210 | } | ||
211 | |||
212 | // Delete script if it exists | ||
213 | Dictionary<LLUUID, LSL_BaseClass> Obj; | ||
214 | Scripts.TryGetValue(localID, out Obj); | ||
215 | if (Obj.ContainsKey(itemID) == true) | ||
216 | Obj.Remove(itemID); | ||
217 | |||
218 | // Add to object | ||
219 | Obj.Add(itemID, Script); | ||
220 | } | ||
221 | |||
222 | internal void RemoveScript(uint localID, LLUUID itemID) | ||
223 | { | ||
224 | // Don't have that object? | ||
225 | if (Scripts.ContainsKey(localID) == false) | ||
226 | return; | ||
227 | |||
228 | // Delete script if it exists | ||
229 | Dictionary<LLUUID, LSL_BaseClass> Obj; | ||
230 | Scripts.TryGetValue(localID, out Obj); | ||
231 | if (Obj.ContainsKey(itemID) == true) | ||
232 | Obj.Remove(itemID); | ||
233 | } | ||
234 | |||
235 | #endregion | ||
236 | |||
237 | #region Start/Stop/Reset script | ||
238 | |||
239 | private Object startStopLock = new Object(); | ||
240 | |||
241 | /// <summary> | ||
242 | /// Fetches, loads and hooks up a script to an objects events | ||
243 | /// </summary> | ||
244 | /// <param name="itemID"></param> | ||
245 | /// <param name="localID"></param> | ||
246 | public void StartScript(uint localID, LLUUID itemID, string Script) | ||
247 | { | ||
248 | LUStruct ls = new LUStruct(); | ||
249 | ls.localID = localID; | ||
250 | ls.itemID = itemID; | ||
251 | ls.script = Script; | ||
252 | ls.Action = LUType.Load; | ||
253 | LUQueue.Enqueue(ls); | ||
254 | } | ||
255 | |||
256 | /// <summary> | ||
257 | /// Disables and unloads a script | ||
258 | /// </summary> | ||
259 | /// <param name="localID"></param> | ||
260 | /// <param name="itemID"></param> | ||
261 | public void StopScript(uint localID, LLUUID itemID) | ||
262 | { | ||
263 | LUStruct ls = new LUStruct(); | ||
264 | ls.localID = localID; | ||
265 | ls.itemID = itemID; | ||
266 | ls.Action = LUType.Unload; | ||
267 | LUQueue.Enqueue(ls); | ||
268 | } | ||
269 | |||
270 | public void ResetScript(uint localID, LLUUID itemID) | ||
271 | { | ||
272 | string script = GetScript(localID, itemID).SourceCode; | ||
273 | StopScript(localID, itemID); | ||
274 | StartScript(localID, itemID, script); | ||
275 | } | ||
276 | |||
277 | // Create a new instance of the compiler (reuse) | ||
278 | private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler(); | ||
279 | |||
280 | private void _StartScript(uint localID, LLUUID itemID, string Script) | ||
281 | { | ||
282 | lock (startStopLock) | ||
283 | { | ||
284 | //IScriptHost root = host.GetRoot(); | ||
285 | Console.WriteLine("ScriptManager StartScript: localID: " + localID + ", itemID: " + itemID); | ||
286 | |||
287 | // We will initialize and start the script. | ||
288 | // It will be up to the script itself to hook up the correct events. | ||
289 | string ScriptSource = ""; | ||
290 | |||
291 | SceneObjectPart m_host = World.GetSceneObjectPart(localID); | ||
292 | |||
293 | try | ||
294 | { | ||
295 | if (!Script.EndsWith("dll")) | ||
296 | { | ||
297 | // Compile (We assume LSL) | ||
298 | ScriptSource = LSLCompiler.CompileFromLSLText(Script); | ||
299 | //Console.WriteLine("Compilation of " + FileName + " done"); | ||
300 | // * Insert yield into code | ||
301 | ScriptSource = ProcessYield(ScriptSource); | ||
302 | } | ||
303 | else | ||
304 | { | ||
305 | ScriptSource = Script; | ||
306 | } | ||
307 | 75 | ||
308 | #if DEBUG | 76 | #if DEBUG |
309 | long before; | 77 | long before; |
310 | before = GC.GetTotalMemory(true); | 78 | before = GC.GetTotalMemory(true); |
311 | #endif | 79 | #endif |
312 | 80 | ||
313 | LSL_BaseClass CompiledScript; | 81 | IScript CompiledScript; |
314 | CompiledScript = m_scriptEngine.m_AppDomainManager.LoadScript(ScriptSource); | 82 | CompiledScript = m_scriptEngine.m_AppDomainManager.LoadScript(ScriptSource); |
315 | 83 | ||
316 | #if DEBUG | 84 | #if DEBUG |
317 | Console.WriteLine("Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(true) - before); | 85 | Console.WriteLine("Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(true) - before); |
318 | #endif | 86 | #endif |
319 | 87 | ||
320 | CompiledScript.SourceCode = ScriptSource; | 88 | CompiledScript.Source = ScriptSource; |
321 | // Add it to our script memstruct | 89 | // Add it to our script memstruct |
322 | SetScript(localID, itemID, CompiledScript); | 90 | SetScript(localID, itemID, CompiledScript); |
323 | 91 | ||
324 | // We need to give (untrusted) assembly a private instance of BuiltIns | 92 | // We need to give (untrusted) assembly a private instance of BuiltIns |
325 | // this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed. | 93 | // this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed. |
326 | 94 | ||
327 | 95 | ||
328 | LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(m_scriptEngine, m_host, localID, itemID); | 96 | LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(m_scriptEngine, m_host, localID, itemID); |
329 | 97 | ||
330 | // Start the script - giving it BuiltIns | 98 | // Start the script - giving it BuiltIns |
331 | CompiledScript.Start(LSLB); | 99 | CompiledScript.Start(LSLB); |
332 | 100 | ||
333 | // Fire the first start-event | 101 | // Fire the first start-event |
334 | m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", new object[] {}); | 102 | m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", new object[] { }); |
335 | } | ||
336 | catch (Exception e) | ||
337 | { | ||
338 | //m_scriptEngine.Log.Error("ScriptEngine", "Error compiling script: " + e.ToString()); | ||
339 | try | ||
340 | { | ||
341 | // DISPLAY ERROR INWORLD | ||
342 | string text = "Error compiling script:\r\n" + e.Message.ToString(); | ||
343 | if (text.Length > 1500) | ||
344 | text = text.Substring(0, 1500); | ||
345 | World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, m_host.AbsolutePosition, | ||
346 | m_host.Name, m_host.UUID); | ||
347 | } | ||
348 | catch (Exception e2) | ||
349 | { | ||
350 | m_scriptEngine.Log.Error("ScriptEngine", "Error displaying error in-world: " + e2.ToString()); | ||
351 | m_scriptEngine.Log.Error("ScriptEngine", | ||
352 | "Errormessage: Error compiling script:\r\n" + e.Message.ToString()); | ||
353 | } | ||
354 | } | ||
355 | } | 103 | } |
356 | } | 104 | catch (Exception e) |
357 | |||
358 | private void _StopScript(uint localID, LLUUID itemID) | ||
359 | { | ||
360 | lock (startStopLock) | ||
361 | { | 105 | { |
362 | // Stop script | 106 | //m_scriptEngine.Log.Error("ScriptEngine", "Error compiling script: " + e.ToString()); |
363 | Console.WriteLine("Stop script localID: " + localID + " LLUID: " + itemID.ToString()); | ||
364 | |||
365 | |||
366 | // Stop long command on script | ||
367 | m_scriptEngine.m_LSLLongCmdHandler.RemoveScript(localID, itemID); | ||
368 | |||
369 | LSL_BaseClass LSLBC = GetScript(localID, itemID); | ||
370 | if (LSLBC == null) | ||
371 | return; | ||
372 | |||
373 | // TEMP: First serialize it | ||
374 | //GetSerializedScript(localID, itemID); | ||
375 | |||
376 | |||
377 | try | 107 | try |
378 | { | 108 | { |
379 | // Get AppDomain | 109 | // DISPLAY ERROR INWORLD |
380 | AppDomain ad = LSLBC.Exec.GetAppDomain(); | 110 | string text = "Error compiling script:\r\n" + e.Message.ToString(); |
381 | // Tell script not to accept new requests | 111 | if (text.Length > 1500) |
382 | GetScript(localID, itemID).Exec.StopScript(); | 112 | text = text.Substring(0, 1500); |
383 | // Remove from internal structure | 113 | World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, m_host.AbsolutePosition, |
384 | RemoveScript(localID, itemID); | 114 | m_host.Name, m_host.UUID); |
385 | // Tell AppDomain that we have stopped script | ||
386 | m_scriptEngine.m_AppDomainManager.StopScript(ad); | ||
387 | } | 115 | } |
388 | catch (Exception e) | 116 | catch (Exception e2) |
389 | { | 117 | { |
390 | Console.WriteLine("Exception stopping script localID: " + localID + " LLUID: " + itemID.ToString() + | 118 | m_scriptEngine.Log.Error("ScriptEngine", "Error displaying error in-world: " + e2.ToString()); |
391 | ": " + e.ToString()); | 119 | m_scriptEngine.Log.Error("ScriptEngine", |
120 | "Errormessage: Error compiling script:\r\n" + e.Message.ToString()); | ||
392 | } | 121 | } |
393 | } | 122 | } |
394 | } | 123 | } |
395 | 124 | ||
396 | private string ProcessYield(string FileName) | 125 | public override void _StopScript(uint localID, LLUUID itemID) |
397 | { | 126 | { |
398 | // TODO: Create a new assembly and copy old but insert Yield Code | 127 | // Stop script |
399 | //return TempDotNetMicroThreadingCodeInjector.TestFix(FileName); | 128 | Console.WriteLine("Stop script localID: " + localID + " LLUID: " + itemID.ToString()); |
400 | return FileName; | ||
401 | } | ||
402 | 129 | ||
403 | #endregion | ||
404 | 130 | ||
405 | #region Perform event execution in script | 131 | // Stop long command on script |
132 | m_scriptEngine.m_LSLLongCmdHandler.RemoveScript(localID, itemID); | ||
406 | 133 | ||
407 | /// <summary> | 134 | IScript LSLBC = GetScript(localID, itemID); |
408 | /// Execute a LL-event-function in Script | 135 | if (LSLBC == null) |
409 | /// </summary> | ||
410 | /// <param name="localID">Object the script is located in</param> | ||
411 | /// <param name="itemID">Script ID</param> | ||
412 | /// <param name="FunctionName">Name of function</param> | ||
413 | /// <param name="args">Arguments to pass to function</param> | ||
414 | internal void ExecuteEvent(uint localID, LLUUID itemID, string FunctionName, object[] args) | ||
415 | { | ||
416 | #if DEBUG | ||
417 | Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName); | ||
418 | #endif | ||
419 | // Execute a function in the script | ||
420 | //m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); | ||
421 | LSL_BaseClass Script = m_scriptEngine.m_ScriptManager.GetScript(localID, itemID); | ||
422 | if (Script == null) | ||
423 | return; | 136 | return; |
424 | 137 | ||
425 | #if DEBUG | 138 | // TEMP: First serialize it |
426 | Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); | 139 | //GetSerializedScript(localID, itemID); |
427 | #endif | ||
428 | // Must be done in correct AppDomain, so leaving it up to the script itself | ||
429 | Script.Exec.ExecuteEvent(FunctionName, args); | ||
430 | } | ||
431 | 140 | ||
432 | #endregion | ||
433 | 141 | ||
434 | #region Script serialization/deserialization | 142 | try |
435 | 143 | { | |
436 | public void GetSerializedScript(uint localID, LLUUID itemID) | 144 | // Get AppDomain |
437 | { | 145 | AppDomain ad = LSLBC.Exec.GetAppDomain(); |
438 | // Serialize the script and return it | 146 | // Tell script not to accept new requests |
439 | // Should not be a problem | 147 | GetScript(localID, itemID).Exec.StopScript(); |
440 | FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID); | 148 | // Remove from internal structure |
441 | BinaryFormatter b = new BinaryFormatter(); | 149 | RemoveScript(localID, itemID); |
442 | b.Serialize(fs, GetScript(localID, itemID)); | 150 | // Tell AppDomain that we have stopped script |
443 | fs.Close(); | 151 | m_scriptEngine.m_AppDomainManager.StopScript(ad); |
444 | } | 152 | } |
445 | 153 | catch (Exception e) | |
446 | public void PutSerializedScript(uint localID, LLUUID itemID) | 154 | { |
447 | { | 155 | Console.WriteLine("Exception stopping script localID: " + localID + " LLUID: " + itemID.ToString() + |
448 | // Deserialize the script and inject it into an AppDomain | 156 | ": " + e.ToString()); |
449 | 157 | } | |
450 | // How to inject into an AppDomain? | ||
451 | } | 158 | } |
452 | 159 | ||
453 | #endregion | ||
454 | } | 160 | } |
455 | } \ No newline at end of file | 161 | } \ No newline at end of file |