BetterGitStatePersistence.cs 2.7 KB

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