From 78814adf0148ec36aa296f174b118c0671e19f54 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 20 Feb 2013 22:43:24 +0000 Subject: [PATCH] Update ScriptModuleComms and interface wholesale from 0.7.5 as of commit 99ebff94 The number of deltas are making this too hard to update through cherry-picking --- .../ScriptModuleCommsModule.cs | 80 +++++++++++++++---- .../Interfaces/IScriptModuleComms.cs | 53 +++++++++++- 2 files changed, 116 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index b297134fad..6bf50d2504 100644 --- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -130,20 +130,25 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms m_scriptModule.PostScriptEvent(script, "link_message", args); } - private static MethodInfo GetMethodInfoFromType(object target, string meth) + private static MethodInfo GetMethodInfoFromType(Type target, string meth, bool searchInstanceMethods) { - MethodInfo mi = target.GetType().GetMethod(meth, - BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + BindingFlags getMethodFlags = + BindingFlags.NonPublic | BindingFlags.Public; - return mi; + if (searchInstanceMethods) + getMethodFlags |= BindingFlags.Instance; + else + getMethodFlags |= BindingFlags.Static; + + return target.GetMethod(meth, getMethodFlags); } public void RegisterScriptInvocation(object target, string meth) { - MethodInfo mi = GetMethodInfoFromType(target, meth); + MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true); if (mi == null) { - m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth); + m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth); return; } @@ -158,38 +163,71 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms public void RegisterScriptInvocation(object target, MethodInfo mi) { - m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name); + m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name); Type delegateType; - var typeArgs = mi.GetParameters() + List typeArgs = mi.GetParameters() .Select(p => p.ParameterType) .ToList(); if (mi.ReturnType == typeof(void)) { - delegateType = Expression.GetActionType(typeArgs.ToArray()); + delegateType = Expression.GetActionType(typeArgs.ToArray()); } else { - typeArgs.Add(mi.ReturnType); - delegateType = Expression.GetFuncType(typeArgs.ToArray()); + typeArgs.Add(mi.ReturnType); + delegateType = Expression.GetFuncType(typeArgs.ToArray()); } - Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi); + Delegate fcall; + if (!(target is Type)) + fcall = Delegate.CreateDelegate(delegateType, target, mi); + else + fcall = Delegate.CreateDelegate(delegateType, (Type)target, mi.Name); lock (m_scriptInvocation) { - ParameterInfo[] parameters = fcall.Method.GetParameters (); + ParameterInfo[] parameters = fcall.Method.GetParameters(); if (parameters.Length < 2) // Must have two UUID params return; // Hide the first two parameters Type[] parmTypes = new Type[parameters.Length - 2]; - for (int i = 2 ; i < parameters.Length ; i++) + for (int i = 2; i < parameters.Length; i++) parmTypes[i - 2] = parameters[i].ParameterType; m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType); } } + + public void RegisterScriptInvocation(Type target, string[] methods) + { + foreach (string method in methods) + { + MethodInfo mi = GetMethodInfoFromType(target, method, false); + if (mi == null) + m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", method); + else + RegisterScriptInvocation(target, mi); + } + } + + public void RegisterScriptInvocations(IRegionModuleBase target) + { + foreach(MethodInfo method in target.GetType().GetMethods( + BindingFlags.Public | BindingFlags.Instance | + BindingFlags.Static)) + { + if(method.GetCustomAttributes( + typeof(ScriptInvocationAttribute), true).Any()) + { + if(method.IsStatic) + RegisterScriptInvocation(target.GetType(), method); + else + RegisterScriptInvocation(target, method); + } + } + } public Delegate[] GetScriptInvocationList() { @@ -292,6 +330,20 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms } } + public void RegisterConstants(IRegionModuleBase target) + { + foreach (FieldInfo field in target.GetType().GetFields( + BindingFlags.Public | BindingFlags.Static | + BindingFlags.Instance)) + { + if (field.GetCustomAttributes( + typeof(ScriptConstantAttribute), true).Any()) + { + RegisterConstant(field.Name, field.GetValue(target)); + } + } + } + /// /// Operation to check for a registered constant /// diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs index d3efa6cd5f..70ff9549e8 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs @@ -55,9 +55,9 @@ namespace OpenSim.Region.Framework.Interfaces void RegisterScriptInvocation(object target, string method); /// - /// Register an instance method as a script call by method info + /// Register a static or instance method as a script call by method info /// - /// + /// If target is a Type object, will assume method is static. /// void RegisterScriptInvocation(object target, MethodInfo method); @@ -68,6 +68,21 @@ namespace OpenSim.Region.Framework.Interfaces /// void RegisterScriptInvocation(object target, string[] methods); + /// + /// Register one or more static methods as script calls by method name + /// + /// + /// + void RegisterScriptInvocation(Type target, string[] methods); + + /// + /// Automatically register script invocations by checking for methods + /// with . Should only check + /// public methods. + /// + /// + void RegisterScriptInvocations(IRegionModuleBase target); + /// /// Returns an array of all registered script calls /// @@ -90,12 +105,44 @@ namespace OpenSim.Region.Framework.Interfaces /// void DispatchReply(UUID scriptId, int code, string text, string key); - /// For constants + /// + /// Operation to for a region module to register a constant to be used + /// by the script engine + /// + /// + /// The name of the constant. LSL convention is for constant names to + /// be uppercase. + /// + /// + /// The value of the constant. Should be of a type that can be + /// converted to one of + /// void RegisterConstant(string cname, object value); + + /// + /// Automatically register all constants on a region module by + /// checking for fields with . + /// + /// + void RegisterConstants(IRegionModuleBase target); + + /// + /// Operation to check for a registered constant + /// + /// Name of constant + /// Value of constant or null if none found. object LookupModConstant(string cname); Dictionary GetConstants(); // For use ONLY by the script API void RaiseEvent(UUID script, string id, string module, string command, string key); } + + [AttributeUsage(AttributeTargets.Method)] + public class ScriptInvocationAttribute : Attribute + { } + + [AttributeUsage(AttributeTargets.Field)] + public class ScriptConstantAttribute : Attribute + { } }