aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs174
1 files changed, 172 insertions, 2 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index 44c9ada..cab30de 100644
--- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic;
30using Nini.Config; 31using Nini.Config;
31using log4net; 32using log4net;
32using OpenSim.Framework; 33using OpenSim.Framework;
@@ -34,8 +35,10 @@ using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
35using Mono.Addins; 36using Mono.Addins;
36using OpenMetaverse; 37using OpenMetaverse;
38using System.Linq;
39using System.Linq.Expressions;
37 40
38namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms 41namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
39{ 42{
40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
41 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms 44 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
@@ -43,10 +46,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
43 private static readonly ILog m_log = 46 private static readonly ILog m_log =
44 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 48
46 private IScriptModule m_scriptModule = null; 49#region ScriptInvocation
50 protected class ScriptInvocationData
51 {
52 public Delegate ScriptInvocationDelegate { get; private set; }
53 public string FunctionName { get; private set; }
54 public Type[] TypeSignature { get; private set; }
55 public Type ReturnType { get; private set; }
56
57 public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig)
58 {
59 FunctionName = fname;
60 ScriptInvocationDelegate = fn;
61 TypeSignature = callsig;
62 ReturnType = returnsig;
63 }
64 }
65
66 private Dictionary<string,ScriptInvocationData> m_scriptInvocation = new Dictionary<string,ScriptInvocationData>();
67#endregion
47 68
69 private IScriptModule m_scriptModule = null;
48 public event ScriptCommand OnScriptCommand; 70 public event ScriptCommand OnScriptCommand;
49 71
72#region RegionModuleInterface
50 public void Initialise(IConfigSource config) 73 public void Initialise(IConfigSource config)
51 { 74 {
52 } 75 }
@@ -81,6 +104,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
81 public void Close() 104 public void Close()
82 { 105 {
83 } 106 }
107#endregion
108
109#region ScriptModuleComms
84 110
85 public void RaiseEvent(UUID script, string id, string module, string command, string k) 111 public void RaiseEvent(UUID script, string id, string module, string command, string k)
86 { 112 {
@@ -101,5 +127,149 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
101 127
102 m_scriptModule.PostScriptEvent(script, "link_message", args); 128 m_scriptModule.PostScriptEvent(script, "link_message", args);
103 } 129 }
130
131 public void RegisterScriptInvocation(object target, string meth)
132 {
133 MethodInfo mi = target.GetType().GetMethod(meth,
134 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
135 if (mi == null)
136 {
137 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth);
138 return;
139 }
140
141 RegisterScriptInvocation(target, mi);
142 }
143
144 public void RegisterScriptInvocation(object target, string[] meth)
145 {
146 foreach (string m in meth)
147 RegisterScriptInvocation(target, m);
148 }
149
150 public void RegisterScriptInvocation(object target, MethodInfo mi)
151 {
152 m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name);
153
154 Type delegateType;
155 var typeArgs = mi.GetParameters()
156 .Select(p => p.ParameterType)
157 .ToList();
158
159 if (mi.ReturnType == typeof(void))
160 {
161 delegateType = Expression.GetActionType(typeArgs.ToArray());
162 }
163 else
164 {
165 typeArgs.Add(mi.ReturnType);
166 delegateType = Expression.GetFuncType(typeArgs.ToArray());
167 }
168
169 Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi);
170
171 lock (m_scriptInvocation)
172 {
173 ParameterInfo[] parameters = fcall.Method.GetParameters ();
174 if (parameters.Length < 2) // Must have two UUID params
175 return;
176
177 // Hide the first two parameters
178 Type[] parmTypes = new Type[parameters.Length - 2];
179 for (int i = 2 ; i < parameters.Length ; i++)
180 parmTypes[i - 2] = parameters[i].ParameterType;
181 m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
182 }
183 }
184
185 public Delegate[] GetScriptInvocationList()
186 {
187 List<Delegate> ret = new List<Delegate>();
188
189 lock (m_scriptInvocation)
190 {
191 foreach (ScriptInvocationData d in m_scriptInvocation.Values)
192 ret.Add(d.ScriptInvocationDelegate);
193 }
194 return ret.ToArray();
195 }
196
197 public string LookupModInvocation(string fname)
198 {
199 lock (m_scriptInvocation)
200 {
201 ScriptInvocationData sid;
202 if (m_scriptInvocation.TryGetValue(fname,out sid))
203 {
204 if (sid.ReturnType == typeof(string))
205 return "modInvokeS";
206 else if (sid.ReturnType == typeof(int))
207 return "modInvokeI";
208 else if (sid.ReturnType == typeof(float))
209 return "modInvokeF";
210 else if (sid.ReturnType == typeof(UUID))
211 return "modInvokeK";
212 else if (sid.ReturnType == typeof(OpenMetaverse.Vector3))
213 return "modInvokeV";
214 else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion))
215 return "modInvokeR";
216 else if (sid.ReturnType == typeof(object[]))
217 return "modInvokeL";
218
219 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
220 }
221 }
222
223 return null;
224 }
225
226 public Delegate LookupScriptInvocation(string fname)
227 {
228 lock (m_scriptInvocation)
229 {
230 ScriptInvocationData sid;
231 if (m_scriptInvocation.TryGetValue(fname,out sid))
232 return sid.ScriptInvocationDelegate;
233 }
234
235 return null;
236 }
237
238 public Type[] LookupTypeSignature(string fname)
239 {
240 lock (m_scriptInvocation)
241 {
242 ScriptInvocationData sid;
243 if (m_scriptInvocation.TryGetValue(fname,out sid))
244 return sid.TypeSignature;
245 }
246
247 return null;
248 }
249
250 public Type LookupReturnType(string fname)
251 {
252 lock (m_scriptInvocation)
253 {
254 ScriptInvocationData sid;
255 if (m_scriptInvocation.TryGetValue(fname,out sid))
256 return sid.ReturnType;
257 }
258
259 return null;
260 }
261
262 public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms)
263 {
264 List<object> olist = new List<object>();
265 olist.Add(hostid);
266 olist.Add(scriptid);
267 foreach (object o in parms)
268 olist.Add(o);
269 Delegate fn = LookupScriptInvocation(fname);
270 return fn.DynamicInvoke(olist.ToArray());
271 }
272#endregion
273
104 } 274 }
105} 275}