Beispiel #1
0
        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);
        }