diff --git a/Assets/UdonSharp/Editor/Editors/UdonSharpSettings.cs b/Assets/UdonSharp/Editor/Editors/UdonSharpSettings.cs index 94bb6cf6..cf9756fe 100644 --- a/Assets/UdonSharp/Editor/Editors/UdonSharpSettings.cs +++ b/Assets/UdonSharp/Editor/Editors/UdonSharpSettings.cs @@ -26,6 +26,7 @@ void Start() public bool autoCompileOnModify = true; public bool compileAllScripts = true; + public bool waitForFocus = false; public TextAsset newScriptTemplateOverride = null; public bool buildDebugInfo = true; @@ -89,6 +90,7 @@ public class UdonSharpSettingsProvider { private static GUIContent autoCompileLabel = new GUIContent("Auto compile on modify", "Trigger a compile whenever a U# source file is modified."); private static GUIContent compileAllLabel = new GUIContent("Compile all scripts", "Compile all scripts when a script is modified. This prevents some potential for weird issues where classes don't match"); + private static GUIContent waitForFocusLabel = new GUIContent("Compile on focus", "Waits for application focus to compile any changed U# scripts"); private static GUIContent templateOverrideLabel = new GUIContent("Script template override", "A custom override file to use as a template for newly created U# files. Put \"\" in place of a class name for it to automatically populate with the file name."); private static GUIContent includeDebugInfoLabel = new GUIContent("Debug build", "Include debug info in build"); private static GUIContent includeInlineCodeLabel = new GUIContent("Inline code", "Include C# inline in generated assembly"); @@ -116,6 +118,8 @@ public static SettingsProvider CreateSettingsProvider() EditorGUILayout.HelpBox("Only compiling the script that has been modified can cause issues if you have multiple scripts communicating via methods.", MessageType.Warning); } + EditorGUILayout.PropertyField(settingsObject.FindProperty(nameof(UdonSharpSettings.waitForFocus)), waitForFocusLabel); + EditorGUILayout.PropertyField(settingsObject.FindProperty("newScriptTemplateOverride"), templateOverrideLabel); EditorGUILayout.Space(); diff --git a/Assets/UdonSharp/Editor/UdonSharpAssetCompileWatcher.cs b/Assets/UdonSharp/Editor/UdonSharpAssetCompileWatcher.cs index 1d38db47..2abdd00d 100644 --- a/Assets/UdonSharp/Editor/UdonSharpAssetCompileWatcher.cs +++ b/Assets/UdonSharp/Editor/UdonSharpAssetCompileWatcher.cs @@ -25,7 +25,7 @@ public class UdonSharpAssetCompileWatcher static readonly object modifiedFileLock = new object(); static HashSet modifiedFilePaths = new HashSet(); - static HashSet renamedFilePaths = new HashSet(); + static HashSet modifiedScripts = new HashSet(); static bool lastEnabledState = false; @@ -37,7 +37,23 @@ static UdonSharpAssetCompileWatcher() static void SetupWatchers() { if (fileSystemWatchers != null) + { + UdonSharpSettings settings = UdonSharpSettings.GetSettings(); + + bool watcherEnabled = settings == null || settings.autoCompileOnModify; + + if (watcherEnabled != lastEnabledState) + { + lastEnabledState = watcherEnabled; + foreach (FileSystemWatcher watcher in fileSystemWatchers) + { + if (watcher != null) + watcher.EnableRaisingEvents = watcherEnabled; + } + } + return; + } AssemblyReloadEvents.beforeAssemblyReload += CleanupWatchers; @@ -82,11 +98,23 @@ static void CleanupWatchers() } } - static void HandleScriptModifications(List scripts) + static void HandleScriptModifications() { UdonSharpSettings settings = UdonSharpSettings.GetSettings(); - if (settings != null && !settings.autoCompileOnModify) + if (settings != null) + { + if (!settings.autoCompileOnModify) + { + modifiedScripts.Clear(); + return; + } + + if (settings.waitForFocus && !UnityEditorInternal.InternalEditorUtility.isApplicationActive) + return; + } + + if (modifiedScripts.Count == 0) return; string[] udonSharpDataAssets = AssetDatabase.FindAssets($"t:{typeof(UdonSharpProgramAsset).Name}"); @@ -100,7 +128,7 @@ static void HandleScriptModifications(List scripts) HashSet assetsToUpdate = new HashSet(); - foreach (MonoScript script in scripts) + foreach (MonoScript script in modifiedScripts) { foreach (UdonSharpProgramAsset programAsset in udonSharpPrograms) { @@ -109,46 +137,63 @@ static void HandleScriptModifications(List scripts) } } - if (assetsToUpdate.Count > 0) + try { - if (settings == null || settings.compileAllScripts) - { - UdonSharpProgramAsset.CompileAllCsPrograms(); - } - else + if (assetsToUpdate.Count > 0) { - UdonSharpCompiler compiler = new UdonSharpCompiler(assetsToUpdate.ToArray()); - compiler.Compile(); + if (settings == null || settings.compileAllScripts) + { + UdonSharpProgramAsset.CompileAllCsPrograms(); + } + else + { + UdonSharpCompiler compiler = new UdonSharpCompiler(assetsToUpdate.ToArray()); + compiler.Compile(); + } } } + finally + { + modifiedScripts.Clear(); + } + + modifiedScripts.Clear(); } static void OnEditorUpdate() { SetupWatchers(); - UdonSharpSettings settings = UdonSharpSettings.GetSettings(); + // Prevent people from entering play mode when there are compile errors, like normal Unity C# + if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying) + { + string[] udonSharpDataAssets = AssetDatabase.FindAssets($"t:{typeof(UdonSharpProgramAsset).Name}"); - bool watcherEnabled = settings == null || settings.autoCompileOnModify; + bool foundCompileErrors = false; - if (watcherEnabled != lastEnabledState && fileSystemWatchers != null) - { - lastEnabledState = watcherEnabled; - foreach (FileSystemWatcher watcher in fileSystemWatchers) + foreach (string dataGuid in udonSharpDataAssets) { - if (watcher != null) - watcher.EnableRaisingEvents = watcherEnabled; + UdonSharpProgramAsset programAsset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(dataGuid)); + + if (programAsset.sourceCsScript != null && programAsset.compileErrors.Count > 0) + { + foundCompileErrors = true; + break; + } } - } - List modifiedScripts = null; + if (foundCompileErrors) + { + EditorApplication.isPlaying = false; + typeof(SceneView).GetMethod("ShowNotification", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).Invoke(null, new object[] { "All U# compiler errors have to be fixed before you can enter playmode!" }); + } + } + lock (modifiedFileLock) { if (modifiedFilePaths.Count > 0) { - modifiedScripts = new List(); - foreach (string filePath in modifiedFilePaths) { MonoScript asset = AssetDatabase.LoadAssetAtPath(filePath.Replace(Application.dataPath.Replace("/", "\\"), "Assets")); @@ -159,8 +204,7 @@ static void OnEditorUpdate() } } - if (modifiedScripts != null && modifiedScripts.Count > 0) - HandleScriptModifications(modifiedScripts); + HandleScriptModifications(); } static void OnSourceFileChanged(object source, FileSystemEventArgs args) diff --git a/Assets/UdonSharp/version.txt b/Assets/UdonSharp/version.txt index d5bd67d2..1902df97 100644 --- a/Assets/UdonSharp/version.txt +++ b/Assets/UdonSharp/version.txt @@ -1 +1 @@ -v0.15.3 +v0.15.5