No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RemoteStatusCache.cs 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections.Generic;
  3. using Codice.Client.BaseCommands;
  4. using Codice.Client.Commands;
  5. using Codice.Client.Common;
  6. using Codice.Client.Common.Threading;
  7. using Codice.Client.GameUI;
  8. using Codice.Client.GameUI.Update;
  9. using Codice.CM.Common;
  10. using Codice.CM.Common.Merge;
  11. using Codice.CM.Common.Mount;
  12. using Codice.CM.Common.Partial;
  13. using Codice.CM.Common.Update.Partial;
  14. using Codice.Utils;
  15. using GluonGui.WorkspaceWindow.Views;
  16. namespace Unity.PlasticSCM.Editor.AssetsOverlays.Cache
  17. {
  18. internal class RemoteStatusCache
  19. {
  20. internal RemoteStatusCache(
  21. WorkspaceInfo wkInfo,
  22. bool isGluonMode,
  23. Action repaintProjectWindow,
  24. Action repaintInspector)
  25. {
  26. mWkInfo = wkInfo;
  27. mIsGluonMode = isGluonMode;
  28. mRepaintProjectWindow = repaintProjectWindow;
  29. mRepaintInspector = repaintInspector;
  30. }
  31. internal AssetStatus GetStatus(string fullPath)
  32. {
  33. if (!mIsGluonMode)
  34. return AssetStatus.UpToDate;
  35. lock(mLock)
  36. {
  37. if (mStatusByPathCache == null)
  38. {
  39. mStatusByPathCache = BuildPathDictionary.ForPlatform<AssetStatus>();
  40. mCurrentCancelToken.Cancel();
  41. mCurrentCancelToken = new CancelToken();
  42. AsyncCalculateStatus(mCurrentCancelToken);
  43. return AssetStatus.UpToDate;
  44. }
  45. AssetStatus result;
  46. if (mStatusByPathCache.TryGetValue(fullPath, out result))
  47. return result;
  48. return AssetStatus.UpToDate;
  49. }
  50. }
  51. internal void Clear()
  52. {
  53. lock (mLock)
  54. {
  55. mCurrentCancelToken.Cancel();
  56. mStatusByPathCache = null;
  57. }
  58. }
  59. void AsyncCalculateStatus(CancelToken cancelToken)
  60. {
  61. Dictionary<string, AssetStatus> statusByPathCache = null;
  62. IThreadWaiter waiter = ThreadWaiter.GetWaiter(50);
  63. waiter.Execute(
  64. /*threadOperationDelegate*/ delegate
  65. {
  66. OutOfDateItems outOfDateItems =
  67. OutOfDateUpdater.CalculateOutOfDateItems(
  68. mWkInfo, new List<ErrorMessage>(),
  69. OutOfDateCalculator.Options.IsIncomingChanges);
  70. if (cancelToken.IsCancelled())
  71. return;
  72. statusByPathCache = BuildStatusByPathCache.
  73. ForOutOfDateItems(outOfDateItems, mWkInfo.ClientPath);
  74. },
  75. /*afterOperationDelegate*/ delegate
  76. {
  77. if (waiter.Exception != null)
  78. {
  79. ExceptionsHandler.LogException(
  80. "RemoteStatusCache",
  81. waiter.Exception);
  82. return;
  83. }
  84. if (cancelToken.IsCancelled())
  85. return;
  86. lock (mLock)
  87. {
  88. mStatusByPathCache = statusByPathCache;
  89. }
  90. mRepaintProjectWindow();
  91. mRepaintInspector();
  92. });
  93. }
  94. static class BuildStatusByPathCache
  95. {
  96. internal static Dictionary<string, AssetStatus> ForOutOfDateItems(
  97. OutOfDateItems outOfDateItems,
  98. string wkPath)
  99. {
  100. Dictionary<string, AssetStatus> result =
  101. BuildPathDictionary.ForPlatform<AssetStatus>();
  102. if (outOfDateItems == null)
  103. return result;
  104. foreach (OutOfDateItemsByMount diffs in
  105. outOfDateItems.GetOutOfDateItemsByMountList(PathHelper.GetPathSorter()))
  106. {
  107. foreach (Difference diff in diffs.Changed)
  108. {
  109. if (diff is DiffXlinkChanged)
  110. continue;
  111. string path = GetPathForDiff(wkPath, diffs.Mount, diff.Path);
  112. result.Add(path, AssetStatus.OutOfDate);
  113. }
  114. foreach (Difference diff in diffs.Deleted)
  115. {
  116. string path = GetPathForDiff(wkPath, diffs.Mount, diff.Path);
  117. result.Add(path, AssetStatus.DeletedOnServer);
  118. }
  119. }
  120. foreach (GluonFileConflict fileConflict in
  121. outOfDateItems.GetFileConflicts())
  122. {
  123. string path = GetPathForConflict(wkPath, fileConflict.CmPath);
  124. result.Add(path, AssetStatus.Conflicted);
  125. }
  126. return result;
  127. }
  128. static string GetPathForDiff(
  129. string wkPath,
  130. MountPointWithPath mountPoint,
  131. string cmSubPath)
  132. {
  133. return WorkspacePath.GetWorkspacePathFromCmPath(
  134. wkPath,
  135. WorkspacePath.ComposeMountPath(mountPoint.MountPath, cmSubPath),
  136. PathHelper.GetDirectorySeparatorChar(wkPath));
  137. }
  138. static string GetPathForConflict(
  139. string wkPath,
  140. string cmPath)
  141. {
  142. return WorkspacePath.GetWorkspacePathFromCmPath(
  143. wkPath, cmPath,
  144. PathHelper.GetDirectorySeparatorChar(wkPath));
  145. }
  146. }
  147. CancelToken mCurrentCancelToken = new CancelToken();
  148. Dictionary<string, AssetStatus> mStatusByPathCache;
  149. readonly Action mRepaintInspector;
  150. readonly Action mRepaintProjectWindow;
  151. readonly bool mIsGluonMode;
  152. readonly WorkspaceInfo mWkInfo;
  153. static object mLock = new object();
  154. }
  155. }