public static void Update() { if (!File.Exists(BoltFlow.Paths.unitOptions)) { Build(); return; } lock (@lock) { using (ProfilingUtility.SampleBlock("Update Unit Database")) { using (NativeUtility.Module("sqlite3.dll")) { var progressTitle = "Updating unit database..."; SQLiteConnection database = null; try { VersionControlUtility.Unlock(BoltFlow.Paths.unitOptions); var steps = 7f; var step = 0f; ProgressUtility.DisplayProgressBar(progressTitle, "Connecting to database...", step++ / steps); database = new SQLiteConnection(BoltFlow.Paths.unitOptions); ProgressUtility.DisplayProgressBar(progressTitle, "Updating type mappings...", step++ / steps); UpdateTypeMappings(); ProgressUtility.DisplayProgressBar(progressTitle, "Fetching modified scripts...", step++ / steps); var modifiedScriptGuids = GetModifiedScriptGuids().Distinct().ToHashSet(); ProgressUtility.DisplayProgressBar(progressTitle, "Fetching deleted scripts...", step++ / steps); var deletedScriptGuids = GetDeletedScriptGuids().Distinct().ToHashSet(); ProgressUtility.DisplayProgressBar(progressTitle, "Updating codebase...", step++ / steps); var modifiedScriptTypes = modifiedScriptGuids.SelectMany(GetScriptTypes).ToArray(); UpdateCodebase(modifiedScriptTypes); var outdatedScriptGuids = new HashSet <string>(); outdatedScriptGuids.UnionWith(modifiedScriptGuids); outdatedScriptGuids.UnionWith(deletedScriptGuids); ProgressUtility.DisplayProgressBar(progressTitle, "Removing outdated unit options...", step++ / steps); options?.RemoveWhere(option => outdatedScriptGuids.Overlaps(option.sourceScriptGuids)); // We want to use the database level WHERE here for speed, // so we'll run multiple queries, one for each outdated script GUID. foreach (var outdatedScriptGuid in outdatedScriptGuids) { foreach (var outdatedRowId in database.Table <UnitOptionRow>() .Where(row => row.sourceScriptGuids.Contains(outdatedScriptGuid)) .Select(row => row.id)) { database.Delete <UnitOptionRow>(outdatedRowId); } } ProgressUtility.DisplayProgressBar(progressTitle, "Converting codebase to unit options...", step++ / steps); var newOptions = new HashSet <IUnitOption>(modifiedScriptGuids.SelectMany(GetScriptTypes) .Distinct() .SelectMany(GetIncrementalOptions)); var rows = new HashSet <UnitOptionRow>(); float progress = 0; foreach (var newOption in newOptions) { options?.Add(newOption); try { ProgressUtility.DisplayProgressBar(progressTitle, newOption.label, (step / steps) + ((1 / step) * (progress / newOptions.Count))); rows.Add(newOption.Serialize()); } catch (Exception ex) { Debug.LogError($"Failed to serialize option '{newOption.GetType()}'.\n{ex}"); } progress++; } ProgressUtility.DisplayProgressBar(progressTitle, "Writing to database...", 1); try { database.InsertAll(rows); } catch (Exception ex) { Debug.LogError($"Failed to write options to database.\n{ex}"); } // Make sure the database is touched to the current date, // even if we didn't do any change. This will avoid unnecessary // analysis in future update checks. File.SetLastWriteTimeUtc(BoltFlow.Paths.unitOptions, DateTime.UtcNow); } finally { database?.Close(); ProgressUtility.ClearProgressBar(); UnityAPI.Async(AssetDatabase.Refresh); //ConsoleProfiler.Dump(); } } } } }
public static void Build() { 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); if (File.Exists(BoltFlow.Paths.unitOptions)) { VersionControlUtility.Unlock(BoltFlow.Paths.unitOptions); File.Delete(BoltFlow.Paths.unitOptions); } 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(); } } } } }