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