A game about forced loneliness, made by TACStudios
1using System; 2using System.Collections.Generic; 3 4using Codice; 5using Codice.Client.Commands; 6using Codice.Client.Commands.WkTree; 7using Codice.Client.Common; 8using Codice.Client.Common.Locks; 9using Codice.Client.Common.Threading; 10using Codice.Client.Common.WkTree; 11using Codice.CM.Common; 12using Codice.CM.Common.Mount; 13using Codice.Utils; 14using PlasticGui.WorkspaceWindow; 15using PlasticGui.WorkspaceWindow.Items.Locks; 16 17namespace Unity.PlasticSCM.Editor.AssetsOverlays.Cache 18{ 19 internal class LockStatusCache 20 { 21 internal LockStatusCache( 22 WorkspaceInfo wkInfo, 23 Action repaintProjectWindow, 24 Action repaintInspector) 25 { 26 mWkInfo = wkInfo; 27 mRepaintProjectWindow = repaintProjectWindow; 28 mRepaintInspector = repaintInspector; 29 } 30 31 internal AssetStatus GetStatus(string fullPath) 32 { 33 LockStatusData lockStatusData = GetLockStatusData(fullPath); 34 35 if (lockStatusData == null) 36 return AssetStatus.None; 37 38 return lockStatusData.Status; 39 } 40 41 internal LockStatusData GetLockStatusData(string fullPath) 42 { 43 lock (mLock) 44 { 45 if (mStatusByPathCache == null) 46 { 47 mStatusByPathCache = BuildPathDictionary.ForPlatform<LockStatusData>(); 48 49 mCurrentCancelToken.Cancel(); 50 mCurrentCancelToken = new CancelToken(); 51 AsyncCalculateStatus(mCurrentCancelToken); 52 53 return null; 54 } 55 56 LockStatusData result; 57 58 if (mStatusByPathCache.TryGetValue(fullPath, out result)) 59 return result; 60 61 return null; 62 } 63 } 64 65 internal void Clear() 66 { 67 lock (mLock) 68 { 69 mCurrentCancelToken.Cancel(); 70 71 mStatusByPathCache = null; 72 } 73 } 74 75 internal void Cancel() 76 { 77 lock (mLock) 78 { 79 mCurrentCancelToken.Cancel(); 80 } 81 } 82 83 void AsyncCalculateStatus(CancelToken cancelToken) 84 { 85 Dictionary<string, LockStatusData> statusByPathCache = null; 86 87 IThreadWaiter waiter = ThreadWaiter.GetWaiter(50); 88 waiter.Execute( 89 /*threadOperationDelegate*/ delegate 90 { 91 Dictionary<MountPointWithPath, List<WorkspaceTreeNode>> lockCandidates = 92 new Dictionary<MountPointWithPath, List<WorkspaceTreeNode>>(); 93 94 FillLockCandidates.ForTree(mWkInfo, lockCandidates); 95 96 if (cancelToken.IsCancelled()) 97 return; 98 99 Dictionary<WorkspaceTreeNode, LockInfo> lockInfoByNode = 100 SearchLocks.GetLocksInfo(mWkInfo, lockCandidates); 101 102 if (cancelToken.IsCancelled()) 103 return; 104 105 statusByPathCache = BuildStatusByNodeCache. 106 ForLocks(mWkInfo.ClientPath, lockInfoByNode); 107 }, 108 /*afterOperationDelegate*/ delegate 109 { 110 if (cancelToken.IsCancelled()) 111 return; 112 113 if (waiter.Exception != null) 114 { 115 ExceptionsHandler.LogException( 116 "LockStatusCache", 117 waiter.Exception); 118 return; 119 } 120 121 lock (mLock) 122 { 123 mStatusByPathCache = statusByPathCache; 124 } 125 126 mRepaintProjectWindow(); 127 mRepaintInspector(); 128 }); 129 } 130 131 static class BuildStatusByNodeCache 132 { 133 internal static Dictionary<string, LockStatusData> ForLocks( 134 string wkPath, 135 Dictionary<WorkspaceTreeNode, LockInfo> lockInfoByNode) 136 { 137 Dictionary<string, LockStatusData> result = 138 BuildPathDictionary.ForPlatform<LockStatusData>(); 139 140 LockOwnerNameResolver nameResolver = new LockOwnerNameResolver(); 141 142 foreach (WorkspaceTreeNode node in lockInfoByNode.Keys) 143 { 144 LockStatusData lockStatusData = BuildLockStatusData( 145 node, lockInfoByNode[node], nameResolver); 146 147 string nodeWkPath = WorkspacePath.GetWorkspacePathFromCmPath( 148 wkPath, 149 WorkspaceNodeOperations.GetCmPath(node), 150 PathHelper.GetDirectorySeparatorChar(wkPath)); 151 152 result.Add(nodeWkPath, lockStatusData); 153 } 154 155 return result; 156 } 157 158 static LockStatusData BuildLockStatusData( 159 WorkspaceTreeNode node, 160 LockInfo lockInfo, 161 LockOwnerNameResolver nameResolver) 162 { 163 return new LockStatusData( 164 GetAssetStatus(node, lockInfo), 165 nameResolver.GetSeidName(lockInfo.SEIDData), 166 BranchInfoCache.GetProtectedBranchName( 167 node.RepSpec, lockInfo.HolderBranchId)); 168 } 169 170 static AssetStatus GetAssetStatus( 171 WorkspaceTreeNode node, 172 LockInfo lockInfo) 173 { 174 if (lockInfo.Status == LockInfo.LockStatus.Retained) 175 return AssetStatus.Retained; 176 177 return CheckWorkspaceTreeNodeStatus.IsCheckedOut(node) ? 178 AssetStatus.Locked : AssetStatus.LockedRemote; 179 } 180 } 181 182 CancelToken mCurrentCancelToken = new CancelToken(); 183 184 Dictionary<string, LockStatusData> mStatusByPathCache; 185 186 readonly Action mRepaintInspector; 187 readonly Action mRepaintProjectWindow; 188 readonly WorkspaceInfo mWkInfo; 189 190 static object mLock = new object(); 191 } 192}