public static void RefactorFunction(uNodeFunction function, string name) { name = uNodeUtility.AutoCorrectName(name); var graph = function.owner; var action = GetUpdateReferencesAction(function); function.Name = name; action?.Invoke(); }
public FunctionView(uNodeFunction function, ExplorerFunctionData data = null) { if (data == null) { data = new ExplorerFunctionData(); } data.guid = uNodeUtility.GetObjectID(function).ToString(); expanded = data.expanded; this.data = data; this.function = function; title = $"{function.Name}({ string.Join(", ", function.Parameters.Select(p => p.type.DisplayName(false, false))) }) : {function.returnType.DisplayName(false, false)}"; titleIcon.image = uNodeEditorUtility.GetTypeIcon(typeof(TypeIcons.MethodIcon)); expanded = data.expanded; expandedElement.visible = false; titleContainer.RegisterCallback <MouseDownEvent>(evt => { if (evt.clickCount >= 2 && evt.button == 0) { uNodeEditor.ChangeTarget(function, true); uNodeEditor.window.Refresh(); } }); onExpandClicked += () => { if (!isInSearch) { data.expanded = expanded; Save(); } }; if (ExplorerManager.explorerData.showSummary) { if (!string.IsNullOrWhiteSpace(function.summary)) { var summary = new SummaryView(function.summary); headerContainer.Add(summary); } } if (ExplorerManager.explorerData.showTypeIcon) { typeIcon = new Image() { name = "type-icon", image = uNodeEditorUtility.GetIcon(function.returnType), }; titleContainer.Add(typeIcon); typeIcon.PlaceInFront(titleIcon); } }
private static bool CallbackRefactorFunction(object obj, uNodeFunction func, string name, Type[] paramTypes) { if (obj is MemberData) { MemberData member = obj as MemberData; if (member.instance as UnityEngine.Object == func.owner && member.targetType == MemberData.TargetType.uNodeFunction) { int pLength = member.ParameterTypes[0] == null ? 0 : member.ParameterTypes[0].Length; if (member.startName.Equals(name) && pLength == paramTypes.Length) { bool isValid = true; if (pLength != 0) { for (int x = 0; x < paramTypes.Length; x++) { if (paramTypes[x] != member.ParameterTypes[0][x]) { isValid = false; break; } } } if (isValid) { if (!member.isDeepTarget) { MemberData.CreateFromValue(func).CopyTo(member); } else { var mVal = MemberData.CreateFromValue(func); var items = member.Items; items[0] = mVal.Items[0]; member.SetItems(items); member.startName = func.Name; } return(true); } } } } return(false); }
/// <summary> /// Return true on flow body can be simplify to lambda expression code. /// </summary> /// <param name="target"></param> /// <param name="returnType"></param> /// <param name="parameterTypes"></param> /// <returns></returns> public static bool CanSimplifyToLambda(MemberData target, Type returnType, IList <Type> parameterTypes) { if (target.IsTargetingNode) { var bodyNode = target.GetTargetNode(); if (bodyNode is MultipurposeNode) { var node = bodyNode as MultipurposeNode; if (node.target.target.isAssigned && !node.onFinished.isAssigned) { System.Type[] memberTypes = null; if (node.target.target.targetType == MemberData.TargetType.Method) { var members = node.target.target.GetMembers(false); if (members != null && members.Length > 0) { var lastMember = members.LastOrDefault() as System.Reflection.MethodInfo; if (lastMember != null && lastMember.ReturnType == returnType) { memberTypes = lastMember.GetParameters().Select(i => i.ParameterType).ToArray(); } } } else if (node.target.target.targetType == MemberData.TargetType.uNodeFunction) { uNodeFunction func = node.target.target.GetUnityObject() as uNodeFunction; if (func != null && func.ReturnType() == returnType) { memberTypes = func.parameters.Select(i => i.Type).ToArray(); } } if (memberTypes != null) { if (parameterTypes.Count == memberTypes.Length && node.target.parameters.Length == memberTypes.Length) { bool flag = true; for (int x = 0; x < parameterTypes.Count; x++) { if (parameterTypes[x] != memberTypes[x]) { flag = false; break; } } if (flag) { for (int x = 0; x < parameterTypes.Count; x++) { var p = node.target.parameters[x]; if (p.targetType != MemberData.TargetType.NodeFieldElement || p.GetAccessIndex() != x) { flag = false; break; } } if (flag) { return(true); } } } } } } } return(false); }
protected override void InitializeView() { base.InitializeView(); // titleIcon.image = null; NodeReturn node = targetNode as NodeReturn; if (!node.returnAnyType) { var parent = node.parentComponent; if (parent != null && parent is uNodeProperty) { uNodeProperty m = parent as uNodeProperty; if (m.CanGetValue() && m.ReturnType() != typeof(void)) { AddInputValuePort( new PortData() { portID = "return", onValueChanged = (o) => { RegisterUndo(); node.returnValue = o as MemberData; }, getPortName = () => "", getPortType = () => m.ReturnType(), getPortValue = () => node.returnValue, } ); } } else if (node.rootObject != null && node.rootObject is uNodeFunction) { uNodeFunction m = node.rootObject as uNodeFunction; if (m.ReturnType() != typeof(void)) { AddInputValuePort( new PortData() { portID = "return", onValueChanged = (o) => { RegisterUndo(); node.returnValue = o as MemberData; }, getPortName = () => "", getPortType = () => m.ReturnType(), getPortValue = () => node.returnValue, } ); } } } else { AddInputValuePort( new PortData() { portID = "return", onValueChanged = (o) => { RegisterUndo(); node.returnValue = o as MemberData; }, getPortName = () => "", getPortType = () => typeof(object), getPortValue = () => node.returnValue, } ); } if (uNodeUtility.preferredDisplay != DisplayKind.Full) { ConstructCompactTitle("return"); } }
public HierarchyFunctionTree(uNodeFunction function, int depth) : base(function.GetHashCode(), depth, $"{function.Name}({ string.Join(", ", function.Parameters.Select(p => p.type.DisplayName(false, false))) }) : {function.returnType.DisplayName(false, false)}") { this.function = function; icon = uNodeEditorUtility.GetTypeIcon(function.returnType) as Texture2D; }
private static void RefactorFunction(uNodeFunction function, string name, Type returnType, Type[] paramTypes) { var graph = function.owner; Undo.SetCurrentGroupName("Refactor Function: " + function.Name); HashSet <GameObject> referencedGraphs = new HashSet <GameObject>(); if (graph != null) { RuntimeMethod runtime = null; if (graph is IIndependentGraph) { if (GraphUtility.IsTempGraphObject(graph.gameObject)) { var prefab = uNodeEditorUtility.GetGameObjectSource(graph.gameObject, null); if (prefab != null) { var oriGraph = prefab.GetComponent <uNodeRoot>(); if (oriGraph != null) { var methods = ReflectionUtils.GetRuntimeType(oriGraph).GetMethods(); foreach (var m in methods) { if (m is RuntimeMethod && m.Name == name) { var parameters = m.GetParameters(); if (parameters.Length == paramTypes.Length) { if (runtime == null) { runtime = m as RuntimeMethod; } bool isValid = true; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType != paramTypes[i]) { isValid = false; break; } } if (isValid) { runtime = m as RuntimeMethod; } } } } } } } else { var methods = ReflectionUtils.GetRuntimeType(graph).GetMethods(); foreach (var m in methods) { if (m is RuntimeGraphMethod runtimeMethod && runtimeMethod.target == function) { runtime = runtimeMethod; break; } } } } MemberInfo nativeMember = null; if (graph.GeneratedTypeName.ToType(false) != null) { var type = graph.GeneratedTypeName.ToType(false); if (paramTypes.Length == 0 && function.GenericParameters.Count == 0) { nativeMember = type.GetMethod(name, MemberData.flags); } var members = type.GetMember(name, MemberData.flags); if (members != null) { var genericLength = function.GenericParameters.Count; foreach (var m in members) { if (m is MethodInfo method) { var mParam = method.GetParameters(); var mGeneric = method.GetGenericArguments(); if (paramTypes.Length == mParam.Length && mGeneric.Length == genericLength) { bool valid = true; for (int i = 0; i < mParam.Length; i++) { if (mParam[i].ParameterType != paramTypes[i]) { valid = false; break; } } if (valid) { nativeMember = method; break; } } } } } } var graphPrefabs = uNodeEditorUtility.FindPrefabsOfType <uNodeRoot>(); foreach (var prefab in graphPrefabs) { var gameObject = prefab; GameObject prefabContent = null; if (GraphUtility.HasTempGraphObject(prefab)) { gameObject = GraphUtility.GetTempGraphObject(prefab); } else if (uNodeEditorUtility.IsPrefab(prefab)) { prefabContent = PrefabUtility.LoadPrefabContents(AssetDatabase.GetAssetPath(prefab)); gameObject = prefabContent; } var scripts = gameObject.GetComponentsInChildren <MonoBehaviour>(true); bool hasUndo = false; Func <object, bool> scriptValidation = (obj) => { MemberData member = obj as MemberData; if (member != null && member.startType is RuntimeType) { var members = member.GetMembers(false); if (members != null) { for (int i = 0; i < members.Length; i++) { var m = members[i]; if (member.namePath.Length > i + 1) { if (m == runtime || m == nativeMember) { if (!hasUndo && prefabContent == null) { uNodeEditorUtility.RegisterFullHierarchyUndo(gameObject); hasUndo = true; } var path = member.namePath; path[i + 1] = function.Name; member.name = string.Join(".", path); { var items = member.Items; if (items.Length > i) { var mVal = MemberData.CreateFromMember(runtime); items[i] = mVal.Items[0]; member.SetItems(items); } } if (m == nativeMember) { referencedGraphs.Add(prefab); } return(true); } } } } } return(false); }; if (runtime != null) { bool hasChanged = false; Array.ForEach(scripts, script => { bool flag = AnalizerUtility.AnalizeObject(script, scriptValidation); if (flag) { hasChanged = true; hasUndo = false; uNodeGUIUtility.GUIChanged(script); uNodeEditorUtility.MarkDirty(script); } }); if (hasChanged) { if (gameObject != prefab) { uNodeEditorUtility.RegisterFullHierarchyUndo(prefab); if (prefabContent == null) { //Save the temporary graph GraphUtility.AutoSaveGraph(gameObject); } else { //Save the prefab contents and unload it uNodeEditorUtility.SavePrefabAsset(gameObject, prefab); } } uNodeEditorUtility.MarkDirty(prefab); } } if (prefabContent != null) { PrefabUtility.UnloadPrefabContents(prefabContent); } } } uNodeEditorUtility.RegisterFullHierarchyUndo(graph.gameObject); graph.Refresh(); Func <object, bool> validation = delegate(object OBJ) { return(CallbackRefactorFunction(OBJ, function, name, paramTypes)); }; Array.ForEach(graph.nodes, item => AnalizerUtility.AnalizeObject(item, validation)); if (GraphUtility.IsTempGraphObject(graph.gameObject)) { var prefab = uNodeEditorUtility.GetGameObjectSource(graph.gameObject, null); uNodeEditorUtility.RegisterFullHierarchyUndo(prefab); GraphUtility.AutoSaveGraph(graph.gameObject); } uNodeEditor.ClearGraphCache(); uNodeEditor.window?.Refresh(true); DoCompileReferences(graph, referencedGraphs); }
void InitMultipurposeMember(FieldInfo field) { MultipurposeMember member = field.GetValueOptimized(data.block) as MultipurposeMember; object[] fieldAttribute = field.GetCustomAttributes(true); if (!ReflectionUtils.TryCorrectingAttribute(data.block, ref fieldAttribute)) { return; } if (member == null) { member = new MultipurposeMember(); field.SetValueOptimized(data.block, member); Repaint(); } if (member.target == null || member.target.isTargeted && member.target.IsTargetingPinOrNode) { var filter = ReflectionUtils.GetAttribute <FilterAttribute>(fieldAttribute) ?? new FilterAttribute() { MaxMethodParam = int.MaxValue, }; var port = AddPort(new PortData() { getPortName = () => field.Name, getPortType = () => typeof(MemberData), getPortValue = () => member.target, filter = filter, onValueChanged = (obj) => { var val = obj as MemberData; RegisterUndo(); if (member.target.targetType != val.targetType || val.targetType != MemberData.TargetType.Values) { member.target = val; owner.nodeView.MarkRepaint(); MemberDataUtility.UpdateMultipurposeMember(member); } else { member.target = val; } field.SetValueOptimized(data.block, member); Repaint(); }, }); var control = port.portData.InstantiateControl(true); control.HideInstance(true); port.Add(new ControlView(control, true)); //ControlConfig config = new ControlConfig() { // owner = owner, // value = member.target, // type = typeof(MemberData), // filter = filter, // onValueChanged = (obj) => { // var val = obj as MemberData; // RegisterUndo(); // if(member.target.targetType != val.targetType || val.targetType != MemberData.TargetType.Values) { // member.target = val; // owner.MarkRepaint(); // uNodeEditorUtility.UpdateMultipurposeMember(member); // } else { // member.target = val; // } // field.SetValue(data.actionEvent, member); // Repaint(); // }, //}; //MemberControl control = new MemberControl(config, true); //AddControl(field.Name, new ControlView(control, true)); } if (member.target.isTargeted) { if (member.target.targetType != MemberData.TargetType.Values) { if (!member.target.isStatic && (!member.target.IsTargetingUNode || !uNodePreference.GetPreference().hideUNodeInstance) && member.target.targetType != MemberData.TargetType.Type && member.target.targetType != MemberData.TargetType.Null) { MemberDataUtility.UpdateMemberInstance(member.target, member.target.startType); var port = AddPort(new PortData() { portID = "Instance", getPortName = () => "Instance", getPortType = () => member.target.startType, getPortValue = () => member.target?.instance, filter = new FilterAttribute(member.target.startType), onValueChanged = (o) => { RegisterUndo(); member.target.instance = o; field.SetValueOptimized(data.block, member); }, }); port.Add(new ControlView(port.portData.InstantiateControl(true), true)); } else if (!uNodePreference.GetPreference().hideUNodeInstance&& member.target.IsTargetingUNode && !member.target.IsTargetingNode) { MemberDataUtility.UpdateMemberInstance(member.target, member.target.startType); var port = AddPort(new PortData() { portID = "Instance", getPortName = () => "", getPortType = () => typeof(uNodeRoot), getPortValue = () => member.target?.instance, filter = new FilterAttribute(typeof(uNodeRoot)), onValueChanged = (o) => { RegisterUndo(); member.target.instance = o; field.SetValueOptimized(data.block, member); }, }); port.Add(new ControlView(port.portData.InstantiateControl(true), true)); } } if (member.target.SerializedItems?.Length > 0) { MemberInfo[] members = null; if (uNodePreference.GetPreference().inEditorDocumentation) { members = member.target.GetMembers(false); if (members != null && members.Length > 0 && members.Length + 1 != member.target.SerializedItems.Length) { members = null; } } uNodeFunction objRef = null; switch (member.target.targetType) { case MemberData.TargetType.uNodeFunction: { uNodeRoot root = member.target.GetInstance() as uNodeRoot; if (root != null) { var gTypes = member.target.GenericTypes[0]; objRef = root.GetFunction(member.target.startName, gTypes != null ? gTypes.Length : 0, member.target.ParameterTypes[0]); } break; } } int totalParam = 0; bool flag = false; for (int i = 0; i < member.target.SerializedItems.Length; i++) { if (i != 0) { if (members != null && (member.target.isDeepTarget || !member.target.IsTargetingUNode)) { MemberInfo mData = members[i - 1]; if (mData is MethodInfo || mData is ConstructorInfo) { var method = mData as MethodInfo; var parameters = method != null?method.GetParameters() : (mData as ConstructorInfo).GetParameters(); if (parameters.Length > 0) { totalParam++; if (totalParam > 1) { flag = true; break; } } } } } } totalParam = 0; int methodDrawCount = 1; for (int i = 0; i < member.target.SerializedItems.Length; i++) { if (i != 0) { if (members != null && (member.target.isDeepTarget || !member.target.IsTargetingUNode)) { MemberInfo memberInfo = members[i - 1]; if (memberInfo is MethodInfo || memberInfo is ConstructorInfo) { var method = memberInfo as MethodInfo; var documentation = XmlDoc.XMLFromMember(memberInfo); if (flag) { AddControl(memberInfo.Name, null); } var parameters = method != null?method.GetParameters() : (memberInfo as ConstructorInfo).GetParameters(); if (parameters.Length > 0) { while (parameters.Length + totalParam > member.parameters.Length) { ArrayUtility.Add(ref member.parameters, MemberData.empty); } for (int x = 0; x < parameters.Length; x++) { var parameter = parameters[x]; if (parameter.ParameterType != null) { int index = totalParam; var param = member.parameters[index]; var port = AddPort(new PortData() { getPortName = () => ObjectNames.NicifyVariableName(parameter.Name), getPortType = () => parameter.ParameterType, getPortValue = () => param, filter = new FilterAttribute(parameter.ParameterType), onValueChanged = (obj) => { RegisterUndo(); param = obj as MemberData; member.parameters[index] = param; field.SetValueOptimized(data.block, member); Repaint(); }, }); port.Add(new ControlView(port.portData.InstantiateControl(true), true)); } totalParam++; } continue; } } } } System.Type[] paramsType = member.target.ParameterTypes[i]; if (paramsType != null && paramsType.Length > 0) { if (flag) { AddControl("Method " + (methodDrawCount), null); methodDrawCount++; } while (paramsType.Length + totalParam > member.parameters.Length) { ArrayUtility.Add(ref member.parameters, MemberData.none); } for (int x = 0; x < paramsType.Length; x++) { System.Type PType = paramsType[x]; if (member.parameters[totalParam] == null) { member.parameters[totalParam] = MemberData.none; } if (PType != null) { int index = totalParam; var param = member.parameters[index]; string pLabel; if (objRef != null) { pLabel = objRef.parameters[x].name; } else { pLabel = "P" + (x + 1); } var port = AddPort(new PortData() { getPortName = () => ObjectNames.NicifyVariableName(pLabel), getPortType = () => PType, getPortValue = () => param, filter = new FilterAttribute(PType), onValueChanged = (obj) => { RegisterUndo(); param = obj as MemberData; member.parameters[index] = param; field.SetValueOptimized(data.block, member); Repaint(); }, }); port.Add(new ControlView(port.portData.InstantiateControl(true), true)); } totalParam++; } } } while (member.parameters.Length > totalParam) { ArrayUtility.RemoveAt(ref member.parameters, member.parameters.Length - 1); } } } }