From 325573e4c0328189cf2353b31fc68780224bbc57 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Tue, 2 Nov 2021 12:47:48 +0100 Subject: [PATCH] make treeView subdata fetching working with IEnumerable --- Crow/src/ItemTemplate.cs | 62 ++++++++++++------- Samples/ShowCase/ShowCase.cs | 2 + .../Experimental/testLoadCtxTree.crow | 44 +++++++++++++ 3 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 Samples/common/ui/Interfaces/Experimental/testLoadCtxTree.crow diff --git a/Crow/src/ItemTemplate.cs b/Crow/src/ItemTemplate.cs index c263b656..9c67d57e 100644 --- a/Crow/src/ItemTemplate.cs +++ b/Crow/src/ItemTemplate.cs @@ -226,7 +226,6 @@ namespace Crow il = dm.GetILGenerator (256); System.Reflection.Emit.Label end = il.DefineLabel (); System.Reflection.Emit.Label test = il.DefineLabel (); - //get the dataSource of the arg0 il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Callvirt, CompilerServices.miGetDataSource); @@ -241,15 +240,20 @@ namespace Crow }else emitGetSubData(il, dataType); } - il.Emit (OpCodes.Isinst, typeof(System.Collections.ICollection)); il.Emit (OpCodes.Dup);//duplicate children for testing if it's a collection for childs counting + il.Emit (OpCodes.Isinst, typeof(System.Collections.ICollection)); il.Emit (OpCodes.Brtrue, test);//if true, jump to perform count - il.Emit (OpCodes.Pop);//pop null - il.Emit (OpCodes.Ldc_I4_0);//push false + il.Emit (OpCodes.Isinst, typeof(System.Collections.IEnumerable));//test if enumerable + System.Reflection.Emit.Label pushTrue = il.DefineLabel (); + il.Emit (OpCodes.Brtrue, pushTrue); + il.Emit (OpCodes.Ldc_I4_0);//is not an enumerable, so push false for return + il.Emit (OpCodes.Br, end); + il.MarkLabel (pushTrue); + il.Emit (OpCodes.Ldc_I4_1);//is an enumerable, so push true for return il.Emit (OpCodes.Br, end); il.MarkLabel (test); - + il.Emit (OpCodes.Isinst, typeof(System.Collections.ICollection)); il.Emit (OpCodes.Callvirt, CompilerServices.miGetColCount); il.Emit (OpCodes.Ldc_I4_0); il.Emit (OpCodes.Cgt); @@ -260,31 +264,41 @@ namespace Crow HasSubItems = (BooleanTestOnInstance)dm.CreateDelegate (typeof(BooleanTestOnInstance)); #endregion } + static void emitcallvirtornot (ILGenerator il, MethodInfo mi) { + if (mi.IsStatic) + il.Emit (OpCodes.Call, mi); + else + il.Emit (OpCodes.Callvirt, mi); + } //data is on the stack void emitGetSubData(ILGenerator il, Type dataType){ if (dataType.IsValueType) il.Emit (OpCodes.Unbox_Any, dataType); - MethodInfo miGetDatas = dataType.GetMethod (fetchMethodName, new Type[] {}); - if (miGetDatas == null) - miGetDatas = iface.SearchExtMethod (dataType, fetchMethodName); - - if (miGetDatas == null) {//in last resort, search among properties - PropertyInfo piDatas = dataType.GetProperty (fetchMethodName); - if (piDatas == null) { - FieldInfo fiDatas = dataType.GetField (fetchMethodName); - if (fiDatas == null)//and among fields - throw new Exception ("Fetch data member not found in ItemTemplate: " + fetchMethodName); - il.Emit (OpCodes.Ldfld, fiDatas); - return; - } - miGetDatas = piDatas.GetGetMethod (); - if (miGetDatas == null) + MemberInfo miGetData = dataType.GetMember (fetchMethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .FirstOrDefault(mmi => (mmi is MethodInfo mmmi && mmmi.GetParameters().Length == 0) || mmi.MemberType != MemberTypes.Method); + + if (miGetData == null) { + MethodInfo extMethd = iface.SearchExtMethod (dataType, fetchMethodName); + if (extMethd == null) + throw new Exception ("Fetch data member not found in ItemTemplate: " + fetchMethodName); + emitcallvirtornot (il, extMethd); + return; + } + if (miGetData is MethodInfo mi) { + emitcallvirtornot (il, mi); + return; + } + if (miGetData is PropertyInfo pi) { + if (!pi.CanRead) throw new Exception ("Write only property for fetching data in ItemTemplate: " + fetchMethodName); + emitcallvirtornot (il, pi.GetGetMethod ()); + //il.Emit (OpCodes.Call, pi.GetGetMethod ()); + return; + } + if (miGetData is FieldInfo fi) { + il.Emit (OpCodes.Ldfld, fi); + return; } - if (miGetDatas.IsStatic) - il.Emit (OpCodes.Call, miGetDatas); - else - il.Emit (OpCodes.Callvirt, miGetDatas); } } diff --git a/Samples/ShowCase/ShowCase.cs b/Samples/ShowCase/ShowCase.cs index 7b25d718..49663438 100644 --- a/Samples/ShowCase/ShowCase.cs +++ b/Samples/ShowCase/ShowCase.cs @@ -188,5 +188,7 @@ namespace ShowCase NotifyValueChanged (Crow.Interface.POLLING_INTERVAL); } } + public IEnumerable AllLoadContexts => + System.Runtime.Loader.AssemblyLoadContext.All; } } \ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Experimental/testLoadCtxTree.crow b/Samples/common/ui/Interfaces/Experimental/testLoadCtxTree.crow new file mode 100644 index 00000000..3a1dd0ef --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/testLoadCtxTree.crow @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + \ No newline at end of file -- 2.47.3