123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- using System;
- using System.Collections.Generic;
- using System.IO;
-
- using Codice;
- using Codice.Client.Commands;
- using Codice.Client.Commands.Mount;
- using Codice.Client.Commands.WkTree;
- using Codice.Client.Common;
- using Codice.Client.Common.Locks;
- using Codice.Client.Common.Threading;
- using Codice.Client.Common.WkTree;
- using Codice.CM.Common;
- using Codice.Utils;
- using PlasticGui.WorkspaceWindow;
-
- namespace Unity.PlasticSCM.Editor.AssetsOverlays.Cache
- {
- internal class LockStatusCache
- {
- internal LockStatusCache(
- WorkspaceInfo wkInfo,
- Action repaintProjectWindow,
- Action repaintInspector)
- {
- mWkInfo = wkInfo;
- mRepaintProjectWindow = repaintProjectWindow;
- mRepaintInspector = repaintInspector;
- }
-
- internal AssetStatus GetStatus(string fullPath)
- {
- LockStatusData lockStatusData = GetLockStatusData(fullPath);
-
- if (lockStatusData == null)
- return AssetStatus.None;
-
- return lockStatusData.Status;
- }
-
- internal LockStatusData GetLockStatusData(string fullPath)
- {
- lock (mLock)
- {
- if (mStatusByPathCache == null)
- {
- mStatusByPathCache = BuildPathDictionary.ForPlatform<LockStatusData>();
-
- mCurrentCancelToken.Cancel();
- mCurrentCancelToken = new CancelToken();
- AsyncCalculateStatus(mCurrentCancelToken);
-
- return null;
- }
-
- LockStatusData result;
-
- if (mStatusByPathCache.TryGetValue(fullPath, out result))
- return result;
-
- return null;
- }
- }
-
- internal void Clear()
- {
- lock (mLock)
- {
- mCurrentCancelToken.Cancel();
-
- mStatusByPathCache = null;
- }
- }
-
- void AsyncCalculateStatus(CancelToken cancelToken)
- {
- Dictionary<string, LockStatusData> statusByPathCache = null;
-
- IThreadWaiter waiter = ThreadWaiter.GetWaiter(50);
- waiter.Execute(
- /*threadOperationDelegate*/ delegate
- {
- Dictionary<MountPointWithPath, List<WorkspaceTreeNode>> lockCandidates =
- new Dictionary<MountPointWithPath, List<WorkspaceTreeNode>>();
-
- FillLockCandidates.ForTree(mWkInfo, lockCandidates);
-
- if (cancelToken.IsCancelled())
- return;
-
- Dictionary<WorkspaceTreeNode, LockInfo> lockInfoByNode =
- SearchLocks.GetLocksInfo(mWkInfo, lockCandidates);
-
- if (cancelToken.IsCancelled())
- return;
-
- statusByPathCache = BuildStatusByNodeCache.
- ForLocks(mWkInfo.ClientPath, lockInfoByNode);
- },
- /*afterOperationDelegate*/ delegate
- {
- if (waiter.Exception != null)
- {
- ExceptionsHandler.LogException(
- "LockStatusCache",
- waiter.Exception);
- return;
- }
-
- if (cancelToken.IsCancelled())
- return;
-
- lock (mLock)
- {
- mStatusByPathCache = statusByPathCache;
- }
-
- mRepaintProjectWindow();
- mRepaintInspector();
- });
- }
-
- static class FillLockCandidates
- {
- internal static void ForTree(
- WorkspaceInfo wkInfo,
- Dictionary<MountPointWithPath, List<WorkspaceTreeNode>> lockCandidates)
- {
- WorkspaceTreeNode rootNode = CmConnection.Get().GetWorkspaceTreeHandler().
- GetWorkspaceTree(wkInfo, wkInfo.ClientPath, true);
-
- Queue<NodeWithPath> pendingDirectories = new Queue<NodeWithPath>();
- pendingDirectories.Enqueue(new NodeWithPath(
- MountPointWithPath.BuildWorkspaceRootMountPoint(rootNode.RepSpec),
- rootNode, wkInfo.ClientPath));
-
- while (pendingDirectories.Count > 0)
- {
- NodeWithPath directoryNode = pendingDirectories.Dequeue();
-
- ForChildren(
- wkInfo.ClientPath,
- directoryNode.Mount,
- directoryNode.Path,
- directoryNode.Node,
- pendingDirectories,
- lockCandidates);
- }
- }
-
- static void ForChildren(
- string wkPath,
- MountPointWithPath parentMount,
- string dirPath,
- WorkspaceTreeNode dirNode,
- Queue<NodeWithPath> pendingDirectories,
- Dictionary<MountPointWithPath, List<WorkspaceTreeNode>> lockCandidates)
- {
- if (!dirNode.HasChildren)
- return;
-
- foreach (WorkspaceTreeNode child in dirNode.Children)
- {
- string childPath = Path.Combine(dirPath, child.Name);
-
- if (CheckWorkspaceTreeNodeStatus.IsDirectory(child))
- {
- MountPointWithPath mount = XlinkWorkspaceTreeNode.IsXlinkWkNode(child) ?
- new MountPointWithPath(
- MountPointId.BuildForXlink(
- ((XlinkWorkspaceTreeNode)child).Xlink.GUID, parentMount.Id),
- child.RepSpec,
- WorkspacePath.CmPathFromWorkspacePath(childPath, wkPath)) :
- parentMount;
-
- pendingDirectories.Enqueue(
- new NodeWithPath(mount, child, childPath));
- continue;
- }
-
- if (CheckWorkspaceTreeNodeStatus.IsAdded(child))
- continue;
-
- List<WorkspaceTreeNode> nodes = null;
- if (!lockCandidates.TryGetValue(parentMount, out nodes))
- {
- nodes = new List<WorkspaceTreeNode>();
- lockCandidates.Add(parentMount, nodes);
- }
-
- nodes.Add(child);
- }
- }
-
- class NodeWithPath
- {
- internal readonly MountPointWithPath Mount;
- internal readonly WorkspaceTreeNode Node;
- internal readonly string Path;
- internal NodeWithPath(
- MountPointWithPath mount,
- WorkspaceTreeNode node,
- string path)
- {
- Mount = mount;
- Node = node;
- Path = path;
- }
- }
- }
-
- static class BuildStatusByNodeCache
- {
- internal static Dictionary<string, LockStatusData> ForLocks(
- string wkPath,
- Dictionary<WorkspaceTreeNode, LockInfo> lockInfoByNode)
- {
- Dictionary<string, LockStatusData> result =
- BuildPathDictionary.ForPlatform<LockStatusData>();
-
- LockOwnerNameResolver nameResolver = new LockOwnerNameResolver();
-
- foreach (WorkspaceTreeNode node in lockInfoByNode.Keys)
- {
- LockStatusData lockStatusData = BuildLockStatusData(
- node, lockInfoByNode[node], nameResolver);
-
- string nodeWkPath = WorkspacePath.GetWorkspacePathFromCmPath(
- wkPath,
- WorkspaceNodeOperations.GetCmPath(node),
- PathHelper.GetDirectorySeparatorChar(wkPath));
-
- result.Add(nodeWkPath, lockStatusData);
- }
-
- return result;
- }
-
- static LockStatusData BuildLockStatusData(
- WorkspaceTreeNode node,
- LockInfo lockInfo,
- LockOwnerNameResolver nameResolver)
- {
- return new LockStatusData(
- GetAssetStatus(node, lockInfo),
- nameResolver.GetSeidName(lockInfo.SEIDData),
- BranchInfoCache.GetProtectedBranchName(
- node.RepSpec, lockInfo.HolderBranchId));
- }
-
- static AssetStatus GetAssetStatus(
- WorkspaceTreeNode node,
- LockInfo lockInfo)
- {
- if (lockInfo.Status == LockInfo.LockStatus.Retained)
- return AssetStatus.Retained;
-
- return CheckWorkspaceTreeNodeStatus.IsCheckedOut(node) ?
- AssetStatus.Locked : AssetStatus.LockedRemote;
- }
- }
-
- CancelToken mCurrentCancelToken = new CancelToken();
-
- Dictionary<string, LockStatusData> mStatusByPathCache;
-
- readonly Action mRepaintInspector;
- readonly Action mRepaintProjectWindow;
- readonly WorkspaceInfo mWkInfo;
-
- static object mLock = new object();
- }
- }
|