123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- using XGame.Editor.Build;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Text.RegularExpressions;
- using UnityEditor;
- using UnityEditor.Compilation;
- using UnityEngine;
- namespace XGame.Editor.Compiler
- {
- //[InitializeOnLoad]
- public static class CompileScriptsHandle
- {
- private static CompileResult result;
- [UnityEditor.Callbacks.DidReloadScripts]
- static void OnDidReloadScripts()
- {
- //Debug.Log("CompileScriptsHandle OnDidReloadScripts.");
- EditorApplication.quitting -= OnQuit;
- EditorApplication.quitting += OnQuit;
- CompilationPipeline.compilationFinished -= OnCompilationFinished;
- CompilationPipeline.compilationFinished += OnCompilationFinished;
- CompilationPipeline.assemblyCompilationFinished -= OnAssemblyCompilationFinished;
- CompilationPipeline.assemblyCompilationFinished += OnAssemblyCompilationFinished;
- //加载 初始化ICompileEvents
- if (HasEvents)
- {
- EditorApplication.update += OnUpdate;
- }
- //Debug.Log($"CompileScriptsHandle InitializeOnLoad. isCompiling: {EditorApplication.isCompiling}");
- }
- //[InitializeOnLoadMethod]
- //static void OnInitializeOnLoadMethod()
- //{
- // Debug.Log("CompileScriptsHandle OnInitializeOnLoadMethod.");
- //}
- /// <summary>
- /// 监听编辑器退出事件
- /// </summary>
- private static void OnQuit()
- {
- //Debug.Log("EditorApplication OnQuit.");
- Clear();
- }
- /// <summary>
- /// 监听Assembly编译事件
- /// 编译失败时需要记录失败状态
- /// </summary>
- /// <param name="obj"></param>
- /// <param name="messages"></param>
- private static void OnAssemblyCompilationFinished(string obj, CompilerMessage[] messages)
- {
- //Debug.Log($"OnAssemblyCompilationFinished. obj:{obj?.ToString() ?? "null"} msgCount:{messages?.Length ?? 0}");
- if (messages != null && HasEvents)
- {
- foreach(var msg in messages)
- {
- if (msg.type == CompilerMessageType.Error)
- {
- result.isFailed = true;
- result.message = msg.message;
- if (result.isCopyAssemblyFailed == false && msg.message.Contains("Copying assembly from"))
- {
- //assembly拷贝失败
- result.isCopyAssemblyFailed = true;
- }
- //打印错误信息
- BuildLog.Error($"OnAssemblyCompilation error. msg:{msg.message} file:{msg.file} line:{msg.line} col:{msg.column}");
- }
- }
- }
- }
- /// <summary>
- /// 监听编译结束回调事件
- /// 编译失败时 Unity 不会执行InitializeOnLoad
- /// 需要主动执行回调事件
- /// </summary>
- /// <param name="obj"></param>
- private static void OnCompilationFinished(object obj)
- {
- //Debug.Log($"OnCompilationFinished. obj:{obj?.ToString() ?? "null"}");
- if (result.isFailed == false) return;
- //编译失败,主动执行回调
- if (HasEvents)
- {
- EditorApplication.update += OnUpdate;
- }
- }
- private static void OnUpdate()
- {
- //Debug.Log($"CompileScriptsHandle OnUpdate. isCompiling: {EditorApplication.isCompiling} isFailed:{result.isFailed}");
- EditorApplication.update -= OnUpdate;
- if (UnityEditorInternal.InternalEditorUtility.inBatchMode == false && result.isFailed && result.isCopyAssemblyFailed)
- {
- //非BatchMode下, 编译失败,并且是拷贝Assembly失败,重新编译
- BuildLog.Log($"Compile Scripts Error: Assembly copy failed. Restart RequestScriptCompilation.");
- result = default;
- CompilationPipeline.RequestScriptCompilation();
- return;
- }
- var events = ReadEvents();
- if (events != null)
- {
- var tempResult = result;
- result = default;
- for (int i = 0; i < events.Length; i++)
- {
- if (tempResult.isFailed)
- {
- events[i].OnCompileFailed(tempResult);
- }
- else
- {
- events[i].OnCompileSuccess();
- }
- }
- events = null;
- }
- }
- private static string OutputPath
- {
- get
- {
- return Path.GetFullPath($"{Application.dataPath}/../ExtAssets/Editor/CompileEvents.json").Replace("\\", "/");
- }
- }
- /// <summary>
- /// 是否有监听事件
- /// </summary>
- private static bool HasEvents => File.Exists(OutputPath);
- public static void RegistEvent(ICompileEvent compileEvent)
- {
- var filePath = OutputPath;
- var dir = Path.GetDirectoryName(filePath);
- if (!Directory.Exists(dir))
- {
- Directory.CreateDirectory(dir);
- }
- var str = $"<type:{compileEvent.GetType().AssemblyQualifiedName} value:{LitJson.JsonMapper.ToJson(compileEvent)}/>";
- try
- {
- var writer = File.Exists(filePath) ? new StreamWriter(filePath, true) : new StreamWriter(filePath);
- writer.WriteLine(str);
- writer.Flush();
- writer.Close();
- BuildLog.Log($"CompileScriptsHandle RegistEvent:{str}");
- }
- catch (Exception ex)
- {
- BuildLog.Exception(ex);
- }
- }
- private static ICompileEvent[] ReadEvents()
- {
- var path = OutputPath;
- if (File.Exists(path))
- {
- List<ICompileEvent> lst = new List<ICompileEvent>();
- try
- {
- Regex regex = new Regex(@"<type:(.+?) value:(.+?)/>", RegexOptions.Multiline);
- var lines = File.ReadAllLines(path);
- foreach (var line in lines)
- {
- var match = regex.Match(line);
- if (match.Success)
- {
- var typeName = match.Groups[1].Value;
- var eventValue = match.Groups[2].Value;
- BuildLog.Log($"CompileScriptsHandle ReadEvents type:{typeName} value:{eventValue}");
- Type type = Type.GetType(typeName);
- var compileEvent = LitJson.JsonMapper.ToObject(eventValue, type) as ICompileEvent;
- lst.Add(compileEvent);
- }
- }
- lst.Sort((a, b) =>
- {
- return a.Priority - b.Priority;
- });
- }
- catch (Exception ex)
- {
- BuildLog.Exception(ex);
- }
- //删除文件
- Clear();
- return lst.ToArray();
- }
- return null;
- }
-
- public static void Clear()
- {
- var path = OutputPath;
- if (File.Exists(path))
- {
- File.Delete(path);
- }
- }
- }
- }
|