From d7cc194e83ade3453649ab897a4f40b0fa856d0d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 26 Mar 2012 00:30:52 +0100 Subject: [PATCH 1/3] Correct the design error I introduced into ScriptComms. Untested but about to be. --- .../Interfaces/IScriptModuleComms.cs | 7 ++-- .../ScriptModuleCommsModule.cs | 36 +++++++++++-------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs index 8bfbbf8c32..8a08fbe8cf 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs @@ -31,7 +31,6 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { public delegate void ScriptCommand(UUID script, string id, string module, string command, string k); - public delegate object ScriptInvocation(UUID script, object[] parms); /// /// Interface for communication between OpenSim modules and in-world scripts @@ -46,10 +45,10 @@ namespace OpenSim.Region.Framework.Interfaces /// event ScriptCommand OnScriptCommand; - void RegisterScriptInvocation(ScriptInvocation fn); - ScriptInvocation[] GetScriptInvocationList(); + void RegisterScriptInvocation(Delegate fn); + Delegate[] GetScriptInvocationList(); - ScriptInvocation LookupScriptInvocation(string fname); + Delegate LookupScriptInvocation(string fname); string LookupModInvocation(string fname); Type[] LookupTypeSignature(string fname); Type LookupReturnType(string fname); diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index 8e8a0b63d8..e37e42e2ab 100644 --- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -47,15 +47,15 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms #region ScriptInvocation protected class ScriptInvocationData { - public ScriptInvocation ScriptInvocationFn { get; private set; } + public Delegate ScriptInvocationDelegate { get; private set; } public string FunctionName { get; private set; } public Type[] TypeSignature { get; private set; } public Type ReturnType { get; private set; } - public ScriptInvocationData(string fname, ScriptInvocation fn, Type[] callsig, Type returnsig) + public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig) { FunctionName = fname; - ScriptInvocationFn = fn; + ScriptInvocationDelegate = fn; TypeSignature = callsig; ReturnType = returnsig; } @@ -126,26 +126,30 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms m_scriptModule.PostScriptEvent(script, "link_message", args); } - public void RegisterScriptInvocation(ScriptInvocation fcall) + public void RegisterScriptInvocation(Delegate fcall) { lock (m_scriptInvocation) { ParameterInfo[] parameters = fcall.Method.GetParameters (); - Type[] parmTypes = new Type[parameters.Length]; - for (int i = 0 ; i < parameters.Length ; i++) - parmTypes[i] = parameters[i].ParameterType; + if (parameters.Length == 0) // Must have one UUID param + return; + + // Hide the first parameter + Type[] parmTypes = new Type[parameters.Length - 1]; + for (int i = 1 ; i < parameters.Length ; i++) + parmTypes[i - 1] = parameters[i].ParameterType; m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType); } } - public ScriptInvocation[] GetScriptInvocationList() + public Delegate[] GetScriptInvocationList() { - List ret = new List(); + List ret = new List(); lock (m_scriptInvocation) { foreach (ScriptInvocationData d in m_scriptInvocation.Values) - ret.Add(d.ScriptInvocationFn); + ret.Add(d.ScriptInvocationDelegate); } return ret.ToArray(); } @@ -177,13 +181,13 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms return null; } - public ScriptInvocation LookupScriptInvocation(string fname) + public Delegate LookupScriptInvocation(string fname) { lock (m_scriptInvocation) { ScriptInvocationData sid; if (m_scriptInvocation.TryGetValue(fname,out sid)) - return sid.ScriptInvocationFn; + return sid.ScriptInvocationDelegate; } return null; @@ -215,8 +219,12 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms public object InvokeOperation(UUID scriptid, string fname, params object[] parms) { - ScriptInvocation fn = LookupScriptInvocation(fname); - return fn(scriptid,parms); + List olist = new List(); + olist.Add(scriptid); + foreach (object o in parms) + olist.Add(o); + Delegate fn = LookupScriptInvocation(fname); + return fn.DynamicInvoke(olist.ToArray()); } #endregion From ac0f1ff0a66e361e7ca24ce4660bf58c5662283c Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 26 Mar 2012 01:21:44 +0100 Subject: [PATCH 2/3] Dynamically create the delegate type to reduce complexity in the caller --- .../Interfaces/IScriptModuleComms.cs | 3 ++- .../ScriptModuleCommsModule.cs | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs index 8a08fbe8cf..34586f5abe 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs @@ -26,6 +26,7 @@ */ using System; +using System.Reflection; using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces @@ -45,7 +46,7 @@ namespace OpenSim.Region.Framework.Interfaces /// event ScriptCommand OnScriptCommand; - void RegisterScriptInvocation(Delegate fn); + void RegisterScriptInvocation(object target, MethodInfo mi); Delegate[] GetScriptInvocationList(); Delegate LookupScriptInvocation(string fname); diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index e37e42e2ab..e0683a08ee 100644 --- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Mono.Addins; using OpenMetaverse; +using System.Linq; +using System.Linq.Expressions; namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms { @@ -126,8 +128,26 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms m_scriptModule.PostScriptEvent(script, "link_message", args); } - public void RegisterScriptInvocation(Delegate fcall) + public void RegisterScriptInvocation(object target, MethodInfo mi) { + Type delegateType; + + var typeArgs = mi.GetParameters() + .Select(p => p.ParameterType) + .ToList(); + + if (mi.ReturnType == typeof(void)) + { + delegateType = Expression.GetActionType(typeArgs.ToArray()); + } + else + { + typeArgs.Add(mi.ReturnType); + delegateType = Expression.GetFuncType(typeArgs.ToArray()); + } + + Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi); + lock (m_scriptInvocation) { ParameterInfo[] parameters = fcall.Method.GetParameters (); From c9c01d52265dde85aa8b8813fb00af8375240ebd Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 26 Mar 2012 03:20:40 +0100 Subject: [PATCH 3/3] Further simplify ScriptComms --- .../Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index e0683a08ee..7fc875919b 100644 --- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -128,8 +128,10 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms m_scriptModule.PostScriptEvent(script, "link_message", args); } - public void RegisterScriptInvocation(object target, MethodInfo mi) + public void RegisterScriptInvocation(object target, string meth) { + MethodInfo mi = target.GetType()..GetMethod(meth, + BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); Type delegateType; var typeArgs = mi.GetParameters()