Skip to content
This repository has been archived by the owner on Jan 22, 2022. It is now read-only.

Commit

Permalink
Add option to wait until Unity is focused to compile a changed source…
Browse files Browse the repository at this point in the history
… file

- Add option to wait until Unity is focused to compile a changed source file
- Add error display that prevents you from entering play mode while a U# script has compile errors
  • Loading branch information
MerlinVR committed Apr 13, 2020
1 parent 9ad2b8c commit 754b59b
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 27 deletions.
4 changes: 4 additions & 0 deletions Assets/UdonSharp/Editor/Editors/UdonSharpSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 \"<TemplateClassName>\" 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");
Expand Down Expand Up @@ -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();
Expand Down
96 changes: 70 additions & 26 deletions Assets/UdonSharp/Editor/UdonSharpAssetCompileWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class UdonSharpAssetCompileWatcher
static readonly object modifiedFileLock = new object();

static HashSet<string> modifiedFilePaths = new HashSet<string>();
static HashSet<string> renamedFilePaths = new HashSet<string>();
static HashSet<MonoScript> modifiedScripts = new HashSet<MonoScript>();

static bool lastEnabledState = false;

Expand All @@ -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;

Expand Down Expand Up @@ -82,11 +98,23 @@ static void CleanupWatchers()
}
}

static void HandleScriptModifications(List<MonoScript> 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}");
Expand All @@ -100,7 +128,7 @@ static void HandleScriptModifications(List<MonoScript> scripts)

HashSet<UdonSharpProgramAsset> assetsToUpdate = new HashSet<UdonSharpProgramAsset>();

foreach (MonoScript script in scripts)
foreach (MonoScript script in modifiedScripts)
{
foreach (UdonSharpProgramAsset programAsset in udonSharpPrograms)
{
Expand All @@ -109,46 +137,63 @@ static void HandleScriptModifications(List<MonoScript> 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<UdonSharpProgramAsset>(AssetDatabase.GUIDToAssetPath(dataGuid));

if (programAsset.sourceCsScript != null && programAsset.compileErrors.Count > 0)
{
foundCompileErrors = true;
break;
}
}
}

List<MonoScript> 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<MonoScript>();

foreach (string filePath in modifiedFilePaths)
{
MonoScript asset = AssetDatabase.LoadAssetAtPath<MonoScript>(filePath.Replace(Application.dataPath.Replace("/", "\\"), "Assets"));
Expand All @@ -159,8 +204,7 @@ static void OnEditorUpdate()
}
}

if (modifiedScripts != null && modifiedScripts.Count > 0)
HandleScriptModifications(modifiedScripts);
HandleScriptModifications();
}

static void OnSourceFileChanged(object source, FileSystemEventArgs args)
Expand Down
2 changes: 1 addition & 1 deletion Assets/UdonSharp/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.15.3
v0.15.5

0 comments on commit 754b59b

Please sign in to comment.