BetterGitStatePersistence.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright (c) 2025 TerraByte Inc.
  2. //
  3. // A static class that persists the state of a multi-file reset operation
  4. // across script re-compilations, ensuring the process is not interrupted.
  5. using System.Linq;
  6. using UnityEditor;
  7. using UnityEngine.Scripting;
  8. namespace Terra.Arbitrator.Services
  9. {
  10. [Preserve]
  11. [InitializeOnLoad]
  12. public static class BetterGitStatePersistence
  13. {
  14. internal const string ResetQueueKey = "BetterGit.ResetQueue";
  15. // This static constructor runs automatically after every script compilation.
  16. static BetterGitStatePersistence()
  17. {
  18. // Use delayCall to ensure this runs after the editor is fully initialized.
  19. EditorApplication.delayCall += ContinueInterruptedReset;
  20. }
  21. public static void ContinueInterruptedReset()
  22. {
  23. while (true)
  24. {
  25. var queuedFiles = SessionState.GetString(ResetQueueKey, "");
  26. if (string.IsNullOrEmpty(queuedFiles))
  27. {
  28. return; // Nothing to do.
  29. }
  30. var fileList = queuedFiles.Split(';').ToList();
  31. if (!fileList.Any())
  32. {
  33. SessionState.EraseString(ResetQueueKey);
  34. return;
  35. }
  36. // Get the next file to process
  37. var fileToReset = fileList.First();
  38. fileList.RemoveAt(0);
  39. // Update the session state with the remaining files BEFORE starting the operation.
  40. if (fileList.Any())
  41. {
  42. SessionState.SetString(ResetQueueKey, string.Join(";", fileList));
  43. }
  44. else
  45. {
  46. // Last file was processed, clear the key.
  47. SessionState.EraseString(ResetQueueKey);
  48. }
  49. // Create a GitChange object for the file to be reset.
  50. // This is a small, synchronous operation to get the file's current status.
  51. var change = GitService.GetChangeForFile(fileToReset);
  52. if (change == null)
  53. {
  54. // The File might have already been reset or state is unusual.
  55. // We'll log it and attempt to continue.
  56. UnityEngine.Debug.LogWarning($"Could not find status for {fileToReset}, skipping reset. It may have already been processed.");
  57. continue;
  58. }
  59. // Trigger the reset. After this, Unity will recompile if it was a script,
  60. // and this whole static constructor will run again.
  61. GitService.ResetFileChanges(change);
  62. break;
  63. }
  64. }
  65. }
  66. }