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
0.7.4-extended
Justin Clark-Casey (justincc) 2013-02-20 22:43:24 +00:00
parent 341dcbede6
commit 78814adf01
2 changed files with 116 additions and 17 deletions

View File

@ -130,20 +130,25 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
m_scriptModule.PostScriptEvent(script, "link_message", args); 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 getMethodFlags =
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); 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) public void RegisterScriptInvocation(object target, string meth)
{ {
MethodInfo mi = GetMethodInfoFromType(target, meth); MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true);
if (mi == null) 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; return;
} }
@ -158,39 +163,72 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
public void RegisterScriptInvocation(object target, MethodInfo mi) 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; Type delegateType;
var typeArgs = mi.GetParameters() List<Type> typeArgs = mi.GetParameters()
.Select(p => p.ParameterType) .Select(p => p.ParameterType)
.ToList(); .ToList();
if (mi.ReturnType == typeof(void)) if (mi.ReturnType == typeof(void))
{ {
delegateType = Expression.GetActionType(typeArgs.ToArray()); delegateType = Expression.GetActionType(typeArgs.ToArray());
} }
else else
{ {
typeArgs.Add(mi.ReturnType); typeArgs.Add(mi.ReturnType);
delegateType = Expression.GetFuncType(typeArgs.ToArray()); 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) lock (m_scriptInvocation)
{ {
ParameterInfo[] parameters = fcall.Method.GetParameters (); ParameterInfo[] parameters = fcall.Method.GetParameters();
if (parameters.Length < 2) // Must have two UUID params if (parameters.Length < 2) // Must have two UUID params
return; return;
// Hide the first two parameters // Hide the first two parameters
Type[] parmTypes = new Type[parameters.Length - 2]; 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; parmTypes[i - 2] = parameters[i].ParameterType;
m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType); 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() public Delegate[] GetScriptInvocationList()
{ {
List<Delegate> ret = new List<Delegate>(); List<Delegate> ret = new List<Delegate>();
@ -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));
}
}
}
/// <summary> /// <summary>
/// Operation to check for a registered constant /// Operation to check for a registered constant
/// </summary> /// </summary>

View File

@ -55,9 +55,9 @@ namespace OpenSim.Region.Framework.Interfaces
void RegisterScriptInvocation(object target, string method); void RegisterScriptInvocation(object target, string method);
/// <summary> /// <summary>
/// Register an instance method as a script call by method info /// Register a static or instance method as a script call by method info
/// </summary> /// </summary>
/// <param name="target"></param> /// <param name="target">If target is a Type object, will assume method is static.</param>
/// <param name="method"></param> /// <param name="method"></param>
void RegisterScriptInvocation(object target, MethodInfo method); void RegisterScriptInvocation(object target, MethodInfo method);
@ -68,6 +68,21 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="methods"></param> /// <param name="methods"></param>
void RegisterScriptInvocation(object target, string[] methods); void RegisterScriptInvocation(object target, string[] methods);
/// <summary>
/// Register one or more static methods as script calls by method name
/// </summary>
/// <param name="target"></param>
/// <param name="methods"></param>
void RegisterScriptInvocation(Type target, string[] methods);
/// <summary>
/// Automatically register script invocations by checking for methods
/// with <see cref="ScriptInvocationAttribute"/>. Should only check
/// public methods.
/// </summary>
/// <param name="target"></param>
void RegisterScriptInvocations(IRegionModuleBase target);
/// <summary> /// <summary>
/// Returns an array of all registered script calls /// Returns an array of all registered script calls
/// </summary> /// </summary>
@ -90,12 +105,44 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="key"></param> /// <param name="key"></param>
void DispatchReply(UUID scriptId, int code, string text, string key); void DispatchReply(UUID scriptId, int code, string text, string key);
/// For constants /// <summary>
/// Operation to for a region module to register a constant to be used
/// by the script engine
/// </summary>
/// <param name="cname">
/// The name of the constant. LSL convention is for constant names to
/// be uppercase.
/// </param>
/// <param name="value">
/// The value of the constant. Should be of a type that can be
/// converted to one of <see cref="OpenSim.Region.ScriptEngine.Shared.LSL_Types"/>
/// </param>
void RegisterConstant(string cname, object value); void RegisterConstant(string cname, object value);
/// <summary>
/// Automatically register all constants on a region module by
/// checking for fields with <see cref="ScriptConstantAttribute"/>.
/// </summary>
/// <param name="target"></param>
void RegisterConstants(IRegionModuleBase target);
/// <summary>
/// Operation to check for a registered constant
/// </summary>
/// <param name="cname">Name of constant</param>
/// <returns>Value of constant or null if none found.</returns>
object LookupModConstant(string cname); object LookupModConstant(string cname);
Dictionary<string, object> GetConstants(); Dictionary<string, object> GetConstants();
// For use ONLY by the script API // For use ONLY by the script API
void RaiseEvent(UUID script, string id, string module, string command, string key); 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
{ }
} }