aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/YEngine/MMRDelegateCommon.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/YEngine/MMRDelegateCommon.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRDelegateCommon.cs117
1 files changed, 117 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRDelegateCommon.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRDelegateCommon.cs
new file mode 100644
index 0000000..433062a
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRDelegateCommon.cs
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Reflection.Emit;
32
33namespace OpenSim.Region.ScriptEngine.Yengine
34{
35
36 public class DelegateCommon
37 {
38 private string sig; // rettype(arg1type,arg2type,...), eg, "void(list,string,integer)"
39 private Type type; // resultant delegate type
40
41 private static Dictionary<string, DelegateCommon> delegateCommons = new Dictionary<string, DelegateCommon>();
42 private static Dictionary<Type, DelegateCommon> delegateCommonsBySysType = new Dictionary<Type, DelegateCommon>();
43 private static ModuleBuilder delegateModuleBuilder = null;
44 public static Type[] constructorArgTypes = new Type[] { typeof(object), typeof(IntPtr) };
45
46 private DelegateCommon()
47 {
48 }
49
50 public static Type GetType(System.Type ret, System.Type[] args, string sig)
51 {
52 DelegateCommon dc;
53 lock(delegateCommons)
54 {
55 if(!delegateCommons.TryGetValue(sig, out dc))
56 {
57 dc = new DelegateCommon();
58 dc.sig = sig;
59 dc.type = CreateDelegateType(sig, ret, args);
60 delegateCommons.Add(sig, dc);
61 delegateCommonsBySysType.Add(dc.type, dc);
62 }
63 }
64 return dc.type;
65 }
66
67 public static Type TryGetType(string sig)
68 {
69 DelegateCommon dc;
70 lock(delegateCommons)
71 {
72 if(!delegateCommons.TryGetValue(sig, out dc))
73 dc = null;
74 }
75 return (dc == null) ? null : dc.type;
76 }
77
78 public static string TryGetName(Type t)
79 {
80 DelegateCommon dc;
81 lock(delegateCommons)
82 {
83 if(!delegateCommonsBySysType.TryGetValue(t, out dc))
84 dc = null;
85 }
86 return (dc == null) ? null : dc.sig;
87 }
88
89 // http://blog.bittercoder.com/PermaLink,guid,a770377a-b1ad-4590-9145-36381757a52b.aspx
90 private static Type CreateDelegateType(string name, Type retType, Type[] argTypes)
91 {
92 if(delegateModuleBuilder == null)
93 {
94 AssemblyName assembly = new AssemblyName();
95 assembly.Name = "CustomDelegateAssembly";
96 AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assembly, AssemblyBuilderAccess.Run);
97 delegateModuleBuilder = assemblyBuilder.DefineDynamicModule("CustomDelegateModule");
98 }
99
100 TypeBuilder typeBuilder = delegateModuleBuilder.DefineType(name,
101 TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class |
102 TypeAttributes.AnsiClass | TypeAttributes.AutoClass, typeof(MulticastDelegate));
103
104 ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(
105 MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public,
106 CallingConventions.Standard, constructorArgTypes);
107 constructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
108
109 MethodBuilder methodBuilder = typeBuilder.DefineMethod("Invoke",
110 MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot |
111 MethodAttributes.Virtual, retType, argTypes);
112 methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.Runtime);
113
114 return typeBuilder.CreateType();
115 }
116 }
117}