diff options
author | Melanie Thielker | 2008-09-26 15:01:03 +0000 |
---|---|---|
committer | Melanie Thielker | 2008-09-26 15:01:03 +0000 |
commit | 24628928c3bd7148e9df6920ca8b3ed74aaafb49 (patch) | |
tree | 2dca9e3e8d06a727bb7fdbb2be28d3e76d86730a /OpenSim/Region/ScriptEngine/DotNetEngine | |
parent | * refactor: split out AssetXferUploader (diff) | |
download | opensim-SC_OLD-24628928c3bd7148e9df6920ca8b3ed74aaafb49.zip opensim-SC_OLD-24628928c3bd7148e9df6920ca8b3ed74aaafb49.tar.gz opensim-SC_OLD-24628928c3bd7148e9df6920ca8b3ed74aaafb49.tar.bz2 opensim-SC_OLD-24628928c3bd7148e9df6920ca8b3ed74aaafb49.tar.xz |
Add per-instance date to DNE to avoid serializing stuff 10 times a second.
Clode cleanup and removal of commented stuff in ScriptManager.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine')
3 files changed, 166 insertions, 206 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs index 969a05e..e32c342 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs | |||
@@ -188,7 +188,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
188 | } | 188 | } |
189 | } | 189 | } |
190 | 190 | ||
191 | public IScript LoadScript(string FileName) | 191 | public IScript LoadScript(string FileName, out AppDomain ad) |
192 | { | 192 | { |
193 | // Find next available AppDomain to put it in | 193 | // Find next available AppDomain to put it in |
194 | AppDomainStructure FreeAppDomain = GetFreeAppDomain(); | 194 | AppDomainStructure FreeAppDomain = GetFreeAppDomain(); |
@@ -201,6 +201,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
201 | FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); | 201 | FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); |
202 | //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); | 202 | //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); |
203 | FreeAppDomain.ScriptsLoaded++; | 203 | FreeAppDomain.ScriptsLoaded++; |
204 | ad = FreeAppDomain.CurrentAppDomain; | ||
204 | 205 | ||
205 | return mbrt; | 206 | return mbrt; |
206 | } | 207 | } |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs index 7ec71c2..6a3f388 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs | |||
@@ -198,12 +198,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
198 | if (localID == 0) | 198 | if (localID == 0) |
199 | return null; | 199 | return null; |
200 | 200 | ||
201 | IScript Script = m_ScriptManager.GetScript(localID, itemID); | 201 | InstanceData id = m_ScriptManager.GetScript(localID, itemID); |
202 | 202 | ||
203 | if (Script == null) | 203 | if (id == null) |
204 | return null; | 204 | return null; |
205 | 205 | ||
206 | DetectParams[] det = m_ScriptManager.GetDetectParams(Script); | 206 | DetectParams[] det = m_ScriptManager.GetDetectParams(id); |
207 | 207 | ||
208 | if (number < 0 || number >= det.Length) | 208 | if (number < 0 || number >= det.Length) |
209 | return null; | 209 | return null; |
@@ -223,12 +223,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
223 | if (localID == 0) | 223 | if (localID == 0) |
224 | return; | 224 | return; |
225 | 225 | ||
226 | IScript Script = m_ScriptManager.GetScript(localID, itemID); | 226 | InstanceData id = m_ScriptManager.GetScript(localID, itemID); |
227 | 227 | ||
228 | if (Script == null) | 228 | if (id == null) |
229 | return; | 229 | return; |
230 | 230 | ||
231 | string currentState = Script.State; | 231 | string currentState = id.State; |
232 | 232 | ||
233 | if (currentState != state) | 233 | if (currentState != state) |
234 | { | 234 | { |
@@ -239,22 +239,29 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
239 | } | 239 | } |
240 | catch (AppDomainUnloadedException) | 240 | catch (AppDomainUnloadedException) |
241 | { | 241 | { |
242 | Console.WriteLine("[SCRIPT]: state change called when script was unloaded. Nothing to worry about, but noting the occurance"); | 242 | Console.WriteLine("[SCRIPT]: state change called when "+ |
243 | "script was unloaded. Nothing to worry about, "+ | ||
244 | "but noting the occurance"); | ||
243 | } | 245 | } |
244 | 246 | ||
245 | Script.State = state; | 247 | id.State = state; |
246 | 248 | ||
247 | try | 249 | try |
248 | { | 250 | { |
249 | int eventFlags = m_ScriptManager.GetStateEventFlags(localID, itemID); | 251 | int eventFlags = m_ScriptManager.GetStateEventFlags(localID, |
252 | itemID); | ||
253 | |||
250 | SceneObjectPart part = m_Scene.GetSceneObjectPart(itemID); | 254 | SceneObjectPart part = m_Scene.GetSceneObjectPart(itemID); |
251 | if (part != null) | 255 | if (part != null) |
252 | part.SetScriptEvents(itemID, eventFlags); | 256 | part.SetScriptEvents(itemID, eventFlags); |
257 | |||
253 | m_EventManager.state_entry(localID); | 258 | m_EventManager.state_entry(localID); |
254 | } | 259 | } |
255 | catch (AppDomainUnloadedException) | 260 | catch (AppDomainUnloadedException) |
256 | { | 261 | { |
257 | Console.WriteLine("[SCRIPT]: state change called when script was unloaded. Nothing to worry about, but noting the occurance"); | 262 | Console.WriteLine("[SCRIPT]: state change called when "+ |
263 | "script was unloaded. Nothing to worry about, but "+ | ||
264 | "noting the occurance"); | ||
258 | } | 265 | } |
259 | } | 266 | } |
260 | } | 267 | } |
@@ -265,11 +272,11 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
265 | if (localID == 0) | 272 | if (localID == 0) |
266 | return false; | 273 | return false; |
267 | 274 | ||
268 | IScript script = m_ScriptManager.GetScript(localID, itemID); | 275 | InstanceData id = m_ScriptManager.GetScript(localID, itemID); |
269 | if (script == null) | 276 | if (id == null) |
270 | return false; | 277 | return false; |
271 | 278 | ||
272 | return script.Exec.Running?true:false; | 279 | return id.Running; |
273 | } | 280 | } |
274 | 281 | ||
275 | public void SetScriptState(UUID itemID, bool state) | 282 | public void SetScriptState(UUID itemID, bool state) |
@@ -278,11 +285,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
278 | if (localID == 0) | 285 | if (localID == 0) |
279 | return; | 286 | return; |
280 | 287 | ||
281 | IScript script = m_ScriptManager.GetScript(localID, itemID); | 288 | InstanceData id = m_ScriptManager.GetScript(localID, itemID); |
282 | if (script == null) | 289 | if (id == null) |
283 | return; | 290 | return; |
284 | 291 | ||
285 | script.Exec.Running = state; | 292 | if (!id.Disabled) |
293 | id.Running = state; | ||
286 | } | 294 | } |
287 | 295 | ||
288 | public void ApiResetScript(UUID itemID) | 296 | public void ApiResetScript(UUID itemID) |
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs index 12a8fe4..99f61cd 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs | |||
@@ -41,6 +41,17 @@ using System.Threading; | |||
41 | 41 | ||
42 | namespace OpenSim.Region.ScriptEngine.DotNetEngine | 42 | namespace OpenSim.Region.ScriptEngine.DotNetEngine |
43 | { | 43 | { |
44 | public class InstanceData | ||
45 | { | ||
46 | public IScript Script; | ||
47 | public string State; | ||
48 | public bool Running; | ||
49 | public bool Disabled; | ||
50 | public string Source; | ||
51 | public int StartParam; | ||
52 | public AppDomain AppDomain; | ||
53 | } | ||
54 | |||
44 | public class ScriptManager | 55 | public class ScriptManager |
45 | { | 56 | { |
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 57 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -49,13 +60,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
49 | 60 | ||
50 | private Thread scriptLoadUnloadThread; | 61 | private Thread scriptLoadUnloadThread; |
51 | private static Thread staticScriptLoadUnloadThread; | 62 | private static Thread staticScriptLoadUnloadThread; |
52 | // private int scriptLoadUnloadThread_IdleSleepms; | ||
53 | private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); | 63 | private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); |
54 | private static bool PrivateThread; | 64 | private static bool PrivateThread; |
55 | private int LoadUnloadMaxQueueSize; | 65 | private int LoadUnloadMaxQueueSize; |
56 | private Object scriptLock = new Object(); | 66 | private Object scriptLock = new Object(); |
57 | private bool m_started = false; | 67 | private bool m_started = false; |
58 | private Dictionary<IScript, DetectParams[]> detparms = new Dictionary<IScript, DetectParams[]>(); | 68 | private Dictionary<InstanceData, DetectParams[]> detparms = |
69 | new Dictionary<InstanceData, DetectParams[]>(); | ||
59 | 70 | ||
60 | // Load/Unload structure | 71 | // Load/Unload structure |
61 | private struct LUStruct | 72 | private struct LUStruct |
@@ -75,15 +86,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
75 | Unload = 2 | 86 | Unload = 2 |
76 | } | 87 | } |
77 | 88 | ||
78 | // Xantor 20080525: Keep a list of compiled scripts this session for reuse | 89 | public Dictionary<UUID, String> scriptList = |
79 | public Dictionary<UUID, String> scriptList = new Dictionary<UUID, string>(); | 90 | new Dictionary<UUID, string>(); |
80 | 91 | ||
81 | // Object<string, Script<string, script>> | 92 | public Dictionary<uint, Dictionary<UUID, InstanceData>> Scripts = |
82 | // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. | 93 | new Dictionary<uint, Dictionary<UUID, InstanceData>>(); |
83 | // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! | ||
84 | public Dictionary<uint, Dictionary<UUID, IScript>> Scripts = | ||
85 | new Dictionary<uint, Dictionary<UUID, IScript>>(); | ||
86 | 94 | ||
95 | private Compiler.LSL.Compiler LSLCompiler; | ||
87 | 96 | ||
88 | public Scene World | 97 | public Scene World |
89 | { | 98 | { |
@@ -91,7 +100,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
91 | } | 100 | } |
92 | 101 | ||
93 | #endregion | 102 | #endregion |
94 | private Compiler.LSL.Compiler LSLCompiler; | ||
95 | 103 | ||
96 | public void Initialize() | 104 | public void Initialize() |
97 | { | 105 | { |
@@ -99,21 +107,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
99 | LSLCompiler = new Compiler.LSL.Compiler(m_scriptEngine); | 107 | LSLCompiler = new Compiler.LSL.Compiler(m_scriptEngine); |
100 | } | 108 | } |
101 | 109 | ||
102 | // KEEP TRACK OF SCRIPTS <int id, whatever script> | 110 | public void _StartScript(uint localID, UUID itemID, string Script, |
103 | //internal Dictionary<uint, Dictionary<UUID, LSL_BaseClass>> Scripts = new Dictionary<uint, Dictionary<UUID, LSL_BaseClass>>(); | 111 | int startParam, bool postOnRez) |
104 | // LOAD SCRIPT | ||
105 | // UNLOAD SCRIPT | ||
106 | // PROVIDE SCRIPT WITH ITS INTERFACE TO OpenSim | ||
107 | |||
108 | |||
109 | public void _StartScript(uint localID, UUID itemID, string Script, int startParam, bool postOnRez) | ||
110 | { | 112 | { |
111 | m_log.DebugFormat( | 113 | m_log.DebugFormat( |
112 | "[{0}]: ScriptManager StartScript: localID: {1}, itemID: {2}", | 114 | "[{0}]: ScriptManager StartScript: localID: {1}, itemID: {2}", |
113 | m_scriptEngine.ScriptEngineName, localID, itemID); | 115 | m_scriptEngine.ScriptEngineName, localID, itemID); |
114 | 116 | ||
115 | //IScriptHost root = host.GetRoot(); | ||
116 | |||
117 | // We will initialize and start the script. | 117 | // We will initialize and start the script. |
118 | // It will be up to the script itself to hook up the correct events. | 118 | // It will be up to the script itself to hook up the correct events. |
119 | string CompiledScriptFile = String.Empty; | 119 | string CompiledScriptFile = String.Empty; |
@@ -123,13 +123,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
123 | if (null == m_host) | 123 | if (null == m_host) |
124 | { | 124 | { |
125 | m_log.ErrorFormat( | 125 | m_log.ErrorFormat( |
126 | "[{0}]: Could not find scene object part corresponding to localID {1} to start script", | 126 | "[{0}]: Could not find scene object part corresponding "+ |
127 | "to localID {1} to start script", | ||
127 | m_scriptEngine.ScriptEngineName, localID); | 128 | m_scriptEngine.ScriptEngineName, localID); |
128 | 129 | ||
129 | return; | 130 | return; |
130 | } | 131 | } |
131 | 132 | ||
132 | // Xantor 20080525: I need assetID here to see if we already compiled this one previously | ||
133 | UUID assetID = UUID.Zero; | 133 | UUID assetID = UUID.Zero; |
134 | TaskInventoryItem taskInventoryItem = new TaskInventoryItem(); | 134 | TaskInventoryItem taskInventoryItem = new TaskInventoryItem(); |
135 | if (m_host.TaskInventory.TryGetValue(itemID, out taskInventoryItem)) | 135 | if (m_host.TaskInventory.TryGetValue(itemID, out taskInventoryItem)) |
@@ -137,122 +137,135 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
137 | 137 | ||
138 | try | 138 | try |
139 | { | 139 | { |
140 | // Xantor 20080525 see if we already compiled this script this session, stop incessant recompiling on | ||
141 | // scriptreset, spawning of objects with embedded scripts etc. | ||
142 | |||
143 | if (scriptList.TryGetValue(assetID, out CompiledScriptFile)) | 140 | if (scriptList.TryGetValue(assetID, out CompiledScriptFile)) |
144 | { | 141 | { |
145 | m_log.InfoFormat("[SCRIPT]: Found existing compile of assetID {0}: {1}", assetID, CompiledScriptFile); | 142 | m_log.InfoFormat("[SCRIPT]: Found existing compile of "+ |
143 | "assetID {0}: {1}", assetID, CompiledScriptFile); | ||
146 | } | 144 | } |
147 | else | 145 | else |
148 | { | 146 | { |
149 | // Compile (We assume LSL) | 147 | // Compile (We assume LSL) |
150 | CompiledScriptFile = LSLCompiler.PerformScriptCompile(Script); | 148 | CompiledScriptFile = |
149 | LSLCompiler.PerformScriptCompile(Script); | ||
151 | 150 | ||
152 | // Xantor 20080525 Save compiled scriptfile for later use | 151 | m_log.InfoFormat("[SCRIPT]: Compiled assetID {0}: {1}", |
153 | m_log.InfoFormat("[SCRIPT]: Compiled assetID {0}: {1}", assetID, CompiledScriptFile); | 152 | assetID, CompiledScriptFile); |
154 | scriptList.Add(assetID, CompiledScriptFile); | 153 | scriptList.Add(assetID, CompiledScriptFile); |
155 | } | 154 | } |
156 | 155 | ||
157 | //#if DEBUG | 156 | InstanceData id = new InstanceData(); |
158 | //long before; | ||
159 | //before = GC.GetTotalMemory(true); // This force a garbage collect that freezes some windows plateforms | ||
160 | //#endif | ||
161 | 157 | ||
162 | IScript CompiledScript; | 158 | IScript CompiledScript; |
163 | CompiledScript = m_scriptEngine.m_AppDomainManager.LoadScript(CompiledScriptFile); | 159 | CompiledScript = |
164 | 160 | m_scriptEngine.m_AppDomainManager.LoadScript( | |
165 | //#if DEBUG | 161 | CompiledScriptFile, out id.AppDomain); |
166 | //m_scriptEngine.Log.DebugFormat("[" + m_scriptEngine.ScriptEngineName + "]: Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(true) - before); | ||
167 | //#endif | ||
168 | 162 | ||
169 | CompiledScript.Source = Script; | 163 | id.Script = CompiledScript; |
170 | CompiledScript.StartParam = startParam; | 164 | id.Source = Script; |
165 | id.StartParam = startParam; | ||
166 | id.State = "default"; | ||
167 | id.Running = true; | ||
168 | id.Disabled = false; | ||
171 | 169 | ||
172 | // Add it to our script memstruct | 170 | // Add it to our script memstruct |
173 | m_scriptEngine.m_ScriptManager.SetScript(localID, itemID, CompiledScript); | 171 | m_scriptEngine.m_ScriptManager.SetScript(localID, itemID, id); |
174 | |||
175 | // We need to give (untrusted) assembly a private instance of BuiltIns | ||
176 | // this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed. | ||
177 | |||
178 | 172 | ||
179 | // OSSL_BuilIn_Commands LSLB = new OSSL_BuilIn_Commands(m_scriptEngine, m_host, localID, itemID); | ||
180 | LSL_Api LSL = new LSL_Api(); | 173 | LSL_Api LSL = new LSL_Api(); |
181 | OSSL_Api OSSL = new OSSL_Api(); | 174 | OSSL_Api OSSL = new OSSL_Api(); |
182 | 175 | ||
183 | LSL.Initialize(m_scriptEngine, m_host, localID, itemID); | 176 | LSL.Initialize(m_scriptEngine, m_host, localID, itemID); |
184 | OSSL.Initialize(m_scriptEngine, m_host, localID, itemID); | 177 | OSSL.Initialize(m_scriptEngine, m_host, localID, itemID); |
185 | 178 | ||
186 | // Start the script - giving it BuiltIns | 179 | // Start the script - giving it the APIs |
187 | CompiledScript.InitApi("LSL", LSL); | 180 | CompiledScript.InitApi("LSL", LSL); |
188 | CompiledScript.InitApi("OSSL", OSSL); | 181 | CompiledScript.InitApi("OSSL", OSSL); |
189 | 182 | ||
190 | // Fire the first start-event | 183 | // Fire the first start-event |
191 | int eventFlags = m_scriptEngine.m_ScriptManager.GetStateEventFlags(localID, itemID); | 184 | int eventFlags = |
185 | m_scriptEngine.m_ScriptManager.GetStateEventFlags( | ||
186 | localID, itemID); | ||
187 | |||
192 | m_host.SetScriptEvents(itemID, eventFlags); | 188 | m_host.SetScriptEvents(itemID, eventFlags); |
193 | m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", new DetectParams[0], new object[] { }); | 189 | |
190 | m_scriptEngine.m_EventQueueManager.AddToScriptQueue( | ||
191 | localID, itemID, "state_entry", new DetectParams[0], | ||
192 | new object[] { }); | ||
193 | |||
194 | if (postOnRez) | 194 | if (postOnRez) |
195 | { | 195 | { |
196 | m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "on_rez", new DetectParams[0], new object[] { new LSL_Types.LSLInteger(startParam) }); | 196 | m_scriptEngine.m_EventQueueManager.AddToScriptQueue( |
197 | localID, itemID, "on_rez", new DetectParams[0], | ||
198 | new object[] { new LSL_Types.LSLInteger(startParam) }); | ||
197 | } | 199 | } |
198 | } | 200 | } |
199 | catch (Exception e) // LEGIT: User Scripting | 201 | catch (Exception e) // LEGIT: User Scripting |
200 | { | 202 | { |
201 | //m_scriptEngine.Log.Error("[ScriptEngine]: Error compiling script: " + e.ToString()); | ||
202 | try | 203 | try |
203 | { | 204 | { |
204 | // DISPLAY ERROR INWORLD | 205 | // DISPLAY ERROR INWORLD |
205 | string text = "Error compiling script:\r\n" + e.Message.ToString(); | 206 | string text = "Error compiling script:\r\n" + |
206 | if (text.Length > 1500) | 207 | e.Message.ToString(); |
207 | text = text.Substring(0, 1499); // 0-1499 is 1500 characters | 208 | if (text.Length > 1100) |
208 | World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, 2147483647, | 209 | text = text.Substring(0, 1099); |
209 | m_host.AbsolutePosition, m_host.Name, m_host.UUID, false); | 210 | |
211 | World.SimChat(Utils.StringToBytes(text), | ||
212 | ChatTypeEnum.DebugChannel, 2147483647, | ||
213 | m_host.AbsolutePosition, m_host.Name, m_host.UUID, | ||
214 | false); | ||
210 | } | 215 | } |
211 | catch (Exception e2) // LEGIT: User Scripting | 216 | catch (Exception e2) // LEGIT: User Scripting |
212 | { | 217 | { |
213 | m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Error displaying error in-world: " + e2.ToString()); | 218 | m_scriptEngine.Log.Error("[" + |
214 | m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: " + | 219 | m_scriptEngine.ScriptEngineName + |
215 | "Errormessage: Error compiling script:\r\n" + e.Message.ToString()); | 220 | "]: Error displaying error in-world: " + |
221 | e2.ToString()); | ||
222 | m_scriptEngine.Log.Error("[" + | ||
223 | m_scriptEngine.ScriptEngineName + "]: " + | ||
224 | "Errormessage: Error compiling script:\r\n" + | ||
225 | e2.Message.ToString()); | ||
216 | } | 226 | } |
217 | } | 227 | } |
218 | } | 228 | } |
219 | 229 | ||
220 | public void _StopScript(uint localID, UUID itemID) | 230 | public void _StopScript(uint localID, UUID itemID) |
221 | { | 231 | { |
222 | IScript LSLBC = GetScript(localID, itemID); | 232 | InstanceData id = GetScript(localID, itemID); |
223 | if (LSLBC == null) | 233 | if (id == null) |
224 | return; | 234 | return; |
225 | 235 | ||
226 | // Stop long command on script | 236 | // Stop long command on script |
227 | AsyncCommandManager.RemoveScript(m_scriptEngine, localID, itemID); | 237 | AsyncCommandManager.RemoveScript(m_scriptEngine, localID, itemID); |
228 | 238 | ||
229 | // TEMP: First serialize it | ||
230 | //GetSerializedScript(localID, itemID); | ||
231 | |||
232 | try | 239 | try |
233 | { | 240 | { |
234 | // Get AppDomain | 241 | // Get AppDomain |
235 | AppDomain ad = LSLBC.Exec.GetAppDomain(); | ||
236 | // Tell script not to accept new requests | 242 | // Tell script not to accept new requests |
237 | m_scriptEngine.m_ScriptManager.GetScript(localID, itemID).Exec.StopScript(); | 243 | id.Running = false; |
244 | id.Disabled = true; | ||
245 | AppDomain ad = id.AppDomain; | ||
246 | |||
238 | // Remove from internal structure | 247 | // Remove from internal structure |
239 | m_scriptEngine.m_ScriptManager.RemoveScript(localID, itemID); | 248 | RemoveScript(localID, itemID); |
249 | |||
240 | // Tell AppDomain that we have stopped script | 250 | // Tell AppDomain that we have stopped script |
241 | m_scriptEngine.m_AppDomainManager.StopScript(ad); | 251 | m_scriptEngine.m_AppDomainManager.StopScript(ad); |
242 | } | 252 | } |
243 | catch (Exception e) // LEGIT: User Scripting | 253 | catch (Exception e) // LEGIT: User Scripting |
244 | { | 254 | { |
245 | m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Exception stopping script localID: " + localID + " LLUID: " + itemID.ToString() + | 255 | m_scriptEngine.Log.Error("[" + |
246 | ": " + e.ToString()); | 256 | m_scriptEngine.ScriptEngineName + |
257 | "]: Exception stopping script localID: " + | ||
258 | localID + " LLUID: " + itemID.ToString() + | ||
259 | ": " + e.ToString()); | ||
247 | } | 260 | } |
248 | } | 261 | } |
249 | 262 | ||
250 | public void ReadConfig() | 263 | public void ReadConfig() |
251 | { | 264 | { |
252 | // scriptLoadUnloadThread_IdleSleepms = m_scriptEngine.ScriptConfigSource.GetInt("ScriptLoadUnloadLoopms", 30); | ||
253 | // TODO: Requires sharing of all ScriptManagers to single thread | 265 | // TODO: Requires sharing of all ScriptManagers to single thread |
254 | PrivateThread = true; // m_scriptEngine.ScriptConfigSource.GetBoolean("PrivateScriptLoadUnloadThread", false); | 266 | PrivateThread = true; |
255 | LoadUnloadMaxQueueSize = m_scriptEngine.ScriptConfigSource.GetInt("LoadUnloadMaxQueueSize", 100); | 267 | LoadUnloadMaxQueueSize = m_scriptEngine.ScriptConfigSource.GetInt( |
268 | "LoadUnloadMaxQueueSize", 100); | ||
256 | } | 269 | } |
257 | 270 | ||
258 | #region Object init/shutdown | 271 | #region Object init/shutdown |
@@ -263,17 +276,20 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
263 | { | 276 | { |
264 | m_scriptEngine = scriptEngine; | 277 | m_scriptEngine = scriptEngine; |
265 | } | 278 | } |
279 | |||
266 | public void Setup() | 280 | public void Setup() |
267 | { | 281 | { |
268 | ReadConfig(); | 282 | ReadConfig(); |
269 | Initialize(); | 283 | Initialize(); |
270 | } | 284 | } |
285 | |||
271 | public void Start() | 286 | public void Start() |
272 | { | 287 | { |
273 | m_started = true; | 288 | m_started = true; |
274 | 289 | ||
275 | 290 | ||
276 | AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); | 291 | AppDomain.CurrentDomain.AssemblyResolve += |
292 | new ResolveEventHandler(CurrentDomain_AssemblyResolve); | ||
277 | 293 | ||
278 | // | 294 | // |
279 | // CREATE THREAD | 295 | // CREATE THREAD |
@@ -289,43 +305,20 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
289 | // Shared thread - make sure one exist, then assign it to the private | 305 | // Shared thread - make sure one exist, then assign it to the private |
290 | if (staticScriptLoadUnloadThread == null) | 306 | if (staticScriptLoadUnloadThread == null) |
291 | { | 307 | { |
292 | //staticScriptLoadUnloadThread = StartScriptLoadUnloadThread(); | 308 | //staticScriptLoadUnloadThread = |
309 | // StartScriptLoadUnloadThread(); | ||
293 | } | 310 | } |
294 | scriptLoadUnloadThread = staticScriptLoadUnloadThread; | 311 | scriptLoadUnloadThread = staticScriptLoadUnloadThread; |
295 | } | 312 | } |
296 | } | 313 | } |
297 | 314 | ||
298 | // TODO: unused | ||
299 | // private static int privateThreadCount = 0; | ||
300 | // private Thread StartScriptLoadUnloadThread() | ||
301 | // { | ||
302 | // Thread t = new Thread(ScriptLoadUnloadThreadLoop); | ||
303 | // string name = "ScriptLoadUnloadThread:"; | ||
304 | // if (PrivateThread) | ||
305 | // { | ||
306 | // name += "Private:" + privateThreadCount; | ||
307 | // privateThreadCount++; | ||
308 | // } | ||
309 | // else | ||
310 | // { | ||
311 | // name += "Shared"; | ||
312 | // } | ||
313 | // t.Name = name; | ||
314 | // t.IsBackground = true; | ||
315 | // t.Priority = ThreadPriority.Normal; | ||
316 | // t.Start(); | ||
317 | // OpenSim.Framework.ThreadTracker.Add(t); | ||
318 | // return t; | ||
319 | // } | ||
320 | |||
321 | ~ScriptManager() | 315 | ~ScriptManager() |
322 | { | 316 | { |
323 | // Abort load/unload thread | 317 | // Abort load/unload thread |
324 | try | 318 | try |
325 | { | 319 | { |
326 | //PleaseShutdown = true; | 320 | if (scriptLoadUnloadThread != null && |
327 | //Thread.Sleep(100); | 321 | scriptLoadUnloadThread.IsAlive == true) |
328 | if (scriptLoadUnloadThread != null && scriptLoadUnloadThread.IsAlive == true) | ||
329 | { | 322 | { |
330 | scriptLoadUnloadThread.Abort(); | 323 | scriptLoadUnloadThread.Abort(); |
331 | //scriptLoadUnloadThread.Join(); | 324 | //scriptLoadUnloadThread.Join(); |
@@ -340,28 +333,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
340 | 333 | ||
341 | #region Load / Unload scripts (Thread loop) | 334 | #region Load / Unload scripts (Thread loop) |
342 | 335 | ||
343 | // TODO: unused | ||
344 | // private void ScriptLoadUnloadThreadLoop() | ||
345 | // { | ||
346 | // try | ||
347 | // { | ||
348 | // while (true) | ||
349 | // { | ||
350 | // if (LUQueue.Count == 0) | ||
351 | // Thread.Sleep(scriptLoadUnloadThread_IdleSleepms); | ||
352 | // //if (PleaseShutdown) | ||
353 | // // return; | ||
354 | // DoScriptLoadUnload(); | ||
355 | // } | ||
356 | // } | ||
357 | // catch (ThreadAbortException tae) | ||
358 | // { | ||
359 | // string a = tae.ToString(); | ||
360 | // a = String.Empty; | ||
361 | // // Expected | ||
362 | // } | ||
363 | // } | ||
364 | |||
365 | public void DoScriptLoadUnload() | 336 | public void DoScriptLoadUnload() |
366 | { | 337 | { |
367 | if (!m_started) | 338 | if (!m_started) |
@@ -371,7 +342,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine | |||
371 | { | 342 | { |
372 | if (LUQueue.Count > 0) | 343 | if (LUQueue.Count > 0) |
373 | { | 344 | { |
374 | m_scriptEngine.Log.InfoFormat("[{0}]: Loading script", m_scriptEngine.ScriptEngineName); | 345 | m_scriptEngine.Log.InfoFormat("[{0}]: Loading script", |
346 | m_scriptEngine.ScriptEngineName); | ||
375 | LUStruct item = LUQueue.Dequeue(); | 347 | LUStruct item = LUQueue.Dequeue(); |
376 | 348 | ||
377 | if (item.Action == LUType.Unload) | 349 | if (item.Action == LUType.Unload) |
@@ -381,7 +353,8 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Loading script", m_scriptEngine.ScriptEngi | |||
381 | } | 353 | } |
382 | else if (item.Action == LUType.Load) | 354 | else if (item.Action == LUType.Load) |
383 | { | 355 | { |
384 | _StartScript(item.localID, item.itemID, item.script, item.startParam, item.postOnRez); | 356 | _StartScript(item.localID, item.itemID, item.script, |
357 | item.startParam, item.postOnRez); | ||
385 | } | 358 | } |
386 | } | 359 | } |
387 | } | 360 | } |
@@ -391,20 +364,17 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Loading script", m_scriptEngine.ScriptEngi | |||
391 | 364 | ||
392 | #region Helper functions | 365 | #region Helper functions |
393 | 366 | ||
394 | private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) | 367 | private static Assembly CurrentDomain_AssemblyResolve( |
368 | object sender, ResolveEventArgs args) | ||
395 | { | 369 | { |
396 | //Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name); | 370 | return Assembly.GetExecutingAssembly().FullName == args.Name ? |
397 | return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null; | 371 | Assembly.GetExecutingAssembly() : null; |
398 | } | 372 | } |
399 | 373 | ||
400 | #endregion | 374 | #endregion |
401 | 375 | ||
402 | |||
403 | |||
404 | #region Start/Stop/Reset script | 376 | #region Start/Stop/Reset script |
405 | 377 | ||
406 | // private readonly Object startStopLock = new Object(); | ||
407 | |||
408 | /// <summary> | 378 | /// <summary> |
409 | /// Fetches, loads and hooks up a script to an objects events | 379 | /// Fetches, loads and hooks up a script to an objects events |
410 | /// </summary> | 380 | /// </summary> |
@@ -416,7 +386,13 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Loading script", m_scriptEngine.ScriptEngi | |||
416 | { | 386 | { |
417 | if ((LUQueue.Count >= LoadUnloadMaxQueueSize) && m_started) | 387 | if ((LUQueue.Count >= LoadUnloadMaxQueueSize) && m_started) |
418 | { | 388 | { |
419 | m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: ERROR: Load/unload queue item count is at " + LUQueue.Count + ". Config variable \"LoadUnloadMaxQueueSize\" is set to " + LoadUnloadMaxQueueSize + ", so ignoring new script."); | 389 | m_scriptEngine.Log.Error("[" + |
390 | m_scriptEngine.ScriptEngineName + | ||
391 | "]: ERROR: Load/unload queue item count is at " + | ||
392 | LUQueue.Count + | ||
393 | ". Config variable \"LoadUnloadMaxQueueSize\" "+ | ||
394 | "is set to " + LoadUnloadMaxQueueSize + | ||
395 | ", so ignoring new script."); | ||
420 | return; | 396 | return; |
421 | } | 397 | } |
422 | 398 | ||
@@ -428,7 +404,6 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Loading script", m_scriptEngine.ScriptEngi | |||
428 | ls.startParam = startParam; | 404 | ls.startParam = startParam; |
429 | ls.postOnRez = postOnRez; | 405 | ls.postOnRez = postOnRez; |
430 | LUQueue.Enqueue(ls); | 406 | LUQueue.Enqueue(ls); |
431 | m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.ScriptEngineName); | ||
432 | } | 407 | } |
433 | } | 408 | } |
434 | 409 | ||
@@ -451,10 +426,6 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.Sc | |||
451 | } | 426 | } |
452 | } | 427 | } |
453 | 428 | ||
454 | // Create a new instance of the compiler (reuse) | ||
455 | //private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler(); | ||
456 | |||
457 | |||
458 | #endregion | 429 | #endregion |
459 | 430 | ||
460 | #region Perform event execution in script | 431 | #region Perform event execution in script |
@@ -466,33 +437,23 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.Sc | |||
466 | /// <param name="itemID">Script ID</param> | 437 | /// <param name="itemID">Script ID</param> |
467 | /// <param name="FunctionName">Name of function</param> | 438 | /// <param name="FunctionName">Name of function</param> |
468 | /// <param name="args">Arguments to pass to function</param> | 439 | /// <param name="args">Arguments to pass to function</param> |
469 | internal void ExecuteEvent(uint localID, UUID itemID, string FunctionName, DetectParams[] qParams, object[] args) | 440 | internal void ExecuteEvent(uint localID, UUID itemID, |
441 | string FunctionName, DetectParams[] qParams, object[] args) | ||
470 | { | 442 | { |
471 | //cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined | 443 | InstanceData id = GetScript(localID, itemID); |
472 | ///#if DEBUG | 444 | if (id == null) |
473 | /// Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName); | ||
474 | ///#endif | ||
475 | // Execute a function in the script | ||
476 | //m_scriptEngine.Log.Info("[" + ScriptEngineName + "]: Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); | ||
477 | //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID); | ||
478 | IScript Script = GetScript(localID, itemID); | ||
479 | if (Script == null) | ||
480 | { | ||
481 | return; | 445 | return; |
482 | } | 446 | |
483 | //cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined | 447 | detparms[id] = qParams; |
484 | ///#if DEBUG | 448 | if (id.Running) |
485 | /// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); | 449 | id.Script.Exec.ExecuteEvent(id.State, FunctionName, args); |
486 | ///#endif | 450 | detparms.Remove(id); |
487 | // Must be done in correct AppDomain, so leaving it up to the script itself | ||
488 | detparms[Script] = qParams; | ||
489 | Script.Exec.ExecuteEvent(FunctionName, args); | ||
490 | detparms.Remove(Script); | ||
491 | } | 451 | } |
492 | 452 | ||
493 | public uint GetLocalID(UUID itemID) | 453 | public uint GetLocalID(UUID itemID) |
494 | { | 454 | { |
495 | foreach (KeyValuePair<uint, Dictionary<UUID, IScript> > k in Scripts) | 455 | foreach (KeyValuePair<uint, Dictionary<UUID, InstanceData> > k |
456 | in Scripts) | ||
496 | { | 457 | { |
497 | if (k.Value.ContainsKey(itemID)) | 458 | if (k.Value.ContainsKey(itemID)) |
498 | return k.Key; | 459 | return k.Key; |
@@ -502,15 +463,15 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.Sc | |||
502 | 463 | ||
503 | public int GetStateEventFlags(uint localID, UUID itemID) | 464 | public int GetStateEventFlags(uint localID, UUID itemID) |
504 | { | 465 | { |
505 | // Console.WriteLine("GetStateEventFlags for <" + localID + "," + itemID + ">"); | ||
506 | try | 466 | try |
507 | { | 467 | { |
508 | IScript Script = GetScript(localID, itemID); | 468 | InstanceData id = GetScript(localID, itemID); |
509 | if (Script == null) | 469 | if (id == null) |
510 | { | 470 | { |
511 | return 0; | 471 | return 0; |
512 | } | 472 | } |
513 | ExecutorBase.scriptEvents evflags = Script.Exec.GetStateEventFlags(); | 473 | ExecutorBase.scriptEvents evflags = |
474 | id.Script.Exec.GetStateEventFlags(id.State); | ||
514 | return (int)evflags; | 475 | return (int)evflags; |
515 | } | 476 | } |
516 | catch (Exception) | 477 | catch (Exception) |
@@ -530,50 +491,50 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.Sc | |||
530 | if (Scripts.ContainsKey(localID) == false) | 491 | if (Scripts.ContainsKey(localID) == false) |
531 | return new List<UUID>(); | 492 | return new List<UUID>(); |
532 | 493 | ||
533 | Dictionary<UUID, IScript> Obj; | 494 | Dictionary<UUID, InstanceData> Obj; |
534 | Scripts.TryGetValue(localID, out Obj); | 495 | Scripts.TryGetValue(localID, out Obj); |
535 | 496 | ||
536 | return new List<UUID>(Obj.Keys); | 497 | return new List<UUID>(Obj.Keys); |
537 | } | 498 | } |
538 | 499 | ||
539 | public IScript GetScript(uint localID, UUID itemID) | 500 | public InstanceData GetScript(uint localID, UUID itemID) |
540 | { | 501 | { |
541 | lock (scriptLock) | 502 | lock (scriptLock) |
542 | { | 503 | { |
543 | IScript Script = null; | 504 | InstanceData id = null; |
544 | 505 | ||
545 | if (Scripts.ContainsKey(localID) == false) | 506 | if (Scripts.ContainsKey(localID) == false) |
546 | return null; | 507 | return null; |
547 | 508 | ||
548 | Dictionary<UUID, IScript> Obj; | 509 | Dictionary<UUID, InstanceData> Obj; |
549 | Scripts.TryGetValue(localID, out Obj); | 510 | Scripts.TryGetValue(localID, out Obj); |
550 | if (Obj.ContainsKey(itemID) == false) | 511 | if (Obj.ContainsKey(itemID) == false) |
551 | return null; | 512 | return null; |
552 | 513 | ||
553 | // Get script | 514 | // Get script |
554 | Obj.TryGetValue(itemID, out Script); | 515 | Obj.TryGetValue(itemID, out id); |
555 | return Script; | 516 | return id; |
556 | } | 517 | } |
557 | } | 518 | } |
558 | 519 | ||
559 | public void SetScript(uint localID, UUID itemID, IScript Script) | 520 | public void SetScript(uint localID, UUID itemID, InstanceData id) |
560 | { | 521 | { |
561 | lock (scriptLock) | 522 | lock (scriptLock) |
562 | { | 523 | { |
563 | // Create object if it doesn't exist | 524 | // Create object if it doesn't exist |
564 | if (Scripts.ContainsKey(localID) == false) | 525 | if (Scripts.ContainsKey(localID) == false) |
565 | { | 526 | { |
566 | Scripts.Add(localID, new Dictionary<UUID, IScript>()); | 527 | Scripts.Add(localID, new Dictionary<UUID, InstanceData>()); |
567 | } | 528 | } |
568 | 529 | ||
569 | // Delete script if it exists | 530 | // Delete script if it exists |
570 | Dictionary<UUID, IScript> Obj; | 531 | Dictionary<UUID, InstanceData> Obj; |
571 | Scripts.TryGetValue(localID, out Obj); | 532 | Scripts.TryGetValue(localID, out Obj); |
572 | if (Obj.ContainsKey(itemID) == true) | 533 | if (Obj.ContainsKey(itemID) == true) |
573 | Obj.Remove(itemID); | 534 | Obj.Remove(itemID); |
574 | 535 | ||
575 | // Add to object | 536 | // Add to object |
576 | Obj.Add(itemID, Script); | 537 | Obj.Add(itemID, id); |
577 | } | 538 | } |
578 | } | 539 | } |
579 | 540 | ||
@@ -587,7 +548,7 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.Sc | |||
587 | return; | 548 | return; |
588 | 549 | ||
589 | // Delete script if it exists | 550 | // Delete script if it exists |
590 | Dictionary<UUID, IScript> Obj; | 551 | Dictionary<UUID, InstanceData> Obj; |
591 | Scripts.TryGetValue(localID, out Obj); | 552 | Scripts.TryGetValue(localID, out Obj); |
592 | if (Obj.ContainsKey(itemID) == true) | 553 | if (Obj.ContainsKey(itemID) == true) |
593 | Obj.Remove(itemID); | 554 | Obj.Remove(itemID); |
@@ -598,13 +559,13 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.Sc | |||
598 | 559 | ||
599 | public void ResetScript(uint localID, UUID itemID) | 560 | public void ResetScript(uint localID, UUID itemID) |
600 | { | 561 | { |
601 | IScript s = GetScript(localID, itemID); | 562 | InstanceData id = GetScript(localID, itemID); |
602 | string script = s.Source; | 563 | string script = id.Source; |
603 | StopScript(localID, itemID); | 564 | StopScript(localID, itemID); |
604 | SceneObjectPart part = World.GetSceneObjectPart(localID); | 565 | SceneObjectPart part = World.GetSceneObjectPart(localID); |
605 | part.GetInventoryItem(itemID).PermsMask = 0; | 566 | part.GetInventoryItem(itemID).PermsMask = 0; |
606 | part.GetInventoryItem(itemID).PermsGranter = UUID.Zero; | 567 | part.GetInventoryItem(itemID).PermsGranter = UUID.Zero; |
607 | StartScript(localID, itemID, script, s.StartParam, false); | 568 | StartScript(localID, itemID, script, id.StartParam, false); |
608 | } | 569 | } |
609 | 570 | ||
610 | 571 | ||
@@ -629,20 +590,10 @@ m_scriptEngine.Log.InfoFormat("[{0}]: Queued script for load", m_scriptEngine.Sc | |||
629 | 590 | ||
630 | #endregion | 591 | #endregion |
631 | 592 | ||
632 | ///// <summary> | 593 | public DetectParams[] GetDetectParams(InstanceData id) |
633 | ///// If set to true then threads and stuff should try to make a graceful exit | ||
634 | ///// </summary> | ||
635 | //public bool PleaseShutdown | ||
636 | //{ | ||
637 | // get { return _PleaseShutdown; } | ||
638 | // set { _PleaseShutdown = value; } | ||
639 | //} | ||
640 | //private bool _PleaseShutdown = false; | ||
641 | |||
642 | public DetectParams[] GetDetectParams(IScript script) | ||
643 | { | 594 | { |
644 | if (detparms.ContainsKey(script)) | 595 | if (detparms.ContainsKey(id)) |
645 | return detparms[script]; | 596 | return detparms[id]; |
646 | 597 | ||
647 | return null; | 598 | return null; |
648 | } | 599 | } |