diff options
author | Tedd Hansen | 2008-01-12 14:45:59 +0000 |
---|---|---|
committer | Tedd Hansen | 2008-01-12 14:45:59 +0000 |
commit | 0081c060d0bb66e842a381e1a15a6cf01c0bd793 (patch) | |
tree | 19a02716e74838a6a7856a265cdc2319feb136b7 /OpenSim/Region/ScriptEngine/Common/ScriptEngineBase | |
parent | Added license to new files (diff) | |
download | opensim-SC_OLD-0081c060d0bb66e842a381e1a15a6cf01c0bd793.zip opensim-SC_OLD-0081c060d0bb66e842a381e1a15a6cf01c0bd793.tar.gz opensim-SC_OLD-0081c060d0bb66e842a381e1a15a6cf01c0bd793.tar.bz2 opensim-SC_OLD-0081c060d0bb66e842a381e1a15a6cf01c0bd793.tar.xz |
Set eol
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase')
7 files changed, 1689 insertions, 1689 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs index df00d4e..68ad88d 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs | |||
@@ -1,239 +1,239 @@ | |||
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 | ||
29 | 29 | ||
30 | using System; | 30 | using System; |
31 | using System.Collections; | 31 | using System.Collections; |
32 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
33 | using System.Reflection; | 33 | using System.Reflection; |
34 | using OpenSim.Region.ScriptEngine.Common; | 34 | using OpenSim.Region.ScriptEngine.Common; |
35 | 35 | ||
36 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 36 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase |
37 | { | 37 | { |
38 | public class AppDomainManager | 38 | public class AppDomainManager |
39 | { | 39 | { |
40 | 40 | ||
41 | // | 41 | // |
42 | // This class does AppDomain handling and loading/unloading of scripts in it. | 42 | // This class does AppDomain handling and loading/unloading of scripts in it. |
43 | // It is instanced in "ScriptEngine" and controlled from "ScriptManager" | 43 | // It is instanced in "ScriptEngine" and controlled from "ScriptManager" |
44 | // | 44 | // |
45 | // 1. Create a new AppDomain if old one is full (or doesn't exist) | 45 | // 1. Create a new AppDomain if old one is full (or doesn't exist) |
46 | // 2. Load scripts into AppDomain | 46 | // 2. Load scripts into AppDomain |
47 | // 3. Unload scripts from AppDomain (stopping them and marking them as inactive) | 47 | // 3. Unload scripts from AppDomain (stopping them and marking them as inactive) |
48 | // 4. Unload AppDomain completely when all scripts in it has stopped | 48 | // 4. Unload AppDomain completely when all scripts in it has stopped |
49 | // | 49 | // |
50 | 50 | ||
51 | 51 | ||
52 | private int maxScriptsPerAppDomain = 1; | 52 | private int maxScriptsPerAppDomain = 1; |
53 | 53 | ||
54 | /// <summary> | 54 | /// <summary> |
55 | /// Internal list of all AppDomains | 55 | /// Internal list of all AppDomains |
56 | /// </summary> | 56 | /// </summary> |
57 | private List<AppDomainStructure> appDomains = new List<AppDomainStructure>(); | 57 | private List<AppDomainStructure> appDomains = new List<AppDomainStructure>(); |
58 | 58 | ||
59 | /// <summary> | 59 | /// <summary> |
60 | /// Structure to keep track of data around AppDomain | 60 | /// Structure to keep track of data around AppDomain |
61 | /// </summary> | 61 | /// </summary> |
62 | private class AppDomainStructure | 62 | private class AppDomainStructure |
63 | { | 63 | { |
64 | /// <summary> | 64 | /// <summary> |
65 | /// The AppDomain itself | 65 | /// The AppDomain itself |
66 | /// </summary> | 66 | /// </summary> |
67 | public AppDomain CurrentAppDomain; | 67 | public AppDomain CurrentAppDomain; |
68 | 68 | ||
69 | /// <summary> | 69 | /// <summary> |
70 | /// Number of scripts loaded into AppDomain | 70 | /// Number of scripts loaded into AppDomain |
71 | /// </summary> | 71 | /// </summary> |
72 | public int ScriptsLoaded; | 72 | public int ScriptsLoaded; |
73 | 73 | ||
74 | /// <summary> | 74 | /// <summary> |
75 | /// Number of dead scripts | 75 | /// Number of dead scripts |
76 | /// </summary> | 76 | /// </summary> |
77 | public int ScriptsWaitingUnload; | 77 | public int ScriptsWaitingUnload; |
78 | } | 78 | } |
79 | 79 | ||
80 | /// <summary> | 80 | /// <summary> |
81 | /// Current AppDomain | 81 | /// Current AppDomain |
82 | /// </summary> | 82 | /// </summary> |
83 | private AppDomainStructure currentAD; | 83 | private AppDomainStructure currentAD; |
84 | 84 | ||
85 | private object getLock = new object(); // Mutex | 85 | private object getLock = new object(); // Mutex |
86 | private object freeLock = new object(); // Mutex | 86 | private object freeLock = new object(); // Mutex |
87 | 87 | ||
88 | //private ScriptEngine m_scriptEngine; | 88 | //private ScriptEngine m_scriptEngine; |
89 | //public AppDomainManager(ScriptEngine scriptEngine) | 89 | //public AppDomainManager(ScriptEngine scriptEngine) |
90 | public AppDomainManager() | 90 | public AppDomainManager() |
91 | { | 91 | { |
92 | //m_scriptEngine = scriptEngine; | 92 | //m_scriptEngine = scriptEngine; |
93 | } | 93 | } |
94 | 94 | ||
95 | /// <summary> | 95 | /// <summary> |
96 | /// Find a free AppDomain, creating one if necessary | 96 | /// Find a free AppDomain, creating one if necessary |
97 | /// </summary> | 97 | /// </summary> |
98 | /// <returns>Free AppDomain</returns> | 98 | /// <returns>Free AppDomain</returns> |
99 | private AppDomainStructure GetFreeAppDomain() | 99 | private AppDomainStructure GetFreeAppDomain() |
100 | { | 100 | { |
101 | Console.WriteLine("Finding free AppDomain"); | 101 | Console.WriteLine("Finding free AppDomain"); |
102 | lock (getLock) | 102 | lock (getLock) |
103 | { | 103 | { |
104 | // Current full? | 104 | // Current full? |
105 | if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain) | 105 | if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain) |
106 | { | 106 | { |
107 | // Add it to AppDomains list and empty current | 107 | // Add it to AppDomains list and empty current |
108 | appDomains.Add(currentAD); | 108 | appDomains.Add(currentAD); |
109 | currentAD = null; | 109 | currentAD = null; |
110 | } | 110 | } |
111 | // No current | 111 | // No current |
112 | if (currentAD == null) | 112 | if (currentAD == null) |
113 | { | 113 | { |
114 | // Create a new current AppDomain | 114 | // Create a new current AppDomain |
115 | currentAD = new AppDomainStructure(); | 115 | currentAD = new AppDomainStructure(); |
116 | currentAD.CurrentAppDomain = PrepareNewAppDomain(); | 116 | currentAD.CurrentAppDomain = PrepareNewAppDomain(); |
117 | } | 117 | } |
118 | 118 | ||
119 | Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded); | 119 | Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded); |
120 | return currentAD; | 120 | return currentAD; |
121 | } // lock | 121 | } // lock |
122 | } | 122 | } |
123 | 123 | ||
124 | private int AppDomainNameCount; | 124 | private int AppDomainNameCount; |
125 | 125 | ||
126 | /// <summary> | 126 | /// <summary> |
127 | /// Create and prepare a new AppDomain for scripts | 127 | /// Create and prepare a new AppDomain for scripts |
128 | /// </summary> | 128 | /// </summary> |
129 | /// <returns>The new AppDomain</returns> | 129 | /// <returns>The new AppDomain</returns> |
130 | private AppDomain PrepareNewAppDomain() | 130 | private AppDomain PrepareNewAppDomain() |
131 | { | 131 | { |
132 | // Create and prepare a new AppDomain | 132 | // Create and prepare a new AppDomain |
133 | AppDomainNameCount++; | 133 | AppDomainNameCount++; |
134 | // TODO: Currently security match current appdomain | 134 | // TODO: Currently security match current appdomain |
135 | 135 | ||
136 | // Construct and initialize settings for a second AppDomain. | 136 | // Construct and initialize settings for a second AppDomain. |
137 | AppDomainSetup ads = new AppDomainSetup(); | 137 | AppDomainSetup ads = new AppDomainSetup(); |
138 | ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; | 138 | ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; |
139 | ads.DisallowBindingRedirects = false; | 139 | ads.DisallowBindingRedirects = false; |
140 | ads.DisallowCodeDownload = true; | 140 | ads.DisallowCodeDownload = true; |
141 | ads.LoaderOptimization = LoaderOptimization.MultiDomain; // Sounds good ;) | 141 | ads.LoaderOptimization = LoaderOptimization.MultiDomain; // Sounds good ;) |
142 | ads.ShadowCopyFiles = "true"; // Enabled shadowing | 142 | ads.ShadowCopyFiles = "true"; // Enabled shadowing |
143 | ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; | 143 | ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; |
144 | 144 | ||
145 | AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); | 145 | AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); |
146 | Console.WriteLine("Loading: " + | 146 | Console.WriteLine("Loading: " + |
147 | AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll").ToString()); | 147 | AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll").ToString()); |
148 | AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll")); | 148 | AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll")); |
149 | 149 | ||
150 | // Return the new AppDomain | 150 | // Return the new AppDomain |
151 | return AD; | 151 | return AD; |
152 | } | 152 | } |
153 | 153 | ||
154 | /// <summary> | 154 | /// <summary> |
155 | /// Unload appdomains that are full and have only dead scripts | 155 | /// Unload appdomains that are full and have only dead scripts |
156 | /// </summary> | 156 | /// </summary> |
157 | private void UnloadAppDomains() | 157 | private void UnloadAppDomains() |
158 | { | 158 | { |
159 | lock (freeLock) | 159 | lock (freeLock) |
160 | { | 160 | { |
161 | // Go through all | 161 | // Go through all |
162 | foreach (AppDomainStructure ads in new ArrayList(appDomains)) | 162 | foreach (AppDomainStructure ads in new ArrayList(appDomains)) |
163 | { | 163 | { |
164 | // Don't process current AppDomain | 164 | // Don't process current AppDomain |
165 | if (ads.CurrentAppDomain != currentAD.CurrentAppDomain) | 165 | if (ads.CurrentAppDomain != currentAD.CurrentAppDomain) |
166 | { | 166 | { |
167 | // Not current AppDomain | 167 | // Not current AppDomain |
168 | // Is number of unloaded bigger or equal to number of loaded? | 168 | // Is number of unloaded bigger or equal to number of loaded? |
169 | if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload) | 169 | if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload) |
170 | { | 170 | { |
171 | Console.WriteLine("Found empty AppDomain, unloading"); | 171 | Console.WriteLine("Found empty AppDomain, unloading"); |
172 | // Remove from internal list | 172 | // Remove from internal list |
173 | appDomains.Remove(ads); | 173 | appDomains.Remove(ads); |
174 | #if DEBUG | 174 | #if DEBUG |
175 | long m = GC.GetTotalMemory(true); | 175 | long m = GC.GetTotalMemory(true); |
176 | #endif | 176 | #endif |
177 | // Unload | 177 | // Unload |
178 | AppDomain.Unload(ads.CurrentAppDomain); | 178 | AppDomain.Unload(ads.CurrentAppDomain); |
179 | #if DEBUG | 179 | #if DEBUG |
180 | Console.WriteLine("AppDomain unload freed " + (m - GC.GetTotalMemory(true)) + | 180 | Console.WriteLine("AppDomain unload freed " + (m - GC.GetTotalMemory(true)) + |
181 | " bytes of memory"); | 181 | " bytes of memory"); |
182 | #endif | 182 | #endif |
183 | } | 183 | } |
184 | } | 184 | } |
185 | } // foreach | 185 | } // foreach |
186 | } // lock | 186 | } // lock |
187 | } | 187 | } |
188 | 188 | ||
189 | 189 | ||
190 | public IScript LoadScript(string FileName) | 190 | public IScript LoadScript(string FileName) |
191 | { | 191 | { |
192 | // Find next available AppDomain to put it in | 192 | // Find next available AppDomain to put it in |
193 | AppDomainStructure FreeAppDomain = GetFreeAppDomain(); | 193 | AppDomainStructure FreeAppDomain = GetFreeAppDomain(); |
194 | 194 | ||
195 | Console.WriteLine("Loading into AppDomain: " + FileName); | 195 | Console.WriteLine("Loading into AppDomain: " + FileName); |
196 | IScript mbrt = | 196 | IScript mbrt = |
197 | (IScript) | 197 | (IScript) |
198 | FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); | 198 | FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); |
199 | //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); | 199 | //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); |
200 | FreeAppDomain.ScriptsLoaded++; | 200 | FreeAppDomain.ScriptsLoaded++; |
201 | 201 | ||
202 | return mbrt; | 202 | return mbrt; |
203 | } | 203 | } |
204 | 204 | ||
205 | 205 | ||
206 | /// <summary> | 206 | /// <summary> |
207 | /// Increase "dead script" counter for an AppDomain | 207 | /// Increase "dead script" counter for an AppDomain |
208 | /// </summary> | 208 | /// </summary> |
209 | /// <param name="ad"></param> | 209 | /// <param name="ad"></param> |
210 | //[Obsolete("Needs fixing, needs a real purpose in life!!!")] | 210 | //[Obsolete("Needs fixing, needs a real purpose in life!!!")] |
211 | public void StopScript(AppDomain ad) | 211 | public void StopScript(AppDomain ad) |
212 | { | 212 | { |
213 | lock (freeLock) | 213 | lock (freeLock) |
214 | { | 214 | { |
215 | Console.WriteLine("Stopping script in AppDomain"); | 215 | Console.WriteLine("Stopping script in AppDomain"); |
216 | // Check if it is current AppDomain | 216 | // Check if it is current AppDomain |
217 | if (currentAD.CurrentAppDomain == ad) | 217 | if (currentAD.CurrentAppDomain == ad) |
218 | { | 218 | { |
219 | // Yes - increase | 219 | // Yes - increase |
220 | currentAD.ScriptsWaitingUnload++; | 220 | currentAD.ScriptsWaitingUnload++; |
221 | return; | 221 | return; |
222 | } | 222 | } |
223 | 223 | ||
224 | // Lopp through all AppDomains | 224 | // Lopp through all AppDomains |
225 | foreach (AppDomainStructure ads in new ArrayList(appDomains)) | 225 | foreach (AppDomainStructure ads in new ArrayList(appDomains)) |
226 | { | 226 | { |
227 | if (ads.CurrentAppDomain == ad) | 227 | if (ads.CurrentAppDomain == ad) |
228 | { | 228 | { |
229 | // Found it | 229 | // Found it |
230 | ads.ScriptsWaitingUnload++; | 230 | ads.ScriptsWaitingUnload++; |
231 | break; | 231 | break; |
232 | } | 232 | } |
233 | } // foreach | 233 | } // foreach |
234 | } // lock | 234 | } // lock |
235 | 235 | ||
236 | UnloadAppDomains(); // Outsite lock, has its own GetLock | 236 | UnloadAppDomains(); // Outsite lock, has its own GetLock |
237 | } | 237 | } |
238 | } | 238 | } |
239 | } \ No newline at end of file | 239 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs index b2eea38..bce26ff 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs | |||
@@ -1,58 +1,58 @@ | |||
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 | ||
29 | 29 | ||
30 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 30 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase |
31 | { | 31 | { |
32 | public static class Common | 32 | public static class Common |
33 | { | 33 | { |
34 | public static bool debug = true; | 34 | public static bool debug = true; |
35 | public static ScriptEngine mySE; | 35 | public static ScriptEngine mySE; |
36 | 36 | ||
37 | // This class just contains some static log stuff used for debugging. | 37 | // This class just contains some static log stuff used for debugging. |
38 | 38 | ||
39 | //public delegate void SendToDebugEventDelegate(string Message); | 39 | //public delegate void SendToDebugEventDelegate(string Message); |
40 | //public delegate void SendToLogEventDelegate(string Message); | 40 | //public delegate void SendToLogEventDelegate(string Message); |
41 | //static public event SendToDebugEventDelegate SendToDebugEvent; | 41 | //static public event SendToDebugEventDelegate SendToDebugEvent; |
42 | //static public event SendToLogEventDelegate SendToLogEvent; | 42 | //static public event SendToLogEventDelegate SendToLogEvent; |
43 | 43 | ||
44 | public static void SendToDebug(string Message) | 44 | public static void SendToDebug(string Message) |
45 | { | 45 | { |
46 | //if (Debug == true) | 46 | //if (Debug == true) |
47 | mySE.Log.Verbose("ScriptEngine", "Debug: " + Message); | 47 | mySE.Log.Verbose("ScriptEngine", "Debug: " + Message); |
48 | //SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); | 48 | //SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); |
49 | } | 49 | } |
50 | 50 | ||
51 | public static void SendToLog(string Message) | 51 | public static void SendToLog(string Message) |
52 | { | 52 | { |
53 | //if (Debug == true) | 53 | //if (Debug == true) |
54 | mySE.Log.Verbose("ScriptEngine", "LOG: " + Message); | 54 | mySE.Log.Verbose("ScriptEngine", "LOG: " + Message); |
55 | //SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); | 55 | //SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); |
56 | } | 56 | } |
57 | } | 57 | } |
58 | } \ No newline at end of file | 58 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs index 07476ac..6df8343 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs | |||
@@ -1,260 +1,260 @@ | |||
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 | ||
29 | 29 | ||
30 | using System; | 30 | using System; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | 33 | ||
34 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 34 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase |
35 | { | 35 | { |
36 | /// <summary> | 36 | /// <summary> |
37 | /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it. | 37 | /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it. |
38 | /// </summary> | 38 | /// </summary> |
39 | [Serializable] | 39 | [Serializable] |
40 | public class EventManager : OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.RemoteEvents | 40 | public class EventManager : OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.RemoteEvents |
41 | { | 41 | { |
42 | 42 | ||
43 | // | 43 | // |
44 | // Class is instanced in "ScriptEngine" and Uses "EventQueueManager" that is also instanced in "ScriptEngine". | 44 | // Class is instanced in "ScriptEngine" and Uses "EventQueueManager" that is also instanced in "ScriptEngine". |
45 | // This class needs a bit of explaining: | 45 | // This class needs a bit of explaining: |
46 | // | 46 | // |
47 | // This class it the link between an event inside OpenSim and the corresponding event in a user script being executed. | 47 | // This class it the link between an event inside OpenSim and the corresponding event in a user script being executed. |
48 | // | 48 | // |
49 | // For example when an user touches an object then the "myScriptEngine.World.EventManager.OnObjectGrab" event is fired inside OpenSim. | 49 | // For example when an user touches an object then the "myScriptEngine.World.EventManager.OnObjectGrab" event is fired inside OpenSim. |
50 | // We hook up to this event and queue a touch_start in EventQueueManager with the proper LSL parameters. | 50 | // We hook up to this event and queue a touch_start in EventQueueManager with the proper LSL parameters. |
51 | // It will then be delivered to the script by EventQueueManager. | 51 | // It will then be delivered to the script by EventQueueManager. |
52 | // | 52 | // |
53 | // You can check debug C# dump of an LSL script if you need to verify what exact parameters are needed. | 53 | // You can check debug C# dump of an LSL script if you need to verify what exact parameters are needed. |
54 | // | 54 | // |
55 | 55 | ||
56 | 56 | ||
57 | private ScriptEngine myScriptEngine; | 57 | private ScriptEngine myScriptEngine; |
58 | //public IScriptHost TEMP_OBJECT_ID; | 58 | //public IScriptHost TEMP_OBJECT_ID; |
59 | public EventManager(ScriptEngine _ScriptEngine, bool performHookUp) | 59 | public EventManager(ScriptEngine _ScriptEngine, bool performHookUp) |
60 | { | 60 | { |
61 | myScriptEngine = _ScriptEngine; | 61 | myScriptEngine = _ScriptEngine; |
62 | 62 | ||
63 | // Hook up to events from OpenSim | 63 | // Hook up to events from OpenSim |
64 | // We may not want to do it because someone is controlling us and will deliver events to us | 64 | // We may not want to do it because someone is controlling us and will deliver events to us |
65 | if (performHookUp) | 65 | if (performHookUp) |
66 | { | 66 | { |
67 | myScriptEngine.Log.Verbose("ScriptEngine", "Hooking up to server events"); | 67 | myScriptEngine.Log.Verbose("ScriptEngine", "Hooking up to server events"); |
68 | myScriptEngine.World.EventManager.OnObjectGrab += touch_start; | 68 | myScriptEngine.World.EventManager.OnObjectGrab += touch_start; |
69 | myScriptEngine.World.EventManager.OnRezScript += OnRezScript; | 69 | myScriptEngine.World.EventManager.OnRezScript += OnRezScript; |
70 | myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript; | 70 | myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript; |
71 | // TODO: HOOK ALL EVENTS UP TO SERVER! | 71 | // TODO: HOOK ALL EVENTS UP TO SERVER! |
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
75 | public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient) | 75 | public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient) |
76 | { | 76 | { |
77 | // Add to queue for all scripts in ObjectID object | 77 | // Add to queue for all scripts in ObjectID object |
78 | myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "touch_start", new object[] {(int) 1}); | 78 | myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "touch_start", new object[] {(int) 1}); |
79 | } | 79 | } |
80 | 80 | ||
81 | public void OnRezScript(uint localID, LLUUID itemID, string script) | 81 | public void OnRezScript(uint localID, LLUUID itemID, string script) |
82 | { | 82 | { |
83 | Console.WriteLine("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " + | 83 | Console.WriteLine("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " + |
84 | script.Length); | 84 | script.Length); |
85 | myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script); | 85 | myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script); |
86 | } | 86 | } |
87 | 87 | ||
88 | public void OnRemoveScript(uint localID, LLUUID itemID) | 88 | public void OnRemoveScript(uint localID, LLUUID itemID) |
89 | { | 89 | { |
90 | Console.WriteLine("OnRemoveScript localID: " + localID + " LLUID: " + itemID.ToString()); | 90 | Console.WriteLine("OnRemoveScript localID: " + localID + " LLUID: " + itemID.ToString()); |
91 | myScriptEngine.m_ScriptManager.StopScript( | 91 | myScriptEngine.m_ScriptManager.StopScript( |
92 | localID, | 92 | localID, |
93 | itemID | 93 | itemID |
94 | ); | 94 | ); |
95 | } | 95 | } |
96 | 96 | ||
97 | // TODO: Replace placeholders below | 97 | // TODO: Replace placeholders below |
98 | // NOTE! THE PARAMETERS FOR THESE FUNCTIONS ARE NOT CORRECT! | 98 | // NOTE! THE PARAMETERS FOR THESE FUNCTIONS ARE NOT CORRECT! |
99 | // These needs to be hooked up to OpenSim during init of this class | 99 | // These needs to be hooked up to OpenSim during init of this class |
100 | // then queued in EventQueueManager. | 100 | // then queued in EventQueueManager. |
101 | // When queued in EventQueueManager they need to be LSL compatible (name and params) | 101 | // When queued in EventQueueManager they need to be LSL compatible (name and params) |
102 | 102 | ||
103 | public void state_exit(uint localID, LLUUID itemID) | 103 | public void state_exit(uint localID, LLUUID itemID) |
104 | { | 104 | { |
105 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_exit"); | 105 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_exit"); |
106 | } | 106 | } |
107 | 107 | ||
108 | public void touch(uint localID, LLUUID itemID) | 108 | public void touch(uint localID, LLUUID itemID) |
109 | { | 109 | { |
110 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch"); | 110 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch"); |
111 | } | 111 | } |
112 | 112 | ||
113 | public void touch_end(uint localID, LLUUID itemID) | 113 | public void touch_end(uint localID, LLUUID itemID) |
114 | { | 114 | { |
115 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch_end"); | 115 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch_end"); |
116 | } | 116 | } |
117 | 117 | ||
118 | public void collision_start(uint localID, LLUUID itemID) | 118 | public void collision_start(uint localID, LLUUID itemID) |
119 | { | 119 | { |
120 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_start"); | 120 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_start"); |
121 | } | 121 | } |
122 | 122 | ||
123 | public void collision(uint localID, LLUUID itemID) | 123 | public void collision(uint localID, LLUUID itemID) |
124 | { | 124 | { |
125 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision"); | 125 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision"); |
126 | } | 126 | } |
127 | 127 | ||
128 | public void collision_end(uint localID, LLUUID itemID) | 128 | public void collision_end(uint localID, LLUUID itemID) |
129 | { | 129 | { |
130 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_end"); | 130 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_end"); |
131 | } | 131 | } |
132 | 132 | ||
133 | public void land_collision_start(uint localID, LLUUID itemID) | 133 | public void land_collision_start(uint localID, LLUUID itemID) |
134 | { | 134 | { |
135 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_start"); | 135 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_start"); |
136 | } | 136 | } |
137 | 137 | ||
138 | public void land_collision(uint localID, LLUUID itemID) | 138 | public void land_collision(uint localID, LLUUID itemID) |
139 | { | 139 | { |
140 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision"); | 140 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision"); |
141 | } | 141 | } |
142 | 142 | ||
143 | public void land_collision_end(uint localID, LLUUID itemID) | 143 | public void land_collision_end(uint localID, LLUUID itemID) |
144 | { | 144 | { |
145 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_end"); | 145 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_end"); |
146 | } | 146 | } |
147 | 147 | ||
148 | // Handled by long commands | 148 | // Handled by long commands |
149 | public void timer(uint localID, LLUUID itemID) | 149 | public void timer(uint localID, LLUUID itemID) |
150 | { | 150 | { |
151 | //myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, ""); | 151 | //myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, ""); |
152 | } | 152 | } |
153 | 153 | ||
154 | public void listen(uint localID, LLUUID itemID) | 154 | public void listen(uint localID, LLUUID itemID) |
155 | { | 155 | { |
156 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "listen"); | 156 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "listen"); |
157 | } | 157 | } |
158 | 158 | ||
159 | public void on_rez(uint localID, LLUUID itemID) | 159 | public void on_rez(uint localID, LLUUID itemID) |
160 | { | 160 | { |
161 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "on_rez"); | 161 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "on_rez"); |
162 | } | 162 | } |
163 | 163 | ||
164 | public void sensor(uint localID, LLUUID itemID) | 164 | public void sensor(uint localID, LLUUID itemID) |
165 | { | 165 | { |
166 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "sensor"); | 166 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "sensor"); |
167 | } | 167 | } |
168 | 168 | ||
169 | public void no_sensor(uint localID, LLUUID itemID) | 169 | public void no_sensor(uint localID, LLUUID itemID) |
170 | { | 170 | { |
171 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "no_sensor"); | 171 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "no_sensor"); |
172 | } | 172 | } |
173 | 173 | ||
174 | public void control(uint localID, LLUUID itemID) | 174 | public void control(uint localID, LLUUID itemID) |
175 | { | 175 | { |
176 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "control"); | 176 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "control"); |
177 | } | 177 | } |
178 | 178 | ||
179 | public void money(uint localID, LLUUID itemID) | 179 | public void money(uint localID, LLUUID itemID) |
180 | { | 180 | { |
181 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "money"); | 181 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "money"); |
182 | } | 182 | } |
183 | 183 | ||
184 | public void email(uint localID, LLUUID itemID) | 184 | public void email(uint localID, LLUUID itemID) |
185 | { | 185 | { |
186 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "email"); | 186 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "email"); |
187 | } | 187 | } |
188 | 188 | ||
189 | public void at_target(uint localID, LLUUID itemID) | 189 | public void at_target(uint localID, LLUUID itemID) |
190 | { | 190 | { |
191 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_target"); | 191 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_target"); |
192 | } | 192 | } |
193 | 193 | ||
194 | public void not_at_target(uint localID, LLUUID itemID) | 194 | public void not_at_target(uint localID, LLUUID itemID) |
195 | { | 195 | { |
196 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_target"); | 196 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_target"); |
197 | } | 197 | } |
198 | 198 | ||
199 | public void at_rot_target(uint localID, LLUUID itemID) | 199 | public void at_rot_target(uint localID, LLUUID itemID) |
200 | { | 200 | { |
201 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_rot_target"); | 201 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_rot_target"); |
202 | } | 202 | } |
203 | 203 | ||
204 | public void not_at_rot_target(uint localID, LLUUID itemID) | 204 | public void not_at_rot_target(uint localID, LLUUID itemID) |
205 | { | 205 | { |
206 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_rot_target"); | 206 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_rot_target"); |
207 | } | 207 | } |
208 | 208 | ||
209 | public void run_time_permissions(uint localID, LLUUID itemID) | 209 | public void run_time_permissions(uint localID, LLUUID itemID) |
210 | { | 210 | { |
211 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "run_time_permissions"); | 211 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "run_time_permissions"); |
212 | } | 212 | } |
213 | 213 | ||
214 | public void changed(uint localID, LLUUID itemID) | 214 | public void changed(uint localID, LLUUID itemID) |
215 | { | 215 | { |
216 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "changed"); | 216 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "changed"); |
217 | } | 217 | } |
218 | 218 | ||
219 | public void attach(uint localID, LLUUID itemID) | 219 | public void attach(uint localID, LLUUID itemID) |
220 | { | 220 | { |
221 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "attach"); | 221 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "attach"); |
222 | } | 222 | } |
223 | 223 | ||
224 | public void dataserver(uint localID, LLUUID itemID) | 224 | public void dataserver(uint localID, LLUUID itemID) |
225 | { | 225 | { |
226 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "dataserver"); | 226 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "dataserver"); |
227 | } | 227 | } |
228 | 228 | ||
229 | public void link_message(uint localID, LLUUID itemID) | 229 | public void link_message(uint localID, LLUUID itemID) |
230 | { | 230 | { |
231 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "link_message"); | 231 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "link_message"); |
232 | } | 232 | } |
233 | 233 | ||
234 | public void moving_start(uint localID, LLUUID itemID) | 234 | public void moving_start(uint localID, LLUUID itemID) |
235 | { | 235 | { |
236 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_start"); | 236 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_start"); |
237 | } | 237 | } |
238 | 238 | ||
239 | public void moving_end(uint localID, LLUUID itemID) | 239 | public void moving_end(uint localID, LLUUID itemID) |
240 | { | 240 | { |
241 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_end"); | 241 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_end"); |
242 | } | 242 | } |
243 | 243 | ||
244 | public void object_rez(uint localID, LLUUID itemID) | 244 | public void object_rez(uint localID, LLUUID itemID) |
245 | { | 245 | { |
246 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "object_rez"); | 246 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "object_rez"); |
247 | } | 247 | } |
248 | 248 | ||
249 | public void remote_data(uint localID, LLUUID itemID) | 249 | public void remote_data(uint localID, LLUUID itemID) |
250 | { | 250 | { |
251 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "remote_data"); | 251 | myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "remote_data"); |
252 | } | 252 | } |
253 | 253 | ||
254 | // Handled by long commands | 254 | // Handled by long commands |
255 | public void http_response(uint localID, LLUUID itemID) | 255 | public void http_response(uint localID, LLUUID itemID) |
256 | { | 256 | { |
257 | // myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "http_response"); | 257 | // myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "http_response"); |
258 | } | 258 | } |
259 | } | 259 | } |
260 | } \ No newline at end of file | 260 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs index ad9ff45..8081e2c 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs | |||
@@ -1,364 +1,364 @@ | |||
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 | ||
29 | 29 | ||
30 | using System; | 30 | using System; |
31 | using System.Collections; | 31 | using System.Collections; |
32 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
33 | using System.Threading; | 33 | using System.Threading; |
34 | using libsecondlife; | 34 | using libsecondlife; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Region.Environment.Scenes.Scripting; | 36 | using OpenSim.Region.Environment.Scenes.Scripting; |
37 | 37 | ||
38 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 38 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase |
39 | { | 39 | { |
40 | /// <summary> | 40 | /// <summary> |
41 | /// EventQueueManager handles event queues | 41 | /// EventQueueManager handles event queues |
42 | /// Events are queued and executed in separate thread | 42 | /// Events are queued and executed in separate thread |
43 | /// </summary> | 43 | /// </summary> |
44 | [Serializable] | 44 | [Serializable] |
45 | public class EventQueueManager | 45 | public class EventQueueManager |
46 | { | 46 | { |
47 | 47 | ||
48 | // | 48 | // |
49 | // Class is instanced in "ScriptEngine" and used by "EventManager" also instanced in "ScriptEngine". | 49 | // Class is instanced in "ScriptEngine" and used by "EventManager" also instanced in "ScriptEngine". |
50 | // | 50 | // |
51 | // Class purpose is to queue and execute functions that are received by "EventManager": | 51 | // Class purpose is to queue and execute functions that are received by "EventManager": |
52 | // - allowing "EventManager" to release its event thread immediately, thus not interrupting server execution. | 52 | // - allowing "EventManager" to release its event thread immediately, thus not interrupting server execution. |
53 | // - allowing us to prioritize and control execution of script functions. | 53 | // - allowing us to prioritize and control execution of script functions. |
54 | // Class can use multiple threads for simultaneous execution. Mutexes are used for thread safety. | 54 | // Class can use multiple threads for simultaneous execution. Mutexes are used for thread safety. |
55 | // | 55 | // |
56 | // 1. Hold an execution queue for scripts | 56 | // 1. Hold an execution queue for scripts |
57 | // 2. Use threads to process queue, each thread executes one script function on each pass. | 57 | // 2. Use threads to process queue, each thread executes one script function on each pass. |
58 | // 3. Catch any script error and process it | 58 | // 3. Catch any script error and process it |
59 | // | 59 | // |
60 | // | 60 | // |
61 | // Notes: | 61 | // Notes: |
62 | // * Current execution load balancing is optimized for 1 thread, and can cause unfair execute balancing between scripts. | 62 | // * Current execution load balancing is optimized for 1 thread, and can cause unfair execute balancing between scripts. |
63 | // Not noticeable unless server is under high load. | 63 | // Not noticeable unless server is under high load. |
64 | // * This class contains the number of threads used for script executions. Since we are not microthreading scripts yet, | 64 | // * This class contains the number of threads used for script executions. Since we are not microthreading scripts yet, |
65 | // increase number of threads to allow more concurrent script executions in OpenSim. | 65 | // increase number of threads to allow more concurrent script executions in OpenSim. |
66 | // | 66 | // |
67 | 67 | ||
68 | 68 | ||
69 | /// <summary> | 69 | /// <summary> |
70 | /// List of threads processing event queue | 70 | /// List of threads processing event queue |
71 | /// </summary> | 71 | /// </summary> |
72 | private List<Thread> eventQueueThreads = new List<Thread>(); | 72 | private List<Thread> eventQueueThreads = new List<Thread>(); |
73 | 73 | ||
74 | private object queueLock = new object(); // Mutex lock object | 74 | private object queueLock = new object(); // Mutex lock object |
75 | 75 | ||
76 | /// <summary> | 76 | /// <summary> |
77 | /// How many ms to sleep if queue is empty | 77 | /// How many ms to sleep if queue is empty |
78 | /// </summary> | 78 | /// </summary> |
79 | private int nothingToDoSleepms = 50; | 79 | private int nothingToDoSleepms = 50; |
80 | 80 | ||
81 | /// <summary> | 81 | /// <summary> |
82 | /// How many threads to process queue with | 82 | /// How many threads to process queue with |
83 | /// </summary> | 83 | /// </summary> |
84 | private int numberOfThreads = 2; | 84 | private int numberOfThreads = 2; |
85 | 85 | ||
86 | /// <summary> | 86 | /// <summary> |
87 | /// Queue containing events waiting to be executed | 87 | /// Queue containing events waiting to be executed |
88 | /// </summary> | 88 | /// </summary> |
89 | private Queue<QueueItemStruct> eventQueue = new Queue<QueueItemStruct>(); | 89 | private Queue<QueueItemStruct> eventQueue = new Queue<QueueItemStruct>(); |
90 | 90 | ||
91 | /// <summary> | 91 | /// <summary> |
92 | /// Queue item structure | 92 | /// Queue item structure |
93 | /// </summary> | 93 | /// </summary> |
94 | private struct QueueItemStruct | 94 | private struct QueueItemStruct |
95 | { | 95 | { |
96 | public uint localID; | 96 | public uint localID; |
97 | public LLUUID itemID; | 97 | public LLUUID itemID; |
98 | public string functionName; | 98 | public string functionName; |
99 | public object[] param; | 99 | public object[] param; |
100 | } | 100 | } |
101 | 101 | ||
102 | /// <summary> | 102 | /// <summary> |
103 | /// List of localID locks for mutex processing of script events | 103 | /// List of localID locks for mutex processing of script events |
104 | /// </summary> | 104 | /// </summary> |
105 | private List<uint> objectLocks = new List<uint>(); | 105 | private List<uint> objectLocks = new List<uint>(); |
106 | 106 | ||
107 | private object tryLockLock = new object(); // Mutex lock object | 107 | private object tryLockLock = new object(); // Mutex lock object |
108 | 108 | ||
109 | private ScriptEngine m_ScriptEngine; | 109 | private ScriptEngine m_ScriptEngine; |
110 | 110 | ||
111 | public EventQueueManager(ScriptEngine _ScriptEngine) | 111 | public EventQueueManager(ScriptEngine _ScriptEngine) |
112 | { | 112 | { |
113 | m_ScriptEngine = _ScriptEngine; | 113 | m_ScriptEngine = _ScriptEngine; |
114 | 114 | ||
115 | // | 115 | // |
116 | // Start event queue processing threads (worker threads) | 116 | // Start event queue processing threads (worker threads) |
117 | // | 117 | // |
118 | for (int ThreadCount = 0; ThreadCount <= numberOfThreads; ThreadCount++) | 118 | for (int ThreadCount = 0; ThreadCount <= numberOfThreads; ThreadCount++) |
119 | { | 119 | { |
120 | Thread EventQueueThread = new Thread(EventQueueThreadLoop); | 120 | Thread EventQueueThread = new Thread(EventQueueThreadLoop); |
121 | eventQueueThreads.Add(EventQueueThread); | 121 | eventQueueThreads.Add(EventQueueThread); |
122 | EventQueueThread.IsBackground = true; | 122 | EventQueueThread.IsBackground = true; |
123 | EventQueueThread.Priority = ThreadPriority.BelowNormal; | 123 | EventQueueThread.Priority = ThreadPriority.BelowNormal; |
124 | EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; | 124 | EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; |
125 | EventQueueThread.Start(); | 125 | EventQueueThread.Start(); |
126 | } | 126 | } |
127 | } | 127 | } |
128 | 128 | ||
129 | ~EventQueueManager() | 129 | ~EventQueueManager() |
130 | { | 130 | { |
131 | // Kill worker threads | 131 | // Kill worker threads |
132 | foreach (Thread EventQueueThread in new ArrayList(eventQueueThreads)) | 132 | foreach (Thread EventQueueThread in new ArrayList(eventQueueThreads)) |
133 | { | 133 | { |
134 | if (EventQueueThread != null && EventQueueThread.IsAlive == true) | 134 | if (EventQueueThread != null && EventQueueThread.IsAlive == true) |
135 | { | 135 | { |
136 | try | 136 | try |
137 | { | 137 | { |
138 | EventQueueThread.Abort(); | 138 | EventQueueThread.Abort(); |
139 | EventQueueThread.Join(); | 139 | EventQueueThread.Join(); |
140 | } | 140 | } |
141 | catch (Exception) | 141 | catch (Exception) |
142 | { | 142 | { |
143 | //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Exception killing worker thread: " + e.ToString()); | 143 | //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Exception killing worker thread: " + e.ToString()); |
144 | } | 144 | } |
145 | } | 145 | } |
146 | } | 146 | } |
147 | eventQueueThreads.Clear(); | 147 | eventQueueThreads.Clear(); |
148 | // Todo: Clean up our queues | 148 | // Todo: Clean up our queues |
149 | eventQueue.Clear(); | 149 | eventQueue.Clear(); |
150 | } | 150 | } |
151 | 151 | ||
152 | /// <summary> | 152 | /// <summary> |
153 | /// Queue processing thread loop | 153 | /// Queue processing thread loop |
154 | /// </summary> | 154 | /// </summary> |
155 | private void EventQueueThreadLoop() | 155 | private void EventQueueThreadLoop() |
156 | { | 156 | { |
157 | //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Worker thread spawned"); | 157 | //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Worker thread spawned"); |
158 | try | 158 | try |
159 | { | 159 | { |
160 | QueueItemStruct BlankQIS = new QueueItemStruct(); | 160 | QueueItemStruct BlankQIS = new QueueItemStruct(); |
161 | while (true) | 161 | while (true) |
162 | { | 162 | { |
163 | try | 163 | try |
164 | { | 164 | { |
165 | QueueItemStruct QIS = BlankQIS; | 165 | QueueItemStruct QIS = BlankQIS; |
166 | bool GotItem = false; | 166 | bool GotItem = false; |
167 | 167 | ||
168 | if (eventQueue.Count == 0) | 168 | if (eventQueue.Count == 0) |
169 | { | 169 | { |
170 | // Nothing to do? Sleep a bit waiting for something to do | 170 | // Nothing to do? Sleep a bit waiting for something to do |
171 | Thread.Sleep(nothingToDoSleepms); | 171 | Thread.Sleep(nothingToDoSleepms); |
172 | } | 172 | } |
173 | else | 173 | else |
174 | { | 174 | { |
175 | // Something in queue, process | 175 | // Something in queue, process |
176 | //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName); | 176 | //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName); |
177 | 177 | ||
178 | // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD | 178 | // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD |
179 | lock (queueLock) | 179 | lock (queueLock) |
180 | { | 180 | { |
181 | GotItem = false; | 181 | GotItem = false; |
182 | for (int qc = 0; qc < eventQueue.Count; qc++) | 182 | for (int qc = 0; qc < eventQueue.Count; qc++) |
183 | { | 183 | { |
184 | // Get queue item | 184 | // Get queue item |
185 | QIS = eventQueue.Dequeue(); | 185 | QIS = eventQueue.Dequeue(); |
186 | 186 | ||
187 | // Check if object is being processed by someone else | 187 | // Check if object is being processed by someone else |
188 | if (TryLock(QIS.localID) == false) | 188 | if (TryLock(QIS.localID) == false) |
189 | { | 189 | { |
190 | // Object is already being processed, requeue it | 190 | // Object is already being processed, requeue it |
191 | eventQueue.Enqueue(QIS); | 191 | eventQueue.Enqueue(QIS); |
192 | } | 192 | } |
193 | else | 193 | else |
194 | { | 194 | { |
195 | // We have lock on an object and can process it | 195 | // We have lock on an object and can process it |
196 | GotItem = true; | 196 | GotItem = true; |
197 | break; | 197 | break; |
198 | } | 198 | } |
199 | } // go through queue | 199 | } // go through queue |
200 | } // lock | 200 | } // lock |
201 | 201 | ||
202 | if (GotItem == true) | 202 | if (GotItem == true) |
203 | { | 203 | { |
204 | // Execute function | 204 | // Execute function |
205 | try | 205 | try |
206 | { | 206 | { |
207 | #if DEBUG | 207 | #if DEBUG |
208 | m_ScriptEngine.Log.Debug("ScriptEngine", "Executing event:\r\n" | 208 | m_ScriptEngine.Log.Debug("ScriptEngine", "Executing event:\r\n" |
209 | + "QIS.localID: " + QIS.localID | 209 | + "QIS.localID: " + QIS.localID |
210 | + ", QIS.itemID: " + QIS.itemID | 210 | + ", QIS.itemID: " + QIS.itemID |
211 | + ", QIS.functionName: " + QIS.functionName); | 211 | + ", QIS.functionName: " + QIS.functionName); |
212 | #endif | 212 | #endif |
213 | m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID, | 213 | m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID, |
214 | QIS.functionName, QIS.param); | 214 | QIS.functionName, QIS.param); |
215 | } | 215 | } |
216 | catch (Exception e) | 216 | catch (Exception e) |
217 | { | 217 | { |
218 | // DISPLAY ERROR INWORLD | 218 | // DISPLAY ERROR INWORLD |
219 | string text = "Error executing script function \"" + QIS.functionName + "\":\r\n"; | 219 | string text = "Error executing script function \"" + QIS.functionName + "\":\r\n"; |
220 | //if (e.InnerException != null) | 220 | //if (e.InnerException != null) |
221 | //{ | 221 | //{ |
222 | // Send inner exception | 222 | // Send inner exception |
223 | text += e.InnerException.Message.ToString(); | 223 | text += e.InnerException.Message.ToString(); |
224 | //} | 224 | //} |
225 | //else | 225 | //else |
226 | //{ | 226 | //{ |
227 | text += "\r\n"; | 227 | text += "\r\n"; |
228 | // Send normal | 228 | // Send normal |
229 | text += e.Message.ToString(); | 229 | text += e.Message.ToString(); |
230 | //} | 230 | //} |
231 | try | 231 | try |
232 | { | 232 | { |
233 | if (text.Length > 1500) | 233 | if (text.Length > 1500) |
234 | text = text.Substring(0, 1500); | 234 | text = text.Substring(0, 1500); |
235 | IScriptHost m_host = m_ScriptEngine.World.GetSceneObjectPart(QIS.localID); | 235 | IScriptHost m_host = m_ScriptEngine.World.GetSceneObjectPart(QIS.localID); |
236 | //if (m_host != null) | 236 | //if (m_host != null) |
237 | //{ | 237 | //{ |
238 | m_ScriptEngine.World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, | 238 | m_ScriptEngine.World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, |
239 | m_host.AbsolutePosition, m_host.Name, m_host.UUID); | 239 | m_host.AbsolutePosition, m_host.Name, m_host.UUID); |
240 | } | 240 | } |
241 | catch | 241 | catch |
242 | { | 242 | { |
243 | //} | 243 | //} |
244 | //else | 244 | //else |
245 | //{ | 245 | //{ |
246 | // T oconsole | 246 | // T oconsole |
247 | m_ScriptEngine.Log.Error("ScriptEngine", | 247 | m_ScriptEngine.Log.Error("ScriptEngine", |
248 | "Unable to send text in-world:\r\n" + text); | 248 | "Unable to send text in-world:\r\n" + text); |
249 | } | 249 | } |
250 | } | 250 | } |
251 | finally | 251 | finally |
252 | { | 252 | { |
253 | ReleaseLock(QIS.localID); | 253 | ReleaseLock(QIS.localID); |
254 | } | 254 | } |
255 | } | 255 | } |
256 | } // Something in queue | 256 | } // Something in queue |
257 | } | 257 | } |
258 | catch (ThreadAbortException tae) | 258 | catch (ThreadAbortException tae) |
259 | { | 259 | { |
260 | throw tae; | 260 | throw tae; |
261 | } | 261 | } |
262 | catch (Exception e) | 262 | catch (Exception e) |
263 | { | 263 | { |
264 | m_ScriptEngine.Log.Error("ScriptEngine", "Exception in EventQueueThreadLoop: " + e.ToString()); | 264 | m_ScriptEngine.Log.Error("ScriptEngine", "Exception in EventQueueThreadLoop: " + e.ToString()); |
265 | } | 265 | } |
266 | } // while | 266 | } // while |
267 | } // try | 267 | } // try |
268 | catch (ThreadAbortException) | 268 | catch (ThreadAbortException) |
269 | { | 269 | { |
270 | //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Worker thread killed: " + tae.Message); | 270 | //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Worker thread killed: " + tae.Message); |
271 | } | 271 | } |
272 | } | 272 | } |
273 | 273 | ||
274 | /// <summary> | 274 | /// <summary> |
275 | /// Try to get a mutex lock on localID | 275 | /// Try to get a mutex lock on localID |
276 | /// </summary> | 276 | /// </summary> |
277 | /// <param name="localID"></param> | 277 | /// <param name="localID"></param> |
278 | /// <returns></returns> | 278 | /// <returns></returns> |
279 | private bool TryLock(uint localID) | 279 | private bool TryLock(uint localID) |
280 | { | 280 | { |
281 | lock (tryLockLock) | 281 | lock (tryLockLock) |
282 | { | 282 | { |
283 | if (objectLocks.Contains(localID) == true) | 283 | if (objectLocks.Contains(localID) == true) |
284 | { | 284 | { |
285 | return false; | 285 | return false; |
286 | } | 286 | } |
287 | else | 287 | else |
288 | { | 288 | { |
289 | objectLocks.Add(localID); | 289 | objectLocks.Add(localID); |
290 | return true; | 290 | return true; |
291 | } | 291 | } |
292 | } | 292 | } |
293 | } | 293 | } |
294 | 294 | ||
295 | /// <summary> | 295 | /// <summary> |
296 | /// Release mutex lock on localID | 296 | /// Release mutex lock on localID |
297 | /// </summary> | 297 | /// </summary> |
298 | /// <param name="localID"></param> | 298 | /// <param name="localID"></param> |
299 | private void ReleaseLock(uint localID) | 299 | private void ReleaseLock(uint localID) |
300 | { | 300 | { |
301 | lock (tryLockLock) | 301 | lock (tryLockLock) |
302 | { | 302 | { |
303 | if (objectLocks.Contains(localID) == true) | 303 | if (objectLocks.Contains(localID) == true) |
304 | { | 304 | { |
305 | objectLocks.Remove(localID); | 305 | objectLocks.Remove(localID); |
306 | } | 306 | } |
307 | } | 307 | } |
308 | } | 308 | } |
309 | 309 | ||
310 | 310 | ||
311 | /// <summary> | 311 | /// <summary> |
312 | /// Add event to event execution queue | 312 | /// Add event to event execution queue |
313 | /// </summary> | 313 | /// </summary> |
314 | /// <param name="localID"></param> | 314 | /// <param name="localID"></param> |
315 | /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param> | 315 | /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param> |
316 | /// <param name="param">Array of parameters to match event mask</param> | 316 | /// <param name="param">Array of parameters to match event mask</param> |
317 | public void AddToObjectQueue(uint localID, string FunctionName, params object[] param) | 317 | public void AddToObjectQueue(uint localID, string FunctionName, params object[] param) |
318 | { | 318 | { |
319 | // Determine all scripts in Object and add to their queue | 319 | // Determine all scripts in Object and add to their queue |
320 | //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Adding localID: " + localID + ", FunctionName: " + FunctionName); | 320 | //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Adding localID: " + localID + ", FunctionName: " + FunctionName); |
321 | 321 | ||
322 | 322 | ||
323 | // Do we have any scripts in this object at all? If not, return | 323 | // Do we have any scripts in this object at all? If not, return |
324 | if (m_ScriptEngine.m_ScriptManager.Scripts.ContainsKey(localID) == false) | 324 | if (m_ScriptEngine.m_ScriptManager.Scripts.ContainsKey(localID) == false) |
325 | { | 325 | { |
326 | //Console.WriteLine("Event \"" + FunctionName + "\" for localID: " + localID + ". No scripts found on this localID."); | 326 | //Console.WriteLine("Event \"" + FunctionName + "\" for localID: " + localID + ". No scripts found on this localID."); |
327 | return; | 327 | return; |
328 | } | 328 | } |
329 | 329 | ||
330 | Dictionary<LLUUID, IScript>.KeyCollection scriptKeys = | 330 | Dictionary<LLUUID, IScript>.KeyCollection scriptKeys = |
331 | m_ScriptEngine.m_ScriptManager.GetScriptKeys(localID); | 331 | m_ScriptEngine.m_ScriptManager.GetScriptKeys(localID); |
332 | 332 | ||
333 | foreach (LLUUID itemID in scriptKeys) | 333 | foreach (LLUUID itemID in scriptKeys) |
334 | { | 334 | { |
335 | // Add to each script in that object | 335 | // Add to each script in that object |
336 | // TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter? | 336 | // TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter? |
337 | AddToScriptQueue(localID, itemID, FunctionName, param); | 337 | AddToScriptQueue(localID, itemID, FunctionName, param); |
338 | } | 338 | } |
339 | } | 339 | } |
340 | 340 | ||
341 | /// <summary> | 341 | /// <summary> |
342 | /// Add event to event execution queue | 342 | /// Add event to event execution queue |
343 | /// </summary> | 343 | /// </summary> |
344 | /// <param name="localID"></param> | 344 | /// <param name="localID"></param> |
345 | /// <param name="itemID"></param> | 345 | /// <param name="itemID"></param> |
346 | /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param> | 346 | /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param> |
347 | /// <param name="param">Array of parameters to match event mask</param> | 347 | /// <param name="param">Array of parameters to match event mask</param> |
348 | public void AddToScriptQueue(uint localID, LLUUID itemID, string FunctionName, params object[] param) | 348 | public void AddToScriptQueue(uint localID, LLUUID itemID, string FunctionName, params object[] param) |
349 | { | 349 | { |
350 | lock (queueLock) | 350 | lock (queueLock) |
351 | { | 351 | { |
352 | // Create a structure and add data | 352 | // Create a structure and add data |
353 | QueueItemStruct QIS = new QueueItemStruct(); | 353 | QueueItemStruct QIS = new QueueItemStruct(); |
354 | QIS.localID = localID; | 354 | QIS.localID = localID; |
355 | QIS.itemID = itemID; | 355 | QIS.itemID = itemID; |
356 | QIS.functionName = FunctionName; | 356 | QIS.functionName = FunctionName; |
357 | QIS.param = param; | 357 | QIS.param = param; |
358 | 358 | ||
359 | // Add it to queue | 359 | // Add it to queue |
360 | eventQueue.Enqueue(QIS); | 360 | eventQueue.Enqueue(QIS); |
361 | } | 361 | } |
362 | } | 362 | } |
363 | } | 363 | } |
364 | } \ No newline at end of file | 364 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs index 94241eb..635c32a 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs | |||
@@ -1,295 +1,295 @@ | |||
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 | ||
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Threading; | 31 | using System.Threading; |
32 | using libsecondlife; | 32 | using libsecondlife; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | using OpenSim.Region.Environment.Modules; | 34 | using OpenSim.Region.Environment.Modules; |
35 | 35 | ||
36 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 36 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase |
37 | { | 37 | { |
38 | /// <summary> | 38 | /// <summary> |
39 | /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc. | 39 | /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc. |
40 | /// </summary> | 40 | /// </summary> |
41 | public class LSLLongCmdHandler | 41 | public class LSLLongCmdHandler |
42 | { | 42 | { |
43 | private Thread cmdHandlerThread; | 43 | private Thread cmdHandlerThread; |
44 | private int cmdHandlerThreadCycleSleepms = 100; | 44 | private int cmdHandlerThreadCycleSleepms = 100; |
45 | 45 | ||
46 | private ScriptEngine m_ScriptEngine; | 46 | private ScriptEngine m_ScriptEngine; |
47 | 47 | ||
48 | public LSLLongCmdHandler(ScriptEngine _ScriptEngine) | 48 | public LSLLongCmdHandler(ScriptEngine _ScriptEngine) |
49 | { | 49 | { |
50 | m_ScriptEngine = _ScriptEngine; | 50 | m_ScriptEngine = _ScriptEngine; |
51 | 51 | ||
52 | // Start the thread that will be doing the work | 52 | // Start the thread that will be doing the work |
53 | cmdHandlerThread = new Thread(CmdHandlerThreadLoop); | 53 | cmdHandlerThread = new Thread(CmdHandlerThreadLoop); |
54 | cmdHandlerThread.Name = "CmdHandlerThread"; | 54 | cmdHandlerThread.Name = "CmdHandlerThread"; |
55 | cmdHandlerThread.Priority = ThreadPriority.BelowNormal; | 55 | cmdHandlerThread.Priority = ThreadPriority.BelowNormal; |
56 | cmdHandlerThread.IsBackground = true; | 56 | cmdHandlerThread.IsBackground = true; |
57 | cmdHandlerThread.Start(); | 57 | cmdHandlerThread.Start(); |
58 | } | 58 | } |
59 | 59 | ||
60 | ~LSLLongCmdHandler() | 60 | ~LSLLongCmdHandler() |
61 | { | 61 | { |
62 | // Shut down thread | 62 | // Shut down thread |
63 | try | 63 | try |
64 | { | 64 | { |
65 | if (cmdHandlerThread != null) | 65 | if (cmdHandlerThread != null) |
66 | { | 66 | { |
67 | if (cmdHandlerThread.IsAlive == true) | 67 | if (cmdHandlerThread.IsAlive == true) |
68 | { | 68 | { |
69 | cmdHandlerThread.Abort(); | 69 | cmdHandlerThread.Abort(); |
70 | cmdHandlerThread.Join(); | 70 | cmdHandlerThread.Join(); |
71 | } | 71 | } |
72 | } | 72 | } |
73 | } | 73 | } |
74 | catch | 74 | catch |
75 | { | 75 | { |
76 | } | 76 | } |
77 | } | 77 | } |
78 | 78 | ||
79 | private void CmdHandlerThreadLoop() | 79 | private void CmdHandlerThreadLoop() |
80 | { | 80 | { |
81 | while (true) | 81 | while (true) |
82 | { | 82 | { |
83 | // Check timers | 83 | // Check timers |
84 | CheckTimerEvents(); | 84 | CheckTimerEvents(); |
85 | Thread.Sleep(25); | 85 | Thread.Sleep(25); |
86 | // Check HttpRequests | 86 | // Check HttpRequests |
87 | CheckHttpRequests(); | 87 | CheckHttpRequests(); |
88 | Thread.Sleep(25); | 88 | Thread.Sleep(25); |
89 | // Check XMLRPCRequests | 89 | // Check XMLRPCRequests |
90 | CheckXMLRPCRequests(); | 90 | CheckXMLRPCRequests(); |
91 | Thread.Sleep(25); | 91 | Thread.Sleep(25); |
92 | // Check Listeners | 92 | // Check Listeners |
93 | CheckListeners(); | 93 | CheckListeners(); |
94 | Thread.Sleep(25); | 94 | Thread.Sleep(25); |
95 | 95 | ||
96 | // Sleep before next cycle | 96 | // Sleep before next cycle |
97 | //Thread.Sleep(cmdHandlerThreadCycleSleepms); | 97 | //Thread.Sleep(cmdHandlerThreadCycleSleepms); |
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | /// <summary> | 101 | /// <summary> |
102 | /// Remove a specific script (and all its pending commands) | 102 | /// Remove a specific script (and all its pending commands) |
103 | /// </summary> | 103 | /// </summary> |
104 | /// <param name="m_localID"></param> | 104 | /// <param name="m_localID"></param> |
105 | /// <param name="m_itemID"></param> | 105 | /// <param name="m_itemID"></param> |
106 | public void RemoveScript(uint localID, LLUUID itemID) | 106 | public void RemoveScript(uint localID, LLUUID itemID) |
107 | { | 107 | { |
108 | // Remove a specific script | 108 | // Remove a specific script |
109 | 109 | ||
110 | // Remove from: Timers | 110 | // Remove from: Timers |
111 | UnSetTimerEvents(localID, itemID); | 111 | UnSetTimerEvents(localID, itemID); |
112 | // Remove from: HttpRequest | 112 | // Remove from: HttpRequest |
113 | IHttpRequests iHttpReq = | 113 | IHttpRequests iHttpReq = |
114 | m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); | 114 | m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); |
115 | iHttpReq.StopHttpRequest(localID, itemID); | 115 | iHttpReq.StopHttpRequest(localID, itemID); |
116 | } | 116 | } |
117 | 117 | ||
118 | #region TIMER | 118 | #region TIMER |
119 | 119 | ||
120 | // | 120 | // |
121 | // TIMER | 121 | // TIMER |
122 | // | 122 | // |
123 | private class TimerClass | 123 | private class TimerClass |
124 | { | 124 | { |
125 | public uint localID; | 125 | public uint localID; |
126 | public LLUUID itemID; | 126 | public LLUUID itemID; |
127 | public double interval; | 127 | public double interval; |
128 | public DateTime next; | 128 | public DateTime next; |
129 | } | 129 | } |
130 | 130 | ||
131 | private List<TimerClass> Timers = new List<TimerClass>(); | 131 | private List<TimerClass> Timers = new List<TimerClass>(); |
132 | private object TimerListLock = new object(); | 132 | private object TimerListLock = new object(); |
133 | 133 | ||
134 | public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec) | 134 | public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec) |
135 | { | 135 | { |
136 | Console.WriteLine("SetTimerEvent"); | 136 | Console.WriteLine("SetTimerEvent"); |
137 | 137 | ||
138 | // Always remove first, in case this is a re-set | 138 | // Always remove first, in case this is a re-set |
139 | UnSetTimerEvents(m_localID, m_itemID); | 139 | UnSetTimerEvents(m_localID, m_itemID); |
140 | if (sec == 0) // Disabling timer | 140 | if (sec == 0) // Disabling timer |
141 | return; | 141 | return; |
142 | 142 | ||
143 | // Add to timer | 143 | // Add to timer |
144 | TimerClass ts = new TimerClass(); | 144 | TimerClass ts = new TimerClass(); |
145 | ts.localID = m_localID; | 145 | ts.localID = m_localID; |
146 | ts.itemID = m_itemID; | 146 | ts.itemID = m_itemID; |
147 | ts.interval = sec; | 147 | ts.interval = sec; |
148 | ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); | 148 | ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); |
149 | lock (TimerListLock) | 149 | lock (TimerListLock) |
150 | { | 150 | { |
151 | Timers.Add(ts); | 151 | Timers.Add(ts); |
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
155 | public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID) | 155 | public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID) |
156 | { | 156 | { |
157 | // Remove from timer | 157 | // Remove from timer |
158 | lock (TimerListLock) | 158 | lock (TimerListLock) |
159 | { | 159 | { |
160 | List<TimerClass> NewTimers = new List<TimerClass>(); | 160 | List<TimerClass> NewTimers = new List<TimerClass>(); |
161 | foreach (TimerClass ts in Timers) | 161 | foreach (TimerClass ts in Timers) |
162 | { | 162 | { |
163 | if (ts.localID != m_localID && ts.itemID != m_itemID) | 163 | if (ts.localID != m_localID && ts.itemID != m_itemID) |
164 | { | 164 | { |
165 | NewTimers.Add(ts); | 165 | NewTimers.Add(ts); |
166 | } | 166 | } |
167 | } | 167 | } |
168 | Timers.Clear(); | 168 | Timers.Clear(); |
169 | Timers = NewTimers; | 169 | Timers = NewTimers; |
170 | } | 170 | } |
171 | } | 171 | } |
172 | 172 | ||
173 | public void CheckTimerEvents() | 173 | public void CheckTimerEvents() |
174 | { | 174 | { |
175 | // Nothing to do here? | 175 | // Nothing to do here? |
176 | if (Timers.Count == 0) | 176 | if (Timers.Count == 0) |
177 | return; | 177 | return; |
178 | 178 | ||
179 | lock (TimerListLock) | 179 | lock (TimerListLock) |
180 | { | 180 | { |
181 | // Go through all timers | 181 | // Go through all timers |
182 | foreach (TimerClass ts in Timers) | 182 | foreach (TimerClass ts in Timers) |
183 | { | 183 | { |
184 | // Time has passed? | 184 | // Time has passed? |
185 | if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) | 185 | if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) |
186 | { | 186 | { |
187 | // Add it to queue | 187 | // Add it to queue |
188 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", | 188 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", |
189 | new object[] {}); | 189 | new object[] {}); |
190 | // set next interval | 190 | // set next interval |
191 | 191 | ||
192 | 192 | ||
193 | ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); | 193 | ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); |
194 | } | 194 | } |
195 | } | 195 | } |
196 | } // lock | 196 | } // lock |
197 | } | 197 | } |
198 | 198 | ||
199 | #endregion | 199 | #endregion |
200 | 200 | ||
201 | #region HTTP REQUEST | 201 | #region HTTP REQUEST |
202 | 202 | ||
203 | public void CheckHttpRequests() | 203 | public void CheckHttpRequests() |
204 | { | 204 | { |
205 | if (m_ScriptEngine.World == null) | 205 | if (m_ScriptEngine.World == null) |
206 | return; | 206 | return; |
207 | 207 | ||
208 | IHttpRequests iHttpReq = | 208 | IHttpRequests iHttpReq = |
209 | m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); | 209 | m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); |
210 | 210 | ||
211 | HttpRequestClass httpInfo = null; | 211 | HttpRequestClass httpInfo = null; |
212 | 212 | ||
213 | if (iHttpReq != null) | 213 | if (iHttpReq != null) |
214 | httpInfo = iHttpReq.GetNextCompletedRequest(); | 214 | httpInfo = iHttpReq.GetNextCompletedRequest(); |
215 | 215 | ||
216 | while (httpInfo != null) | 216 | while (httpInfo != null) |
217 | { | 217 | { |
218 | //Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status); | 218 | //Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status); |
219 | 219 | ||
220 | // Deliver data to prim's remote_data handler | 220 | // Deliver data to prim's remote_data handler |
221 | // | 221 | // |
222 | // TODO: Returning null for metadata, since the lsl function | 222 | // TODO: Returning null for metadata, since the lsl function |
223 | // only returns the byte for HTTP_BODY_TRUNCATED, which is not | 223 | // only returns the byte for HTTP_BODY_TRUNCATED, which is not |
224 | // implemented here yet anyway. Should be fixed if/when maxsize | 224 | // implemented here yet anyway. Should be fixed if/when maxsize |
225 | // is supported | 225 | // is supported |
226 | 226 | ||
227 | object[] resobj = new object[] | 227 | object[] resobj = new object[] |
228 | { | 228 | { |
229 | httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body | 229 | httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body |
230 | }; | 230 | }; |
231 | 231 | ||
232 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( | 232 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( |
233 | httpInfo.localID, httpInfo.itemID, "http_response", resobj | 233 | httpInfo.localID, httpInfo.itemID, "http_response", resobj |
234 | ); | 234 | ); |
235 | 235 | ||
236 | httpInfo.Stop(); | 236 | httpInfo.Stop(); |
237 | httpInfo = null; | 237 | httpInfo = null; |
238 | 238 | ||
239 | httpInfo = iHttpReq.GetNextCompletedRequest(); | 239 | httpInfo = iHttpReq.GetNextCompletedRequest(); |
240 | } | 240 | } |
241 | } | 241 | } |
242 | 242 | ||
243 | #endregion | 243 | #endregion |
244 | 244 | ||
245 | public void CheckXMLRPCRequests() | 245 | public void CheckXMLRPCRequests() |
246 | { | 246 | { |
247 | if (m_ScriptEngine.World == null) | 247 | if (m_ScriptEngine.World == null) |
248 | return; | 248 | return; |
249 | 249 | ||
250 | IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); | 250 | IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); |
251 | 251 | ||
252 | if (xmlrpc != null) | 252 | if (xmlrpc != null) |
253 | { | 253 | { |
254 | while (xmlrpc.hasRequests()) | 254 | while (xmlrpc.hasRequests()) |
255 | { | 255 | { |
256 | RPCRequestInfo rInfo = xmlrpc.GetNextRequest(); | 256 | RPCRequestInfo rInfo = xmlrpc.GetNextRequest(); |
257 | //Console.WriteLine("PICKED REQUEST"); | 257 | //Console.WriteLine("PICKED REQUEST"); |
258 | 258 | ||
259 | //Deliver data to prim's remote_data handler | 259 | //Deliver data to prim's remote_data handler |
260 | object[] resobj = new object[] | 260 | object[] resobj = new object[] |
261 | { | 261 | { |
262 | 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), "", | 262 | 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), "", |
263 | rInfo.GetIntValue(), | 263 | rInfo.GetIntValue(), |
264 | rInfo.GetStrVal() | 264 | rInfo.GetStrVal() |
265 | }; | 265 | }; |
266 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( | 266 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( |
267 | rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", resobj | 267 | rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", resobj |
268 | ); | 268 | ); |
269 | } | 269 | } |
270 | } | 270 | } |
271 | } | 271 | } |
272 | 272 | ||
273 | public void CheckListeners() | 273 | public void CheckListeners() |
274 | { | 274 | { |
275 | if (m_ScriptEngine.World == null) | 275 | if (m_ScriptEngine.World == null) |
276 | return; | 276 | return; |
277 | IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); | 277 | IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); |
278 | 278 | ||
279 | while (comms.HasMessages()) | 279 | while (comms.HasMessages()) |
280 | { | 280 | { |
281 | ListenerInfo lInfo = comms.GetNextMessage(); | 281 | ListenerInfo lInfo = comms.GetNextMessage(); |
282 | 282 | ||
283 | //Deliver data to prim's listen handler | 283 | //Deliver data to prim's listen handler |
284 | object[] resobj = new object[] | 284 | object[] resobj = new object[] |
285 | { | 285 | { |
286 | lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage() | 286 | lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage() |
287 | }; | 287 | }; |
288 | 288 | ||
289 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( | 289 | m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( |
290 | lInfo.GetLocalID(), lInfo.GetItemID(), "listen", resobj | 290 | lInfo.GetLocalID(), lInfo.GetItemID(), "listen", resobj |
291 | ); | 291 | ); |
292 | } | 292 | } |
293 | } | 293 | } |
294 | } | 294 | } |
295 | } \ No newline at end of file | 295 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs index 39d0bc3..da0baba 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs | |||
@@ -1,132 +1,132 @@ | |||
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 | ||
29 | 29 | ||
30 | using System; | 30 | using System; |
31 | using Nini.Config; | 31 | using Nini.Config; |
32 | using OpenSim.Framework.Console; | 32 | using OpenSim.Framework.Console; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | using OpenSim.Region.Environment.Scenes; | 34 | using OpenSim.Region.Environment.Scenes; |
35 | using OpenSim.Region.ScriptEngine.Common; | 35 | using OpenSim.Region.ScriptEngine.Common; |
36 | using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase; | 36 | using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase; |
37 | 37 | ||
38 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 38 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase |
39 | { | 39 | { |
40 | /// <summary> | 40 | /// <summary> |
41 | /// This is the root object for ScriptEngine. Objects access each other trough this class. | 41 | /// This is the root object for ScriptEngine. Objects access each other trough this class. |
42 | /// </summary> | 42 | /// </summary> |
43 | /// | 43 | /// |
44 | [Serializable] | 44 | [Serializable] |
45 | public abstract class ScriptEngine : IRegionModule, OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.ScriptEngine | 45 | public abstract class ScriptEngine : IRegionModule, OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.ScriptEngine |
46 | { | 46 | { |
47 | public Scene World; | 47 | public Scene World; |
48 | public EventManager m_EventManager; // Handles and queues incoming events from OpenSim | 48 | public EventManager m_EventManager; // Handles and queues incoming events from OpenSim |
49 | public EventQueueManager m_EventQueueManager; // Executes events | 49 | public EventQueueManager m_EventQueueManager; // Executes events |
50 | public ScriptManager m_ScriptManager; // Load, unload and execute scripts | 50 | public ScriptManager m_ScriptManager; // Load, unload and execute scripts |
51 | public AppDomainManager m_AppDomainManager; | 51 | public AppDomainManager m_AppDomainManager; |
52 | public LSLLongCmdHandler m_LSLLongCmdHandler; | 52 | public LSLLongCmdHandler m_LSLLongCmdHandler; |
53 | 53 | ||
54 | public ScriptManager GetScriptManager() | 54 | public ScriptManager GetScriptManager() |
55 | { | 55 | { |
56 | return _GetScriptManager(); | 56 | return _GetScriptManager(); |
57 | } | 57 | } |
58 | public abstract ScriptManager _GetScriptManager(); | 58 | public abstract ScriptManager _GetScriptManager(); |
59 | 59 | ||
60 | private LogBase m_log; | 60 | private LogBase m_log; |
61 | 61 | ||
62 | public ScriptEngine() | 62 | public ScriptEngine() |
63 | { | 63 | { |
64 | //Common.SendToDebug("ScriptEngine Object Initialized"); | 64 | //Common.SendToDebug("ScriptEngine Object Initialized"); |
65 | Common.mySE = this; | 65 | Common.mySE = this; |
66 | } | 66 | } |
67 | 67 | ||
68 | public LogBase Log | 68 | public LogBase Log |
69 | { | 69 | { |
70 | get { return m_log; } | 70 | get { return m_log; } |
71 | } | 71 | } |
72 | 72 | ||
73 | public void InitializeEngine(Scene Sceneworld, LogBase logger, bool HookUpToServer, ScriptManager newScriptManager) | 73 | public void InitializeEngine(Scene Sceneworld, LogBase logger, bool HookUpToServer, ScriptManager newScriptManager) |
74 | { | 74 | { |
75 | World = Sceneworld; | 75 | World = Sceneworld; |
76 | m_log = logger; | 76 | m_log = logger; |
77 | 77 | ||
78 | Log.Verbose("ScriptEngine", "DotNet & LSL ScriptEngine initializing"); | 78 | Log.Verbose("ScriptEngine", "DotNet & LSL ScriptEngine initializing"); |
79 | 79 | ||
80 | //m_logger.Status("ScriptEngine", "InitializeEngine"); | 80 | //m_logger.Status("ScriptEngine", "InitializeEngine"); |
81 | 81 | ||
82 | // Create all objects we'll be using | 82 | // Create all objects we'll be using |
83 | m_EventQueueManager = new EventQueueManager(this); | 83 | m_EventQueueManager = new EventQueueManager(this); |
84 | m_EventManager = new EventManager(this, HookUpToServer); | 84 | m_EventManager = new EventManager(this, HookUpToServer); |
85 | m_ScriptManager = newScriptManager; | 85 | m_ScriptManager = newScriptManager; |
86 | //m_ScriptManager = new ScriptManager(this); | 86 | //m_ScriptManager = new ScriptManager(this); |
87 | m_AppDomainManager = new AppDomainManager(); | 87 | m_AppDomainManager = new AppDomainManager(); |
88 | m_LSLLongCmdHandler = new LSLLongCmdHandler(this); | 88 | m_LSLLongCmdHandler = new LSLLongCmdHandler(this); |
89 | 89 | ||
90 | // Should we iterate the region for scripts that needs starting? | 90 | // Should we iterate the region for scripts that needs starting? |
91 | // Or can we assume we are loaded before anything else so we can use proper events? | 91 | // Or can we assume we are loaded before anything else so we can use proper events? |
92 | } | 92 | } |
93 | 93 | ||
94 | public void Shutdown() | 94 | public void Shutdown() |
95 | { | 95 | { |
96 | // We are shutting down | 96 | // We are shutting down |
97 | } | 97 | } |
98 | 98 | ||
99 | ScriptServerInterfaces.RemoteEvents ScriptServerInterfaces.ScriptEngine.EventManager() | 99 | ScriptServerInterfaces.RemoteEvents ScriptServerInterfaces.ScriptEngine.EventManager() |
100 | { | 100 | { |
101 | return this.m_EventManager; | 101 | return this.m_EventManager; |
102 | } | 102 | } |
103 | 103 | ||
104 | 104 | ||
105 | #region IRegionModule | 105 | #region IRegionModule |
106 | 106 | ||
107 | public abstract void Initialise(Scene scene, IConfigSource config); | 107 | public abstract void Initialise(Scene scene, IConfigSource config); |
108 | 108 | ||
109 | public void PostInitialise() | 109 | public void PostInitialise() |
110 | { | 110 | { |
111 | } | 111 | } |
112 | 112 | ||
113 | public void Close() | 113 | public void Close() |
114 | { | 114 | { |
115 | } | 115 | } |
116 | 116 | ||
117 | public string Name | 117 | public string Name |
118 | { | 118 | { |
119 | get { return "DotNetEngine"; } | 119 | get { return "DotNetEngine"; } |
120 | } | 120 | } |
121 | 121 | ||
122 | public bool IsSharedModule | 122 | public bool IsSharedModule |
123 | { | 123 | { |
124 | get { return false; } | 124 | get { return false; } |
125 | } | 125 | } |
126 | 126 | ||
127 | 127 | ||
128 | 128 | ||
129 | #endregion | 129 | #endregion |
130 | 130 | ||
131 | } | 131 | } |
132 | } \ No newline at end of file | 132 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs index e98ff81..8f74620 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs | |||
@@ -1,348 +1,348 @@ | |||
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 | ||
29 | 29 | ||
30 | using System; | 30 | using System; |
31 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
32 | using System.IO; | 32 | using System.IO; |
33 | using System.Reflection; | 33 | using System.Reflection; |
34 | using System.Runtime.Serialization.Formatters.Binary; | 34 | using System.Runtime.Serialization.Formatters.Binary; |
35 | using System.Threading; | 35 | using System.Threading; |
36 | using libsecondlife; | 36 | using libsecondlife; |
37 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Region.Environment.Scenes; | 38 | using OpenSim.Region.Environment.Scenes; |
39 | using OpenSim.Region.ScriptEngine.Common; | 39 | using OpenSim.Region.ScriptEngine.Common; |
40 | 40 | ||
41 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 41 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase |
42 | { | 42 | { |
43 | /// <summary> | 43 | /// <summary> |
44 | /// Loads scripts | 44 | /// Loads scripts |
45 | /// Compiles them if necessary | 45 | /// Compiles them if necessary |
46 | /// Execute functions for EventQueueManager (Sends them to script on other AppDomain for execution) | 46 | /// Execute functions for EventQueueManager (Sends them to script on other AppDomain for execution) |
47 | /// </summary> | 47 | /// </summary> |
48 | /// | 48 | /// |
49 | 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. | 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 | 51 | // * Keeps track of running scripts |
52 | // * Compiles script if necessary (through "Compiler") | 52 | // * Compiles script if necessary (through "Compiler") |
53 | // * Loads script (through "AppDomainManager" called from for example "EventQueueManager") | 53 | // * Loads script (through "AppDomainManager" called from for example "EventQueueManager") |
54 | // * Executes functions inside script (called from for example "EventQueueManager" class) | 54 | // * Executes functions inside script (called from for example "EventQueueManager" class) |
55 | // * Unloads script (through "AppDomainManager" called from for example "EventQueueManager") | 55 | // * Unloads script (through "AppDomainManager" called from for example "EventQueueManager") |
56 | // * Dedicated load/unload thread, and queues loading/unloading. | 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. | 57 | // This so that scripts starting or stopping will not slow down other theads or whole system. |
58 | // | 58 | // |
59 | [Serializable] | 59 | [Serializable] |
60 | public abstract class ScriptManager | 60 | public abstract class ScriptManager |
61 | { | 61 | { |
62 | #region Declares | 62 | #region Declares |
63 | 63 | ||
64 | private Thread scriptLoadUnloadThread; | 64 | private Thread scriptLoadUnloadThread; |
65 | private int scriptLoadUnloadThread_IdleSleepms = 100; | 65 | private int scriptLoadUnloadThread_IdleSleepms = 100; |
66 | private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); | 66 | private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); |
67 | 67 | ||
68 | 68 | ||
69 | // Load/Unload structure | 69 | // Load/Unload structure |
70 | private struct LUStruct | 70 | private struct LUStruct |
71 | { | 71 | { |
72 | public uint localID; | 72 | public uint localID; |
73 | public LLUUID itemID; | 73 | public LLUUID itemID; |
74 | public string script; | 74 | public string script; |
75 | public LUType Action; | 75 | public LUType Action; |
76 | } | 76 | } |
77 | 77 | ||
78 | private enum LUType | 78 | private enum LUType |
79 | { | 79 | { |
80 | Unknown = 0, | 80 | Unknown = 0, |
81 | Load = 1, | 81 | Load = 1, |
82 | Unload = 2 | 82 | Unload = 2 |
83 | } | 83 | } |
84 | 84 | ||
85 | // Object<string, Script<string, script>> | 85 | // Object<string, Script<string, script>> |
86 | // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. | 86 | // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. |
87 | // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! | 87 | // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! |
88 | public Dictionary<uint, Dictionary<LLUUID, IScript>> Scripts = | 88 | public Dictionary<uint, Dictionary<LLUUID, IScript>> Scripts = |
89 | new Dictionary<uint, Dictionary<LLUUID, IScript>>(); | 89 | new Dictionary<uint, Dictionary<LLUUID, IScript>>(); |
90 | 90 | ||
91 | public Scene World | 91 | public Scene World |
92 | { | 92 | { |
93 | get { return m_scriptEngine.World; } | 93 | get { return m_scriptEngine.World; } |
94 | } | 94 | } |
95 | 95 | ||
96 | #endregion | 96 | #endregion |
97 | 97 | ||
98 | #region Object init/shutdown | 98 | #region Object init/shutdown |
99 | 99 | ||
100 | public ScriptEngineBase.ScriptEngine m_scriptEngine; | 100 | public ScriptEngineBase.ScriptEngine m_scriptEngine; |
101 | 101 | ||
102 | public ScriptManager(ScriptEngineBase.ScriptEngine scriptEngine) | 102 | public ScriptManager(ScriptEngineBase.ScriptEngine scriptEngine) |
103 | { | 103 | { |
104 | m_scriptEngine = scriptEngine; | 104 | m_scriptEngine = scriptEngine; |
105 | AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); | 105 | AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); |
106 | scriptLoadUnloadThread = new Thread(ScriptLoadUnloadThreadLoop); | 106 | scriptLoadUnloadThread = new Thread(ScriptLoadUnloadThreadLoop); |
107 | scriptLoadUnloadThread.Name = "ScriptLoadUnloadThread"; | 107 | scriptLoadUnloadThread.Name = "ScriptLoadUnloadThread"; |
108 | scriptLoadUnloadThread.IsBackground = true; | 108 | scriptLoadUnloadThread.IsBackground = true; |
109 | scriptLoadUnloadThread.Priority = ThreadPriority.BelowNormal; | 109 | scriptLoadUnloadThread.Priority = ThreadPriority.BelowNormal; |
110 | scriptLoadUnloadThread.Start(); | 110 | scriptLoadUnloadThread.Start(); |
111 | } | 111 | } |
112 | 112 | ||
113 | ~ScriptManager() | 113 | ~ScriptManager() |
114 | { | 114 | { |
115 | // Abort load/unload thread | 115 | // Abort load/unload thread |
116 | try | 116 | try |
117 | { | 117 | { |
118 | if (scriptLoadUnloadThread != null) | 118 | if (scriptLoadUnloadThread != null) |
119 | { | 119 | { |
120 | if (scriptLoadUnloadThread.IsAlive == true) | 120 | if (scriptLoadUnloadThread.IsAlive == true) |
121 | { | 121 | { |
122 | scriptLoadUnloadThread.Abort(); | 122 | scriptLoadUnloadThread.Abort(); |
123 | scriptLoadUnloadThread.Join(); | 123 | scriptLoadUnloadThread.Join(); |
124 | } | 124 | } |
125 | } | 125 | } |
126 | } | 126 | } |
127 | catch | 127 | catch |
128 | { | 128 | { |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | #endregion | 132 | #endregion |
133 | 133 | ||
134 | #region Load / Unload scripts (Thread loop) | 134 | #region Load / Unload scripts (Thread loop) |
135 | 135 | ||
136 | private void ScriptLoadUnloadThreadLoop() | 136 | private void ScriptLoadUnloadThreadLoop() |
137 | { | 137 | { |
138 | try | 138 | try |
139 | { | 139 | { |
140 | while (true) | 140 | while (true) |
141 | { | 141 | { |
142 | if (LUQueue.Count == 0) | 142 | if (LUQueue.Count == 0) |
143 | Thread.Sleep(scriptLoadUnloadThread_IdleSleepms); | 143 | Thread.Sleep(scriptLoadUnloadThread_IdleSleepms); |
144 | if (LUQueue.Count > 0) | 144 | if (LUQueue.Count > 0) |
145 | { | 145 | { |
146 | LUStruct item = LUQueue.Dequeue(); | 146 | LUStruct item = LUQueue.Dequeue(); |
147 | lock (startStopLock) // Lock so we have only 1 thread working on loading/unloading of scripts | 147 | lock (startStopLock) // Lock so we have only 1 thread working on loading/unloading of scripts |
148 | { | 148 | { |
149 | if (item.Action == LUType.Unload) | 149 | if (item.Action == LUType.Unload) |
150 | { | 150 | { |
151 | _StopScript(item.localID, item.itemID); | 151 | _StopScript(item.localID, item.itemID); |
152 | } | 152 | } |
153 | if (item.Action == LUType.Load) | 153 | if (item.Action == LUType.Load) |
154 | { | 154 | { |
155 | _StartScript(item.localID, item.itemID, item.script); | 155 | _StartScript(item.localID, item.itemID, item.script); |
156 | } | 156 | } |
157 | } | 157 | } |
158 | } | 158 | } |
159 | } | 159 | } |
160 | } | 160 | } |
161 | catch (ThreadAbortException tae) | 161 | catch (ThreadAbortException tae) |
162 | { | 162 | { |
163 | string a = tae.ToString(); | 163 | string a = tae.ToString(); |
164 | a = ""; | 164 | a = ""; |
165 | // Expected | 165 | // Expected |
166 | } | 166 | } |
167 | } | 167 | } |
168 | 168 | ||
169 | #endregion | 169 | #endregion |
170 | 170 | ||
171 | #region Helper functions | 171 | #region Helper functions |
172 | 172 | ||
173 | private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) | 173 | private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) |
174 | { | 174 | { |
175 | //Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name); | 175 | //Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name); |
176 | return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null; | 176 | return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null; |
177 | } | 177 | } |
178 | 178 | ||
179 | #endregion | 179 | #endregion |
180 | 180 | ||
181 | 181 | ||
182 | 182 | ||
183 | #region Start/Stop/Reset script | 183 | #region Start/Stop/Reset script |
184 | 184 | ||
185 | private readonly Object startStopLock = new Object(); | 185 | private readonly Object startStopLock = new Object(); |
186 | 186 | ||
187 | /// <summary> | 187 | /// <summary> |
188 | /// Fetches, loads and hooks up a script to an objects events | 188 | /// Fetches, loads and hooks up a script to an objects events |
189 | /// </summary> | 189 | /// </summary> |
190 | /// <param name="itemID"></param> | 190 | /// <param name="itemID"></param> |
191 | /// <param name="localID"></param> | 191 | /// <param name="localID"></param> |
192 | public void StartScript(uint localID, LLUUID itemID, string Script) | 192 | public void StartScript(uint localID, LLUUID itemID, string Script) |
193 | { | 193 | { |
194 | LUStruct ls = new LUStruct(); | 194 | LUStruct ls = new LUStruct(); |
195 | ls.localID = localID; | 195 | ls.localID = localID; |
196 | ls.itemID = itemID; | 196 | ls.itemID = itemID; |
197 | ls.script = Script; | 197 | ls.script = Script; |
198 | ls.Action = LUType.Load; | 198 | ls.Action = LUType.Load; |
199 | LUQueue.Enqueue(ls); | 199 | LUQueue.Enqueue(ls); |
200 | } | 200 | } |
201 | 201 | ||
202 | /// <summary> | 202 | /// <summary> |
203 | /// Disables and unloads a script | 203 | /// Disables and unloads a script |
204 | /// </summary> | 204 | /// </summary> |
205 | /// <param name="localID"></param> | 205 | /// <param name="localID"></param> |
206 | /// <param name="itemID"></param> | 206 | /// <param name="itemID"></param> |
207 | public void StopScript(uint localID, LLUUID itemID) | 207 | public void StopScript(uint localID, LLUUID itemID) |
208 | { | 208 | { |
209 | LUStruct ls = new LUStruct(); | 209 | LUStruct ls = new LUStruct(); |
210 | ls.localID = localID; | 210 | ls.localID = localID; |
211 | ls.itemID = itemID; | 211 | ls.itemID = itemID; |
212 | ls.Action = LUType.Unload; | 212 | ls.Action = LUType.Unload; |
213 | LUQueue.Enqueue(ls); | 213 | LUQueue.Enqueue(ls); |
214 | } | 214 | } |
215 | 215 | ||
216 | // Create a new instance of the compiler (reuse) | 216 | // Create a new instance of the compiler (reuse) |
217 | //private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler(); | 217 | //private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler(); |
218 | 218 | ||
219 | public abstract void _StartScript(uint localID, LLUUID itemID, string Script); | 219 | public abstract void _StartScript(uint localID, LLUUID itemID, string Script); |
220 | 220 | ||
221 | public abstract void _StopScript(uint localID, LLUUID itemID); | 221 | public abstract void _StopScript(uint localID, LLUUID itemID); |
222 | 222 | ||
223 | 223 | ||
224 | #endregion | 224 | #endregion |
225 | 225 | ||
226 | #region Perform event execution in script | 226 | #region Perform event execution in script |
227 | 227 | ||
228 | /// <summary> | 228 | /// <summary> |
229 | /// Execute a LL-event-function in Script | 229 | /// Execute a LL-event-function in Script |
230 | /// </summary> | 230 | /// </summary> |
231 | /// <param name="localID">Object the script is located in</param> | 231 | /// <param name="localID">Object the script is located in</param> |
232 | /// <param name="itemID">Script ID</param> | 232 | /// <param name="itemID">Script ID</param> |
233 | /// <param name="FunctionName">Name of function</param> | 233 | /// <param name="FunctionName">Name of function</param> |
234 | /// <param name="args">Arguments to pass to function</param> | 234 | /// <param name="args">Arguments to pass to function</param> |
235 | internal void ExecuteEvent(uint localID, LLUUID itemID, string FunctionName, object[] args) | 235 | internal void ExecuteEvent(uint localID, LLUUID itemID, string FunctionName, object[] args) |
236 | { | 236 | { |
237 | #if DEBUG | 237 | #if DEBUG |
238 | Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName); | 238 | Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName); |
239 | #endif | 239 | #endif |
240 | // Execute a function in the script | 240 | // Execute a function in the script |
241 | //m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); | 241 | //m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); |
242 | //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID); | 242 | //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID); |
243 | IScript Script = GetScript(localID, itemID); | 243 | IScript Script = GetScript(localID, itemID); |
244 | if (Script == null) | 244 | if (Script == null) |
245 | return; | 245 | return; |
246 | #if DEBUG | 246 | #if DEBUG |
247 | Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); | 247 | Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); |
248 | #endif | 248 | #endif |
249 | // Must be done in correct AppDomain, so leaving it up to the script itself | 249 | // Must be done in correct AppDomain, so leaving it up to the script itself |
250 | Script.Exec.ExecuteEvent(FunctionName, args); | 250 | Script.Exec.ExecuteEvent(FunctionName, args); |
251 | } | 251 | } |
252 | 252 | ||
253 | #endregion | 253 | #endregion |
254 | 254 | ||
255 | #region Internal functions to keep track of script | 255 | #region Internal functions to keep track of script |
256 | 256 | ||
257 | public Dictionary<LLUUID, IScript>.KeyCollection GetScriptKeys(uint localID) | 257 | public Dictionary<LLUUID, IScript>.KeyCollection GetScriptKeys(uint localID) |
258 | { | 258 | { |
259 | if (Scripts.ContainsKey(localID) == false) | 259 | if (Scripts.ContainsKey(localID) == false) |
260 | return null; | 260 | return null; |
261 | 261 | ||
262 | Dictionary<LLUUID, IScript> Obj; | 262 | Dictionary<LLUUID, IScript> Obj; |
263 | Scripts.TryGetValue(localID, out Obj); | 263 | Scripts.TryGetValue(localID, out Obj); |
264 | 264 | ||
265 | return Obj.Keys; | 265 | return Obj.Keys; |
266 | } | 266 | } |
267 | 267 | ||
268 | public IScript GetScript(uint localID, LLUUID itemID) | 268 | public IScript GetScript(uint localID, LLUUID itemID) |
269 | { | 269 | { |
270 | if (Scripts.ContainsKey(localID) == false) | 270 | if (Scripts.ContainsKey(localID) == false) |
271 | return null; | 271 | return null; |
272 | 272 | ||
273 | Dictionary<LLUUID, IScript> Obj; | 273 | Dictionary<LLUUID, IScript> Obj; |
274 | Scripts.TryGetValue(localID, out Obj); | 274 | Scripts.TryGetValue(localID, out Obj); |
275 | if (Obj.ContainsKey(itemID) == false) | 275 | if (Obj.ContainsKey(itemID) == false) |
276 | return null; | 276 | return null; |
277 | 277 | ||
278 | // Get script | 278 | // Get script |
279 | IScript Script; | 279 | IScript Script; |
280 | Obj.TryGetValue(itemID, out Script); | 280 | Obj.TryGetValue(itemID, out Script); |
281 | 281 | ||
282 | return Script; | 282 | return Script; |
283 | } | 283 | } |
284 | 284 | ||
285 | public void SetScript(uint localID, LLUUID itemID, IScript Script) | 285 | public void SetScript(uint localID, LLUUID itemID, IScript Script) |
286 | { | 286 | { |
287 | // Create object if it doesn't exist | 287 | // Create object if it doesn't exist |
288 | if (Scripts.ContainsKey(localID) == false) | 288 | if (Scripts.ContainsKey(localID) == false) |
289 | { | 289 | { |
290 | Scripts.Add(localID, new Dictionary<LLUUID, IScript>()); | 290 | Scripts.Add(localID, new Dictionary<LLUUID, IScript>()); |
291 | } | 291 | } |
292 | 292 | ||
293 | // Delete script if it exists | 293 | // Delete script if it exists |
294 | Dictionary<LLUUID, IScript> Obj; | 294 | Dictionary<LLUUID, IScript> Obj; |
295 | Scripts.TryGetValue(localID, out Obj); | 295 | Scripts.TryGetValue(localID, out Obj); |
296 | if (Obj.ContainsKey(itemID) == true) | 296 | if (Obj.ContainsKey(itemID) == true) |
297 | Obj.Remove(itemID); | 297 | Obj.Remove(itemID); |
298 | 298 | ||
299 | // Add to object | 299 | // Add to object |
300 | Obj.Add(itemID, Script); | 300 | Obj.Add(itemID, Script); |
301 | } | 301 | } |
302 | 302 | ||
303 | public void RemoveScript(uint localID, LLUUID itemID) | 303 | public void RemoveScript(uint localID, LLUUID itemID) |
304 | { | 304 | { |
305 | // Don't have that object? | 305 | // Don't have that object? |
306 | if (Scripts.ContainsKey(localID) == false) | 306 | if (Scripts.ContainsKey(localID) == false) |
307 | return; | 307 | return; |
308 | 308 | ||
309 | // Delete script if it exists | 309 | // Delete script if it exists |
310 | Dictionary<LLUUID, IScript> Obj; | 310 | Dictionary<LLUUID, IScript> Obj; |
311 | Scripts.TryGetValue(localID, out Obj); | 311 | Scripts.TryGetValue(localID, out Obj); |
312 | if (Obj.ContainsKey(itemID) == true) | 312 | if (Obj.ContainsKey(itemID) == true) |
313 | Obj.Remove(itemID); | 313 | Obj.Remove(itemID); |
314 | } | 314 | } |
315 | 315 | ||
316 | #endregion | 316 | #endregion |
317 | 317 | ||
318 | 318 | ||
319 | public void ResetScript(uint localID, LLUUID itemID) | 319 | public void ResetScript(uint localID, LLUUID itemID) |
320 | { | 320 | { |
321 | string script = GetScript(localID, itemID).Source; | 321 | string script = GetScript(localID, itemID).Source; |
322 | StopScript(localID, itemID); | 322 | StopScript(localID, itemID); |
323 | StartScript(localID, itemID, script); | 323 | StartScript(localID, itemID, script); |
324 | } | 324 | } |
325 | 325 | ||
326 | 326 | ||
327 | #region Script serialization/deserialization | 327 | #region Script serialization/deserialization |
328 | 328 | ||
329 | public void GetSerializedScript(uint localID, LLUUID itemID) | 329 | public void GetSerializedScript(uint localID, LLUUID itemID) |
330 | { | 330 | { |
331 | // Serialize the script and return it | 331 | // Serialize the script and return it |
332 | // Should not be a problem | 332 | // Should not be a problem |
333 | FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID); | 333 | FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID); |
334 | BinaryFormatter b = new BinaryFormatter(); | 334 | BinaryFormatter b = new BinaryFormatter(); |
335 | b.Serialize(fs, GetScript(localID, itemID)); | 335 | b.Serialize(fs, GetScript(localID, itemID)); |
336 | fs.Close(); | 336 | fs.Close(); |
337 | } | 337 | } |
338 | 338 | ||
339 | public void PutSerializedScript(uint localID, LLUUID itemID) | 339 | public void PutSerializedScript(uint localID, LLUUID itemID) |
340 | { | 340 | { |
341 | // Deserialize the script and inject it into an AppDomain | 341 | // Deserialize the script and inject it into an AppDomain |
342 | 342 | ||
343 | // How to inject into an AppDomain? | 343 | // How to inject into an AppDomain? |
344 | } | 344 | } |
345 | 345 | ||
346 | #endregion | 346 | #endregion |
347 | } | 347 | } |
348 | } \ No newline at end of file | 348 | } \ No newline at end of file |