public static string GetPluginRuntimeGUID(Plugin plugin) { Ensure.That(nameof(plugin)).IsNotNull(plugin); return(AssetDatabase.AssetPathToGUID(PathUtility.FromProject(plugin.runtimeAssembly.Location))); }
private void DeleteAotStubs() { PathUtility.DeleteProjectFileIfExists(linkerPath, true); PathUtility.DeleteProjectFileIfExists(aotStubsPath, true); }
public static void Build() { if (!IsUnitOptionsBuilt()) { var progressTitle = "Building unit database..."; lock (@lock) { using (ProfilingUtility.SampleBlock("Update Unit Database")) { using (NativeUtility.Module("sqlite3.dll")) { SQLiteConnection database = null; try { ProgressUtility.DisplayProgressBar(progressTitle, "Creating database...", 0); PathUtility.CreateParentDirectoryIfNeeded(BoltFlow.Paths.unitOptions); database = new SQLiteConnection(BoltFlow.Paths.unitOptions); database.CreateTable <UnitOptionRow>(); ProgressUtility.DisplayProgressBar(progressTitle, "Updating codebase...", 0); UpdateCodebase(); ProgressUtility.DisplayProgressBar(progressTitle, "Updating type mappings...", 0); UpdateTypeMappings(); ProgressUtility.DisplayProgressBar(progressTitle, "Converting codebase to unit options...", 0); options = new HashSet <IUnitOption>(GetStaticOptions()); var rows = new HashSet <UnitOptionRow>(); var progress = 0; var lastShownProgress = 0f; foreach (var option in options) { try { var shownProgress = (float)progress / options.Count; if (shownProgress > lastShownProgress + 0.01f) { ProgressUtility.DisplayProgressBar(progressTitle, "Converting codebase to unit options...", shownProgress); lastShownProgress = shownProgress; } rows.Add(option.Serialize()); } catch (Exception ex) { Debug.LogError($"Failed to save option '{option.GetType()}'.\n{ex}"); } progress++; } ProgressUtility.DisplayProgressBar(progressTitle, "Writing to database...", 1); try { database.CreateTable <UnitOptionRow>(); database.InsertAll(rows); } catch (Exception ex) { Debug.LogError($"Failed to write options to database.\n{ex}"); } } finally { database?.Close(); ProgressUtility.ClearProgressBar(); AssetDatabase.Refresh(); //ConsoleProfiler.Dump(); } } } } } }
private void GenerateStubScript(string scriptPath, IEnumerable <AotStubWriter> stubWriters) { Ensure.That(nameof(stubWriters)).IsNotNull(stubWriters); var unit = new CodeCompileUnit(); var @namespace = new CodeNamespace("Unity.VisualScripting.Generated.Aot"); unit.Namespaces.Add(@namespace); var @class = new CodeTypeDeclaration("AotStubs") { IsClass = true }; @class.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(PreserveAttribute)))); @namespace.Types.Add(@class); var usedMethodNames = new HashSet <string>(); foreach (var stubWriter in stubWriters.OrderBy(sw => sw.stubMethodComment)) { if (stubWriter.skip) { continue; } var methodName = stubWriter.stubMethodName; var i = 0; while (usedMethodNames.Contains(methodName)) { methodName = stubWriter.stubMethodName + "_" + i++; } usedMethodNames.Add(methodName); @class.Comments.Add(new CodeCommentStatement(stubWriter.stubMethodComment)); var @method = new CodeMemberMethod { Name = methodName, ReturnType = new CodeTypeReference(typeof(void)), Attributes = MemberAttributes.Public | MemberAttributes.Static }; @method.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(PreserveAttribute), CodeTypeReferenceOptions.GlobalReference))); @method.Comments.Add(new CodeCommentStatement(stubWriter.stubMethodComment)); @method.Statements.AddRange(stubWriter.GetStubStatements().ToArray()); @class.Members.Add(@method); } PathUtility.CreateDirectoryIfNeeded(BoltCore.Paths.transientGenerated); PathUtility.DeleteProjectFileIfExists(aotStubsPath, true); using (var provider = CodeDomProvider.CreateProvider("CSharp")) { var options = new CodeGeneratorOptions { BracingStyle = "C", IndentString = "\t", BlankLinesBetweenMembers = true, ElseOnClosing = false, VerbatimOrder = true }; using (var scriptWriter = new StreamWriter(scriptPath)) { provider.GenerateCodeFromCompileUnit(new CodeSnippetCompileUnit("#pragma warning disable 219"), scriptWriter, options); // Disable unused variable warning provider.GenerateCodeFromCompileUnit(unit, scriptWriter, options); } } AssetDatabase.Refresh(); }
public static void Run(IEnumerable <string> paths, IEnumerable <ScriptReferenceReplacement> replacements, Mode mode) { if (!canRun) { var message = "Cannot run missing script resolver with the current serialization mode.\nSet the project serialization mode to 'Force Text' and try again."; if (mode == Mode.Dialog) { EditorUtility.DisplayDialog("Script Reference Resolver", message, "OK"); } else if (mode == Mode.Console) { Debug.LogWarning(message); } return; } // Doing a naive approach here: replacing the exact string by regex instead of parsing the YAML, // since Unity sometimes breaks YAML specifications. This is whitespace dependant, but it should work. var newContents = new Dictionary <string, string[]>(); var _paths = paths.ToArray(); var pathIndex = 0; var regexes = new Dictionary <ScriptReferenceReplacement, Regex>(); foreach (var replacement in replacements) { var regex = new Regex($@"\{{fileID: {replacement.previousReference.fileID}, guid: {replacement.previousReference.guid}, type: 3\}}", RegexOptions.Compiled); regexes.Add(replacement, regex); } foreach (var path in _paths) { if (newContents.ContainsKey(path)) { // Duplicate path continue; } var replaced = false; var fileContents = new List <string>(); if (mode == Mode.Dialog) { ProgressUtility.DisplayProgressBar("Script Reference Resolver", $"Analyzing '{path}'...", pathIndex++ / (float)_paths.Length); } foreach (var line in File.ReadAllLines(path)) { var newLine = line; foreach (var replacement in replacements) { newLine = regexes[replacement].Replace ( newLine, (match) => { replaced = true; return($@"{{fileID: {replacement.newReference.fileID}, guid: {replacement.newReference.guid}, type: 3}}"); } ); } fileContents.Add(newLine); } if (replaced) { newContents.Add(path, fileContents.ToArray()); } } pathIndex = 0; if (newContents.Count > 0) { var pathMaxLength = 40; var fileLimit = 15; var fileList = newContents.Keys.Select(p => StringUtility.PathEllipsis(PathUtility.FromProject(p), pathMaxLength)).Take(fileLimit).ToLineSeparatedString(); if (newContents.Count > fileLimit) { fileList += "\n..."; } var replace = true; if (mode == Mode.Dialog) { var message = $"Missing script references have been found in {newContents.Count} file{(newContents.Count > 1 ? "s" : "")}: \n\n{fileList}\n\nProceed with replacement?"; replace = EditorUtility.DisplayDialog("Script Reference Resolver", message, "Replace References", "Cancel"); } if (replace) { foreach (var newContent in newContents) { if (mode == Mode.Dialog) { ProgressUtility.DisplayProgressBar("Script Reference Resolver", $"Fixing '{newContent.Key}'...", pathIndex++ / (float)_paths.Length); } VersionControlUtility.Unlock(newContent.Key); File.WriteAllLines(newContent.Key, newContent.Value); } if (mode == Mode.Dialog) { EditorUtility.DisplayDialog("Script Reference Resolver", "Script references have been successfully replaced.\nRestarting Unity is recommended.", "OK"); } else if (mode == Mode.Console) { Debug.Log($"Missing script references have been replaced in {newContents.Count} file{(newContents.Count > 1 ? "s" : "")}.\nRestarting Unity is recommended.\n{fileList}\n"); } } } else { var message = "No missing script reference was found."; if (mode == Mode.Dialog) { EditorUtility.DisplayDialog("Script Reference Resolver", message, "OK"); } else if (mode == Mode.Console) { // Debug.Log(message); } } if (mode == Mode.Dialog) { ProgressUtility.ClearProgressBar(); } }