aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/CompilerServices
diff options
context:
space:
mode:
authorjpbruyere <jp.bruyere@hotmail.com>2015-05-18 18:13:48 +0200
committerjpbruyere <jp.bruyere@hotmail.com>2015-05-18 18:13:48 +0200
commitfd19c1fd6960faf9b7131a4dfade4bba95abcf81 (patch)
tree59653a3db212e877aa125884e85e11333bc474cd /src/CompilerServices
parent2a48f25993b48535eb84f0e83e4dd7c064ed6e49 (diff)
Simple bindings
demonstration in testFps
Diffstat (limited to 'src/CompilerServices')
-rw-r--r--src/CompilerServices/CompilerServices.cs112
1 files changed, 107 insertions, 5 deletions
diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs
index 034180d1..36c88030 100644
--- a/src/CompilerServices/CompilerServices.cs
+++ b/src/CompilerServices/CompilerServices.cs
@@ -1,6 +1,10 @@
using System;
using System.Reflection.Emit;
using System.Reflection;
+using System.Collections;
+using System.Diagnostics;
+using System.Linq;
+
namespace go
{
@@ -33,12 +37,12 @@ namespace go
}
static int dynHandleCpt = 0;
- public static void CompileEventSource(EventSource es)
+ public static void CompileEventSource(DynAttribute es)
{
Type srcType = es.Source.GetType ();
#region Retrieve EventHandler parameter type
- EventInfo ei = srcType.GetEvent (es.EventName);
+ EventInfo ei = srcType.GetEvent (es.MemberName);
MethodInfo invoke = ei.EventHandlerType.GetMethod ("Invoke");
ParameterInfo[] pars = invoke.GetParameters ();
@@ -54,10 +58,10 @@ namespace go
#region IL generation
ILGenerator il = dm.GetILGenerator(256);
- string src = es.Handler.Trim();
+ string src = es.Value.Trim();
if (! (src.StartsWith("{") || src.EndsWith ("}")))
- throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", es.EventName, es.Handler));
+ throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", es.MemberName, es.Value));
src = src.Substring (1, src.Length - 2);
string[] srcLines = src.Split (new char[] { ';' });
@@ -145,11 +149,109 @@ namespace go
#endregion
- FieldInfo evtFi = getEventHandlerField (srcType, es.EventName);
+ FieldInfo evtFi = getEventHandlerField (srcType, es.MemberName);
Delegate del = dm.CreateDelegate(evtFi.FieldType);
evtFi.SetValue(es.Source, del);
}
+ public static void CreateBinding(DynAttribute binding, object _source)
+ {
+
+ Type srcType = _source.GetType ();
+ Type dstType = binding.Source.GetType ();
+
+ MemberInfo miSrc = srcType.GetMember (binding.Value).FirstOrDefault();
+ Type srcValueType = null;
+ if (miSrc.MemberType == MemberTypes.Property)
+ srcValueType = (miSrc as PropertyInfo).PropertyType;
+ else if (miSrc.MemberType == MemberTypes.Field)
+ srcValueType = (miSrc as FieldInfo).FieldType;
+ else
+ throw new Exception("unandled source type for binding");
+
+ #region Retrieve EventHandler parameter type
+ EventInfo ei = srcType.GetEvent ("ValueChanged");
+ MethodInfo evtInvoke = ei.EventHandlerType.GetMethod ("Invoke");
+ ParameterInfo[] evtParams = evtInvoke.GetParameters ();
+
+ Type handlerArgsType = evtParams [1].ParameterType;
+ #endregion
+
+ Type[] args = {typeof(object), handlerArgsType};
+ DynamicMethod dm = new DynamicMethod("dynHandle_" + dynHandleCpt,
+ typeof(void),
+ args,
+ srcType.Module, true);
+
+ //register target object reference
+ int dstIdx = Interface.References.IndexOf(binding.Source);
+
+ if (dstIdx < 0) {
+ dstIdx = Interface.References.Count;
+ Interface.References.Add (binding.Source);
+ }
+
+
+
+ #region IL generation
+ ILGenerator il = dm.GetILGenerator(256);
+
+ System.Reflection.Emit.Label labFailed = il.DefineLabel();
+ System.Reflection.Emit.Label labContinue = il.DefineLabel();
+
+ #region test if valueChange event is the correct one
+ il.Emit (OpCodes.Ldstr, binding.Value);
+ //push name from arg
+ il.Emit(OpCodes.Ldarg_1);
+ FieldInfo fiMbName = typeof(ValueChangeEventArgs).GetField("MemberName");
+ il.Emit(OpCodes.Ldfld, fiMbName);
+ MethodInfo miStrEqu = typeof(string).GetMethod("op_Inequality", new Type[] {typeof(string),typeof(string)});
+ il.Emit(OpCodes.Call, miStrEqu);
+ il.Emit(OpCodes.Brfalse_S, labContinue);
+ il.Emit(OpCodes.Br_S, labFailed);
+ il.MarkLabel(labContinue);
+ #endregion
+
+ string[] srcLines = binding.Value.Trim().Split (new char[] { ';' });
+ foreach (string srcLine in srcLines) {
+ MethodInfo infoWriteLine = typeof(System.Diagnostics.Debug).GetMethod("WriteLine", new Type[] { typeof(string) });
+
+ string statement = srcLine.Trim ();
+
+ //load target ref onto the stack
+ FieldInfo fiRefs = typeof(Interface).GetField("References");
+ il.Emit(OpCodes.Ldsfld, fiRefs);
+ il.Emit(OpCodes.Ldc_I4, dstIdx);
+
+ MethodInfo miGetRef = Interface.References.GetType().GetMethod("get_Item");
+ il.Emit(OpCodes.Callvirt, miGetRef);
+ il.Emit(OpCodes.Isinst, dstType);
+
+ //push new value
+ il.Emit(OpCodes.Ldarg_1);
+ FieldInfo fiNewValue = typeof(ValueChangeEventArgs).GetField("NewValue");
+ il.Emit(OpCodes.Ldfld, fiNewValue);
+
+ PropertyInfo piTarget = dstType.GetProperty(binding.MemberName);
+ MethodInfo miToStr = typeof(object).GetMethod("ToString",Type.EmptyTypes);
+
+ if (!srcValueType.IsValueType)
+ il.Emit(OpCodes.Castclass, srcValueType);
+ il.Emit(OpCodes.Callvirt, miToStr);
+ il.Emit(OpCodes.Callvirt, piTarget.GetSetMethod());
+ }
+ il.MarkLabel(labFailed);
+ il.Emit(OpCodes.Ret);
+
+ #endregion
+
+ Delegate del = dm.CreateDelegate(ei.EventHandlerType);
+ MethodInfo addHandler = ei.GetAddMethod ();
+ //Delegate del = dm.CreateDelegate(typeof(System.EventHandler));
+ addHandler.Invoke(_source, new object[] {del});
+ }
+
+
public static FieldInfo getEventHandlerField(Type type, string eventName)
{
FieldInfo fi;