HistoryModel.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. using System;
  2. using System.Collections.Generic;
  3. using JetBrains.Annotations;
  4. using Unity.Cloud.Collaborate.Models.Api;
  5. using Unity.Cloud.Collaborate.Models.Structures;
  6. using Unity.Cloud.Collaborate.UserInterface;
  7. using UnityEngine;
  8. using UnityEngine.Assertions;
  9. namespace Unity.Cloud.Collaborate.Models
  10. {
  11. internal class HistoryModel : IHistoryModel
  12. {
  13. [NotNull]
  14. readonly ISourceControlProvider m_Provider;
  15. [NotNull]
  16. readonly HashSet<string> m_Requests;
  17. const string k_RequestPage = "request-page";
  18. const string k_RequestEntry = "request-entry";
  19. const string k_RequestEntryNumber = "request-entry-number";
  20. /// <inheritdoc />
  21. public event Action HistoryListUpdated;
  22. /// <inheritdoc />
  23. public event Action<IReadOnlyList<IHistoryEntry>> HistoryListReceived;
  24. /// <inheritdoc />
  25. public event Action<IHistoryEntry> SelectedRevisionReceived;
  26. /// <inheritdoc />
  27. public event Action<bool> BusyStatusUpdated;
  28. /// <inheritdoc />
  29. public event Action<int?> EntryCountUpdated;
  30. /// <inheritdoc />
  31. public event Action StateChanged;
  32. public HistoryModel([NotNull] ISourceControlProvider provider)
  33. {
  34. m_Provider = provider;
  35. m_Requests = new HashSet<string>();
  36. SelectedRevisionId = string.Empty;
  37. SavedRevisionId = string.Empty;
  38. }
  39. /// <inheritdoc />
  40. public void OnStart()
  41. {
  42. // Setup events
  43. m_Provider.UpdatedHistoryEntries += OnUpdatedHistoryEntries;
  44. }
  45. /// <inheritdoc />
  46. public void OnStop()
  47. {
  48. // Clean up.
  49. m_Provider.UpdatedHistoryEntries -= OnUpdatedHistoryEntries;
  50. }
  51. /// <inheritdoc />
  52. public void RestoreState(IWindowCache cache)
  53. {
  54. // Populate data.
  55. PageNumber = cache.HistoryPageNumber;
  56. SavedRevisionId = cache.SelectedHistoryRevision;
  57. StateChanged?.Invoke();
  58. }
  59. /// <inheritdoc />
  60. public void SaveState(IWindowCache cache)
  61. {
  62. // Update cache.
  63. cache.HistoryPageNumber = PageNumber;
  64. cache.SelectedHistoryRevision = SelectedRevisionId;
  65. }
  66. /// <summary>
  67. /// Event handler for when the requested history entry count has been received.
  68. /// </summary>
  69. /// <param name="entryCount">Received entry count.</param>
  70. void OnReceivedHistoryEntryCount(int? entryCount)
  71. {
  72. RemoveRequest(k_RequestEntryNumber);
  73. EntryCountUpdated?.Invoke(entryCount);
  74. }
  75. /// <summary>
  76. /// Event handler for when the requested page of history entries has been received.
  77. /// </summary>
  78. /// <param name="list">Received list of entries.</param>
  79. void OnReceivedHistoryPage(IReadOnlyList<IHistoryEntry> list)
  80. {
  81. RemoveRequest(k_RequestPage);
  82. HistoryListReceived?.Invoke(list);
  83. }
  84. /// <summary>
  85. /// Event handler for when a requested single history entry has been received.
  86. /// </summary>
  87. /// <param name="entry">Received entry.</param>
  88. void OnReceivedHistoryEntry(IHistoryEntry entry)
  89. {
  90. RemoveRequest(k_RequestEntry);
  91. SelectedRevisionReceived?.Invoke(entry);
  92. }
  93. /// <summary>
  94. /// Event handler for when the provider has received an updated history list.
  95. /// </summary>
  96. void OnUpdatedHistoryEntries()
  97. {
  98. HistoryListUpdated?.Invoke();
  99. }
  100. /// <inheritdoc />
  101. public void RequestPageOfRevisions(int pageSize)
  102. {
  103. // Only one request at a time.
  104. if (!AddRequest(k_RequestPage)) return;
  105. SelectedRevisionId = string.Empty;
  106. m_Provider.RequestHistoryPage(PageNumber * pageSize, pageSize, OnReceivedHistoryPage);
  107. }
  108. /// <inheritdoc />
  109. public void RequestSingleRevision(string revisionId)
  110. {
  111. // Only one request at a time.
  112. if (!AddRequest(k_RequestEntry)) return;
  113. SavedRevisionId = string.Empty;
  114. SelectedRevisionId = revisionId;
  115. m_Provider.RequestHistoryEntry(revisionId, OnReceivedHistoryEntry);
  116. }
  117. /// <inheritdoc />
  118. public void RequestEntryNumber()
  119. {
  120. // Only one request at a time.
  121. if (!AddRequest(k_RequestEntryNumber)) return;
  122. m_Provider.RequestHistoryCount(OnReceivedHistoryEntryCount);
  123. }
  124. /// <inheritdoc />
  125. public void RequestUpdateTo(string revisionId)
  126. {
  127. m_Provider.RequestUpdateTo(revisionId);
  128. }
  129. /// <inheritdoc />
  130. public void RequestRestoreTo(string revisionId)
  131. {
  132. m_Provider.RequestRestoreTo(revisionId);
  133. }
  134. /// <inheritdoc />
  135. public void RequestGoBackTo(string revisionId)
  136. {
  137. m_Provider.RequestGoBackTo(revisionId);
  138. }
  139. /// <inheritdoc />
  140. public bool SupportsRevert => m_Provider.SupportsRevert;
  141. /// <inheritdoc />
  142. public void RequestRevert(string revisionId, IReadOnlyList<string> files)
  143. {
  144. m_Provider.RequestRevert(revisionId, files);
  145. }
  146. /// <summary>
  147. /// Add a started request.
  148. /// </summary>
  149. /// <param name="requestId">Id of the request to add.</param>
  150. /// <returns>False if the request already exists.</returns>
  151. bool AddRequest([NotNull] string requestId)
  152. {
  153. if (m_Requests.Contains(requestId)) return false;
  154. m_Requests.Add(requestId);
  155. // Signal background activity if this is the only thing running.
  156. if (m_Requests.Count == 1)
  157. BusyStatusUpdated?.Invoke(true);
  158. return true;
  159. }
  160. /// <summary>
  161. /// Remove a finished request.
  162. /// </summary>
  163. /// <param name="requestId">Id of the request to remove.</param>
  164. void RemoveRequest([NotNull] string requestId)
  165. {
  166. Assert.IsTrue(m_Requests.Contains(requestId), $"Expects request to have first been made for it to have been finished: {requestId}");
  167. m_Requests.Remove(requestId);
  168. // Signal no background activity if no requests in progress
  169. if (m_Requests.Count == 0)
  170. BusyStatusUpdated?.Invoke(false);
  171. }
  172. /// <inheritdoc />
  173. public bool Busy => m_Requests.Count != 0;
  174. /// <inheritdoc />
  175. public int PageNumber { get; set; }
  176. /// <inheritdoc />
  177. public string SelectedRevisionId { get; private set; }
  178. /// <inheritdoc />
  179. public string SavedRevisionId { get; private set; }
  180. /// <inheritdoc />
  181. public bool IsRevisionSelected => !string.IsNullOrEmpty(SelectedRevisionId);
  182. }
  183. }