示例#1
0
        public static string GetPluginRuntimeGUID(Plugin plugin)
        {
            Ensure.That(nameof(plugin)).IsNotNull(plugin);

            return(AssetDatabase.AssetPathToGUID(PathUtility.FromProject(plugin.runtimeAssembly.Location)));
        }
示例#2
0
 private void DeleteAotStubs()
 {
     PathUtility.DeleteProjectFileIfExists(linkerPath, true);
     PathUtility.DeleteProjectFileIfExists(aotStubsPath, true);
 }
示例#3
0
        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();
                            }
                        }
                    }
                }
            }
        }
示例#4
0
        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();
            }
        }