public static void CompileNativeGraph(GameObject graphObject, bool enableLogging = true) { string fileName = graphObject.name; GameObject prefabContent = null; var go = graphObject; if (uNodeEditorUtility.IsPrefab(graphObject)) { if (GraphUtility.HasTempGraphObject(graphObject)) { go = GraphUtility.GetTempGraphObject(graphObject); } else { prefabContent = PrefabUtility.LoadPrefabContents(AssetDatabase.GetAssetPath(graphObject)); go = prefabContent; } } else if (GraphUtility.IsTempGraphObject(graphObject)) { graphObject = GraphUtility.GetOriginalObject(graphObject); } uNodeRoot renamedRoot = null; { var root = go.GetComponent <uNodeRoot>(); if (root && string.IsNullOrEmpty(root.Name)) { root.Name = fileName; renamedRoot = root; } } Directory.CreateDirectory(GenerationUtility.tempFolder); char separator = Path.DirectorySeparatorChar; string path = GenerationUtility.tempFolder + separator + fileName + ".cs"; try { System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); var script = GenerationUtility.GenerateCSharpScript(go, true, (progress, text) => { EditorUtility.DisplayProgressBar("Loading", text, progress); }); List <ScriptInformation> informations; var generatedScript = script.ToScript(out informations); if (preferenceData.generatorData.convertLineEnding) { generatedScript = GenerationUtility.ConvertLineEnding(generatedScript, Application.platform != RuntimePlatform.WindowsEditor); } if (preferenceData.generatorData != null && preferenceData.generatorData.analyzeScript && preferenceData.generatorData.formatScript) { var codeFormatter = TypeSerializer.Deserialize("MaxyGames.uNode.Editors.CSharpFormatter", false); if (codeFormatter != null) { var str = codeFormatter. GetMethod("FormatCode"). Invoke(null, new object[] { generatedScript }) as string; generatedScript = str; } } using (StreamWriter sw = new StreamWriter(path)) { sw.Write(generatedScript); sw.Close(); } watch.Stop(); if (enableLogging) { Debug.LogFormat("Generating C# took {0,8:N3} s.", watch.Elapsed.TotalSeconds); } if (preferenceData.generatorData.compileScript) { bool isBecauseOfAccessibility = false; try { watch.Reset(); watch.Start(); EditorUtility.DisplayProgressBar("Loading", "Compiling", 1); var compileResult = CompileScript(generatedScript); if (compileResult.assembly == null) { isBecauseOfAccessibility = true; foreach (var error in compileResult.errors) { if (error.errorNumber != "CS0122") { isBecauseOfAccessibility = false; break; } } throw new Exception(compileResult.GetErrorMessage()); } watch.Stop(); #if !NET_STANDARD_2_0 if (enableLogging) { Debug.LogFormat("Compiling script took {0,8:N3} s.", watch.Elapsed.TotalSeconds); } #endif } catch (System.Exception ex) { watch.Stop(); EditorUtility.ClearProgressBar(); if (EditorUtility.DisplayDialog("Compile Errors", "Compile before save detect an error: \n" + ex.Message + "\n\n" + (isBecauseOfAccessibility ? "The initial errors may because of using a private class.\nWould you like to ignore the error and save it?" : "Would you like to ignore the error and save it?"), "Ok, save it", "No, don't save")) { Debug.Log("Compile errors: " + ex.Message); } else { Debug.Log("Temp script saved to: " + Path.GetFullPath(path)); throw ex; } } } if (EditorUtility.IsPersistent(graphObject)) //For prefab and asset { path = (Path.GetDirectoryName(AssetDatabase.GetAssetPath(graphObject)) + separator + fileName + ".cs"); if (informations != null) { uNodeEditor.SavedData.RegisterGraphInfos(informations, script.graphOwner, path); } using (FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write)) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Write(generatedScript); writer.Close(); } stream.Close(); } } else //For the scene object. { path = EditorUtility.SaveFilePanel("Save Script", "Assets", fileName + ".cs", "cs"); if (informations != null) { uNodeEditor.SavedData.RegisterGraphInfos(informations, script.graphOwner, path); } using (FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write)) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Write(generatedScript); writer.Close(); } stream.Close(); } } AssetDatabase.Refresh(); Debug.Log("Script saved to: " + Path.GetFullPath(path)); EditorUtility.ClearProgressBar(); } catch { EditorUtility.ClearProgressBar(); Debug.LogError("Aborting Generating C# Script because have error."); throw; } finally { if (renamedRoot) { renamedRoot.Name = ""; } if (prefabContent != null) { PrefabUtility.UnloadPrefabContents(prefabContent); } } }
void Init(bool autoLayout) { if (config.type is RuntimeType) { if (config.owner.targetNode.owner.IsRuntimeGraph()) { var field = new ObjectRuntimeField() { objectType = config.type as RuntimeType, value = config.value as UnityEngine.Object, allowSceneObjects = uNodeEditorUtility.IsSceneObject(config.owner.targetNode) }; field.RegisterValueChangedCallback((e) => { config.OnValueChanged(e.newValue); MarkDirtyRepaint(); }); Add(field); } else { var button = new Label() { text = "null" }; button.AddToClassList("PopupButton"); button.EnableInClassList("Layout", autoLayout); Add(button); // if(config.value != null) { // try { // config.OnValueChanged(null); // } catch{ } // } } } else { ObjectField field = new ObjectField() { objectType = config.type, value = config.value as UnityEngine.Object, }; field.RegisterValueChangedCallback((e) => { config.OnValueChanged(e.newValue); MarkDirtyRepaint(); }); field.allowSceneObjects = uNodeEditorUtility.IsSceneObject(config.owner.targetNode) && !GraphUtility.IsTempGraphObject(config.owner.targetNode.gameObject); Add(field); } }
public static void RefactorProperty(uNodeProperty property, string name) { name = uNodeUtility.AutoCorrectName(name); var graph = property.owner; bool hasVariable = false; if (graph.Properties != null && graph.Properties.Count > 0) { foreach (var V in graph.Properties) { if (V.Name == name) { hasVariable = true; break; } } } if (graph.Variables != null && graph.Variables.Count > 0) { foreach (var V in graph.Variables) { if (V.Name == name) { hasVariable = true; break; } } } if (hasVariable) { return; } Undo.SetCurrentGroupName("Rename Property: " + property.Name); HashSet <GameObject> referencedGraphs = new HashSet <GameObject>(); if (graph != null) { RuntimeProperty 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) { runtime = ReflectionUtils.GetRuntimeType(oriGraph).GetProperty(property.Name) as RuntimeProperty; } } } else { runtime = ReflectionUtils.GetRuntimeType(graph).GetProperty(property.Name) as RuntimeProperty; } } PropertyInfo nativeMember = null; if (graph.GeneratedTypeName.ToType(false) != null) { var type = graph.GeneratedTypeName.ToType(false); nativeMember = type.GetProperty(property.Name, MemberData.flags); } 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] = name; member.name = string.Join(".", path); if (m == nativeMember) { referencedGraphs.Add(prefab); } return(true); } } } } } return(false); }; if (runtime != null || nativeMember != 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); string oldVarName = property.Name; property.Name = name; graph.Refresh(); Func <object, bool> validation = delegate(object OBJ) { return(CallbackRenameProperty(OBJ, graph, property.name, oldVarName)); }; 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); }
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); }
public static void RefactorVariable(VariableData variable, string name, UnityEngine.Object owner) { bool isLocal = false; uNodeRoot graph = owner as uNodeRoot; if (graph == null) { INode <uNodeRoot> node = owner as INode <uNodeRoot>; if (node != null) { graph = node.GetOwner(); isLocal = true; } } if (graph != null) { HashSet <GameObject> referencedGraphs = new HashSet <GameObject>(); if (!isLocal) { RuntimeField field = 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) { field = ReflectionUtils.GetRuntimeType(oriGraph).GetField(variable.Name) as RuntimeField; } } } else { field = ReflectionUtils.GetRuntimeType(graph).GetField(variable.Name) as RuntimeField; } } FieldInfo nativeMember = null; if (graph.GeneratedTypeName.ToType(false) != null) { var type = graph.GeneratedTypeName.ToType(false); nativeMember = type.GetField(variable.Name, MemberData.flags); } 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) { 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 == field || m == nativeMember) { if (!hasUndo && prefabContent == null) { uNodeEditorUtility.RegisterFullHierarchyUndo(gameObject, "Rename Variable: " + variable.Name); hasUndo = true; } var path = member.namePath; path[i + 1] = name; member.name = string.Join(".", path); if (m == nativeMember) { referencedGraphs.Add(prefab); } return(true); } } } } } return(false); }; if (field != null || nativeMember != 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, "Rename Variable: " + variable.Name); if (prefabContent == null) { //Save the temporary graph GraphUtility.AutoSaveGraph(gameObject); } else { //Save the prefab contents uNodeEditorUtility.SavePrefabAsset(gameObject, prefab); } } uNodeEditorUtility.MarkDirty(prefab); } } if (prefabContent != null) { PrefabUtility.UnloadPrefabContents(prefabContent); } } } string oldVarName = variable.Name; variable.Name = name; Func <object, bool> validation = delegate(object OBJ) { return(CallbackRenameVariable(OBJ, owner, variable.Name, oldVarName)); }; graph.Refresh(); Array.ForEach(graph.nodes, item => AnalizerUtility.AnalizeObject(item, validation)); if (GraphUtility.IsTempGraphObject(graph.gameObject)) { var prefab = uNodeEditorUtility.GetGameObjectSource(graph.gameObject, null); uNodeEditorUtility.RegisterFullHierarchyUndo(prefab, "Rename Variable: " + oldVarName); GraphUtility.AutoSaveGraph(graph.gameObject); } uNodeEditor.ClearGraphCache(); uNodeEditor.window?.Refresh(true); DoCompileReferences(graph, referencedGraphs); } }