182 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			182 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System.Collections.Generic; | ||
|  | 
 | ||
|  | using Codice.Client.Common; | ||
|  | using Codice.Client.Common.Threading; | ||
|  | using Codice.CM.Common; | ||
|  | using Codice.CM.Common.Merge; | ||
|  | using Codice.CM.Common.Mount; | ||
|  | using Codice.CM.Common.Partial; | ||
|  | using Codice.CM.Common.Update.Partial; | ||
|  | using Codice.Utils; | ||
|  | using GluonGui.WorkspaceWindow.Views; | ||
|  | using Unity.PlasticSCM.Editor.AssetUtils; | ||
|  | 
 | ||
|  | namespace Unity.PlasticSCM.Editor.AssetsOverlays.Cache | ||
|  | { | ||
|  |     internal class RemoteStatusCache | ||
|  |     { | ||
|  |         internal RemoteStatusCache( | ||
|  |             WorkspaceInfo wkInfo, | ||
|  |             bool isGluonMode) | ||
|  |         { | ||
|  |             mWkInfo = wkInfo; | ||
|  |             mIsGluonMode = isGluonMode; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal AssetStatus GetStatus(string fullPath) | ||
|  |         { | ||
|  |             if (!mIsGluonMode) | ||
|  |                 return AssetStatus.UpToDate; | ||
|  | 
 | ||
|  |             lock(mLock) | ||
|  |             { | ||
|  |                 if (mStatusByPathCache == null) | ||
|  |                 { | ||
|  |                     mStatusByPathCache = BuildPathDictionary.ForPlatform<AssetStatus>(); | ||
|  | 
 | ||
|  |                     mCurrentCancelToken.Cancel(); | ||
|  |                     mCurrentCancelToken = new CancelToken(); | ||
|  |                     AsyncCalculateStatus(mCurrentCancelToken); | ||
|  | 
 | ||
|  |                     return AssetStatus.UpToDate; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 AssetStatus result; | ||
|  |                 if (mStatusByPathCache.TryGetValue(fullPath, out result)) | ||
|  |                     return result; | ||
|  | 
 | ||
|  |                 return AssetStatus.UpToDate; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void Clear() | ||
|  |         { | ||
|  |             lock (mLock) | ||
|  |             { | ||
|  |                 mCurrentCancelToken.Cancel(); | ||
|  |                 mStatusByPathCache = null; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void Cancel() | ||
|  |         { | ||
|  |             lock (mLock) | ||
|  |             { | ||
|  |                 mCurrentCancelToken.Cancel(); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         void AsyncCalculateStatus(CancelToken cancelToken) | ||
|  |         { | ||
|  |             Dictionary<string, AssetStatus> statusByPathCache = null; | ||
|  | 
 | ||
|  |             IThreadWaiter waiter = ThreadWaiter.GetWaiter(50); | ||
|  |             waiter.Execute( | ||
|  |                 /*threadOperationDelegate*/ delegate | ||
|  |                 { | ||
|  |                     OutOfDateItems outOfDateItems = | ||
|  |                         OutOfDateUpdater.CalculateOutOfDateItems( | ||
|  |                             mWkInfo, new List<ErrorMessage>(), | ||
|  |                             OutOfDateCalculator.Options.IsIncomingChanges); | ||
|  | 
 | ||
|  |                     if (cancelToken.IsCancelled()) | ||
|  |                         return; | ||
|  | 
 | ||
|  |                     statusByPathCache = BuildStatusByPathCache. | ||
|  |                         ForOutOfDateItems(outOfDateItems, mWkInfo.ClientPath); | ||
|  |                 }, | ||
|  |                 /*afterOperationDelegate*/ delegate | ||
|  |                 { | ||
|  |                     if (cancelToken.IsCancelled()) | ||
|  |                         return; | ||
|  | 
 | ||
|  |                     if (waiter.Exception != null) | ||
|  |                     { | ||
|  |                         ExceptionsHandler.LogException( | ||
|  |                             "RemoteStatusCache", | ||
|  |                             waiter.Exception); | ||
|  |                         return; | ||
|  |                     } | ||
|  | 
 | ||
|  |                     lock (mLock) | ||
|  |                     { | ||
|  |                         mStatusByPathCache = statusByPathCache; | ||
|  |                     } | ||
|  | 
 | ||
|  |                     RepaintEditor.AllWindowsWithOverlays(); | ||
|  |                 }); | ||
|  |         } | ||
|  | 
 | ||
|  |         static class BuildStatusByPathCache | ||
|  |         { | ||
|  |             internal static Dictionary<string, AssetStatus> ForOutOfDateItems( | ||
|  |                 OutOfDateItems outOfDateItems, | ||
|  |                 string wkPath) | ||
|  |             { | ||
|  |                 Dictionary<string, AssetStatus> result = | ||
|  |                     BuildPathDictionary.ForPlatform<AssetStatus>(); | ||
|  | 
 | ||
|  |                 if (outOfDateItems == null) | ||
|  |                     return result; | ||
|  | 
 | ||
|  |                 foreach (OutOfDateItemsByMount diffs in | ||
|  |                     outOfDateItems.GetOutOfDateItemsByMountList(PathHelper.GetPathSorter())) | ||
|  |                 { | ||
|  |                     foreach (Difference diff in diffs.Changed) | ||
|  |                     { | ||
|  |                         if (diff is DiffXlinkChanged) | ||
|  |                             continue; | ||
|  | 
 | ||
|  |                         string path = GetPathForDiff(wkPath, diffs.Mount, diff.Path); | ||
|  |                         result.Add(path, AssetStatus.OutOfDate); | ||
|  |                     } | ||
|  | 
 | ||
|  |                     foreach (Difference diff in diffs.Deleted) | ||
|  |                     { | ||
|  |                         string path = GetPathForDiff(wkPath, diffs.Mount, diff.Path); | ||
|  |                         result.Add(path, AssetStatus.DeletedOnServer); | ||
|  |                     } | ||
|  |                 } | ||
|  | 
 | ||
|  |                 foreach (GluonFileConflict fileConflict in | ||
|  |                     outOfDateItems.GetFileConflicts()) | ||
|  |                 { | ||
|  |                     string path = GetPathForConflict(wkPath, fileConflict.CmPath); | ||
|  |                     result.Add(path, AssetStatus.Conflicted); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 return result; | ||
|  |             } | ||
|  | 
 | ||
|  |             static string GetPathForDiff( | ||
|  |                 string wkPath, | ||
|  |                 MountPointWithPath mountPoint, | ||
|  |                 string cmSubPath) | ||
|  |             { | ||
|  |                 return WorkspacePath.GetWorkspacePathFromCmPath( | ||
|  |                     wkPath, | ||
|  |                     WorkspacePath.ComposeMountPath(mountPoint.MountPath, cmSubPath), | ||
|  |                     PathHelper.GetDirectorySeparatorChar(wkPath)); | ||
|  |             } | ||
|  | 
 | ||
|  |             static string GetPathForConflict( | ||
|  |                 string wkPath, | ||
|  |                 string cmPath) | ||
|  |             { | ||
|  |                 return WorkspacePath.GetWorkspacePathFromCmPath( | ||
|  |                     wkPath, cmPath, | ||
|  |                     PathHelper.GetDirectorySeparatorChar(wkPath)); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         CancelToken mCurrentCancelToken = new CancelToken(); | ||
|  | 
 | ||
|  |         Dictionary<string, AssetStatus> mStatusByPathCache; | ||
|  | 
 | ||
|  |         readonly bool mIsGluonMode; | ||
|  |         readonly WorkspaceInfo mWkInfo; | ||
|  | 
 | ||
|  |         static object mLock = new object(); | ||
|  |     } | ||
|  | } |