diff --git a/OpenSim/Region/ScriptEngine/Common/Executor.cs b/OpenSim/Region/ScriptEngine/Common/Executor.cs index ca6459b65c..dedf00d70c 100644 --- a/OpenSim/Region/ScriptEngine/Common/Executor.cs +++ b/OpenSim/Region/ScriptEngine/Common/Executor.cs @@ -5,7 +5,7 @@ using System.Reflection; namespace OpenSim.Region.ScriptEngine.Common { - public class Executor: MarshalByRefObject + public class Executor : MarshalByRefObject { /* TODO: * @@ -16,10 +16,12 @@ namespace OpenSim.Region.ScriptEngine.Common */ private IScript m_Script; + private Dictionary Events = new Dictionary(); public Executor(IScript Script) { m_Script = Script; + } public void ExecuteEvent(string FunctionName, object[] args) { @@ -34,23 +36,51 @@ namespace OpenSim.Region.ScriptEngine.Common //} //} - Type type = m_Script.GetType(); - Console.WriteLine("ScriptEngine Executor.ExecuteEvent: \"" + m_Script.State() + "_event_" + FunctionName + "\""); + string EventName = m_Script.State() + "_event_" + FunctionName; + + //type.InvokeMember(EventName, BindingFlags.InvokeMethod, null, m_Script, args); + + Console.WriteLine("ScriptEngine Executor.ExecuteEvent: \"" + EventName + "\""); + + if (Events.ContainsKey(EventName) == false) + { + // Not found, create + Type type = m_Script.GetType(); + try + { + MethodInfo mi = type.GetMethod(EventName); + Events.Add(EventName, mi); + } + catch (Exception e) + { + // Event name not found, cache it as not found + Events.Add(EventName, null); + } + } + + // Get event + MethodInfo ev = null; + Events.TryGetValue(EventName, out ev); + + if (ev == null) // No event by that name! + return; + + // Found try { - type.InvokeMember(m_Script.State() + "_event_" + FunctionName, BindingFlags.InvokeMethod, null, m_Script, args); + // Invoke it + ev.Invoke(m_Script, args); + } catch (Exception e) { // TODO: Send to correct place Console.WriteLine("ScriptEngine Exception attempting to executing script function: " + e.ToString()); } - - } - } + } diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs index 77c859f19e..1218b193c6 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs @@ -14,7 +14,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine { public class AppDomainManager { - private int MaxScriptsPerAppDomain = 1; + private int MaxScriptsPerAppDomain = 3; /// /// Internal list of all AppDomains /// @@ -22,7 +22,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine /// /// Structure to keep track of data around AppDomain /// - private struct AppDomainStructure + private class AppDomainStructure { /// /// The AppDomain itself @@ -57,33 +57,25 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine /// Free AppDomain private AppDomainStructure GetFreeAppDomain() { - FreeAppDomains(); - lock(GetLock) { + FreeAppDomains(); // Outsite lock, has its own GetLock + lock (GetLock) + { // Current full? - if (CurrentAD.ScriptsLoaded >= MaxScriptsPerAppDomain) + if (CurrentAD != null && CurrentAD.ScriptsLoaded >= MaxScriptsPerAppDomain) { // Add it to AppDomains list and empty current AppDomains.Add(CurrentAD); - CurrentAD = new AppDomainStructure(); + CurrentAD = null; } // No current - if (CurrentAD.CurrentAppDomain == null) + if (CurrentAD == null) { // Create a new current AppDomain CurrentAD = new AppDomainStructure(); - CurrentAD.ScriptsWaitingUnload = 0; // to avoid compile warning for not in use - CurrentAD.CurrentAppDomain = PrepareNewAppDomain(); - - + CurrentAD.CurrentAppDomain = PrepareNewAppDomain(); } - // Increase number of scripts loaded into this - // TODO: - // - We assume that every time someone wants an AppDomain they will load into it - // if this assumption is wrong we end up with a miscount and will never unload it. - // - - // Return AppDomain + Console.WriteLine("Scripts loaded in this Appdomain: " + CurrentAD.ScriptsLoaded); return CurrentAD; } // lock } @@ -143,19 +135,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine - public OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass LoadScript(string FileName, IScriptHost host) + public OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass LoadScript(string FileName) { - //LSL_BaseClass mbrt = (LSL_BaseClass)FreeAppDomain.CreateInstanceAndUnwrap(FileName, "SecondLife.Script"); - //Console.WriteLine("Base directory: " + AppDomain.CurrentDomain.BaseDirectory); - // * Find next available AppDomain to put it in + // Find next available AppDomain to put it in AppDomainStructure FreeAppDomain = GetFreeAppDomain(); - + if (FreeAppDomain == null) Console.WriteLine("FreeAppDomain == null"); + if (FreeAppDomain.CurrentAppDomain == null) Console.WriteLine("FreeAppDomain.CurrentAppDomain == null"); LSL_BaseClass mbrt = (LSL_BaseClass)FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); - //LSL_BuiltIn_Commands_Interface mbrt = (LSL_BuiltIn_Commands_Interface)FreeAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); //Type mytype = mbrt.GetType(); - //Console.WriteLine("is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); + Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); + // Increase script count in tihs AppDomain FreeAppDomain.ScriptsLoaded++; //mbrt.Start(); @@ -169,7 +160,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine /// Increase "dead script" counter for an AppDomain /// /// - [Obsolete("Needs fixing!!!")] + [Obsolete("Needs fixing, needs a real purpose in life!!!")] public void StopScript(AppDomain ad) { lock (FreeLock) @@ -188,10 +179,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine if (ads.CurrentAppDomain == ad) { // Found it - messy code to increase structure - AppDomainStructure ads2 = ads; - ads2.ScriptsWaitingUnload++; - AppDomains.Remove(ads); - AppDomains.Add(ads2); + //AppDomainStructure ads2 = ads; + ads.ScriptsWaitingUnload++; + //AppDomains.Remove(ads); + //AppDomains.Add(ads2); return; } } // foreach diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs index 9a65b5c8f3..4879fb2d04 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs @@ -34,6 +34,7 @@ using System.Reflection; using System.Runtime.Remoting; using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes.Scripting; +using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler; using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL; using OpenSim.Region.ScriptEngine.Common; @@ -176,7 +177,16 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine //OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName); //OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName, ObjectID); - OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName, ObjectID); + long before; + before = GC.GetTotalMemory(true); + LSL_BaseClass Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName); + Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before); + before = GC.GetTotalMemory(true); + Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName); + Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before); + before = GC.GetTotalMemory(true); + Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName); + Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before); // Add it to our temporary active script keeper @@ -184,7 +194,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine SetScript(ObjectID, ScriptID, Script); // We need to give (untrusted) assembly a private instance of BuiltIns // this private copy will contain Read-Only FullScriptID so that it can bring that on to the server whenever needed. - OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL_BuiltIn_Commands LSLB = new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL_BuiltIn_Commands(this, ObjectID); + LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(this, ObjectID); // Start the script - giving it BuiltIns Script.Start(LSLB);