static void LoadCustomPortMethods() { BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; foreach (var type in AppDomain.CurrentDomain.GetAllTypes()) { if (type.IsAbstract || type.ContainsGenericParameters) { continue; } if (!(type.IsSubclassOf(typeof(BaseNode)))) { continue; } var methods = type.GetMethods(bindingFlags); foreach (var method in methods) { var portInputAttr = method.GetCustomAttribute <CustomPortInputAttribute>(); var portOutputAttr = method.GetCustomAttribute <CustomPortOutputAttribute>(); if (portInputAttr == null && portOutputAttr == null) { continue; } CustomPortIODelegate deleg; #if ENABLE_IL2CPP // IL2CPP doesn't support expression builders deleg = new CustomPortIODelegate((node, edges) => { method.Invoke(node, new object[] { edges }); }); #else var p1 = Expression.Parameter(typeof(BaseNode), "node"); var p2 = Expression.Parameter(typeof(List <SerializableEdge>), "edges"); var ex = Expression.Call(Expression.Convert(p1, type), method, p2); deleg = Expression.Lambda <CustomPortIODelegate>(ex, p1, p2).Compile(); #endif if (deleg == null) { Debug.LogWarning("Can't use custom IO port function " + method + ": The method have to respect this format: " + typeof(CustomPortIODelegate)); continue; } string fieldName = (portInputAttr == null) ? portOutputAttr.fieldName : portInputAttr.fieldName; Type customType = (portInputAttr == null) ? portOutputAttr.outputType : portInputAttr.inputType; Type fieldType = type.GetField(fieldName, bindingFlags).FieldType; AddCustomIOMethod(type, fieldName, deleg); AddAssignableTypes(customType, fieldType); AddAssignableTypes(fieldType, customType); } } }
public NodePort(BaseNode owner, string fieldName) { this.fieldName = fieldName; this.owner = owner; ourValueField = owner.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); customPortIOMethod = CustomPortIO.GetCustomPortMethod(owner.GetType(), fieldName); }
static void AddCustomIOMethod(Type nodeType, string fieldName, CustomPortIODelegate deleg) { if (!customIOPortMethods.ContainsKey(nodeType)) { customIOPortMethods[nodeType] = new PortIOPerField(); } customIOPortMethods[nodeType][fieldName] = deleg; }
/// <summary> /// Constructor /// </summary> /// <param name="owner">owner node</param> /// <param name="fieldName">the C# property name</param> /// <param name="portData">Data of the port</param> public NodePort(BaseNode owner, string fieldName, PortData portData) { this.fieldName = fieldName; this.owner = owner; this.portData = portData; fieldInfo = owner.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); customPortIOMethod = CustomPortIO.GetCustomPortMethod(owner.GetType(), fieldName); }