A game about forced loneliness, made by TACStudios
at master 233 lines 7.3 kB view raw
1using System.Collections.Generic; 2 3using Codice.Client.Commands; 4using Codice.Client.Common; 5using Codice.CM.Common; 6using Codice.Utils; 7using PlasticGui; 8using PlasticGui.Diff; 9using PlasticGui.WorkspaceWindow.Diff; 10 11namespace Unity.PlasticSCM.Editor.Views.Diff 12{ 13 internal class UnityDiffTree 14 { 15 internal UnityDiffTree() 16 { 17 mInnerTree = new DiffTree(); 18 mMetaCache = new MetaCache(); 19 } 20 21 internal void BuildCategories( 22 WorkspaceInfo wkInfo, 23 List<ClientDiff> diffs, 24 BranchResolver brResolver, 25 bool skipMergeTracking) 26 { 27 mInnerTree.BuildCategories( 28 RevisionInfoCodeReviewAdapter.CalculateCodeReviewEntries( 29 wkInfo, 30 diffs, 31 brResolver, 32 skipMergeTracking), 33 brResolver); 34 mMetaCache.Build(mInnerTree.GetNodes()); 35 } 36 37 internal List<IDiffCategory> GetNodes() 38 { 39 return mInnerTree.GetNodes(); 40 } 41 42 internal bool HasMeta(ClientDiffInfo difference) 43 { 44 return mMetaCache.ContainsMeta(difference); 45 } 46 47 internal ClientDiffInfo GetMetaDiff(ClientDiffInfo diff) 48 { 49 return mMetaCache.GetExistingMeta(diff); 50 } 51 52 internal void FillWithMeta(List<ClientDiffInfo> diffs) 53 { 54 diffs.AddRange( 55 mMetaCache.GetExistingMeta(diffs)); 56 } 57 58 internal void Sort(string key, bool sortAscending) 59 { 60 mInnerTree.Sort(key, sortAscending); 61 } 62 63 internal void Filter(Filter filter, List<string> columnNames) 64 { 65 mInnerTree.Filter(filter, columnNames); 66 } 67 68 MetaCache mMetaCache = new MetaCache(); 69 DiffTree mInnerTree; 70 71 class MetaCache 72 { 73 internal void Build(List<IDiffCategory> categories) 74 { 75 mCache.Clear(); 76 77 HashSet<string> indexedKeys = BuildIndexedKeys( 78 GetClientDiffInfos.FromCategories(categories)); 79 80 for (int i = 0; i < categories.Count; i++) 81 { 82 ExtractToMetaCache( 83 (ITreeViewNode)categories[i], 84 i, 85 mCache, 86 indexedKeys); 87 } 88 } 89 90 internal bool ContainsMeta(ClientDiffInfo diff) 91 { 92 return mCache.ContainsKey( 93 BuildKey.ForMetaDiff(diff)); 94 } 95 96 internal ClientDiffInfo GetExistingMeta(ClientDiffInfo diff) 97 { 98 ClientDiffInfo result; 99 100 if (!mCache.TryGetValue(BuildKey.ForMetaDiff(diff), out result)) 101 return null; 102 103 return result; 104 } 105 106 internal List<ClientDiffInfo> GetExistingMeta(List<ClientDiffInfo> diffs) 107 { 108 List<ClientDiffInfo> result = new List<ClientDiffInfo>(); 109 110 foreach (ClientDiffInfo diff in diffs) 111 { 112 string key = BuildKey.ForMetaDiff(diff); 113 114 ClientDiffInfo metaDiff; 115 if (!mCache.TryGetValue(key, out metaDiff)) 116 continue; 117 118 result.Add(metaDiff); 119 } 120 121 return result; 122 } 123 124 static void ExtractToMetaCache( 125 ITreeViewNode node, 126 int nodeIndex, 127 Dictionary<string, ClientDiffInfo> cache, 128 HashSet<string> indexedKeys) 129 { 130 if (node is ClientDiffInfo) 131 { 132 ClientDiffInfo diff = (ClientDiffInfo)node; 133 134 string path = diff.DiffWithMount.Difference.Path; 135 136 if (!MetaPath.IsMetaPath(path)) 137 return; 138 139 string realPath = MetaPath.GetPathFromMetaPath(path); 140 141 if (!indexedKeys.Contains(BuildKey.BuildCacheKey( 142 BuildKey.GetCategoryGroup(diff), 143 BuildKey.GetChangeCategory(diff), 144 realPath))) 145 return; 146 147 // found foo.c and foo.c.meta 148 // with the same chage types - move .meta to cache 149 cache.Add(BuildKey.ForDiff(diff), diff); 150 ((ChangeCategory)node.GetParent()).RemoveDiffAt(nodeIndex); 151 } 152 153 for (int i = node.GetChildrenCount() - 1; i >= 0; i--) 154 { 155 ExtractToMetaCache( 156 node.GetChild(i), 157 i, 158 cache, 159 indexedKeys); 160 } 161 } 162 163 HashSet<string> BuildIndexedKeys(List<ClientDiffInfo> diffs) 164 { 165 HashSet<string> result = new HashSet<string>(); 166 167 foreach (ClientDiffInfo diff in diffs) 168 { 169 if (MetaPath.IsMetaPath(diff.DiffWithMount.Difference.Path)) 170 continue; 171 172 result.Add(BuildKey.ForDiff(diff)); 173 } 174 175 return result; 176 } 177 178 Dictionary<string, ClientDiffInfo> mCache = 179 new Dictionary<string, ClientDiffInfo>(); 180 181 static class BuildKey 182 { 183 internal static string ForDiff( 184 ClientDiffInfo diff) 185 { 186 return BuildCacheKey( 187 GetCategoryGroup(diff), 188 GetChangeCategory(diff), 189 diff.DiffWithMount.Difference.Path); 190 } 191 192 internal static string ForMetaDiff( 193 ClientDiffInfo diff) 194 { 195 return BuildCacheKey( 196 GetCategoryGroup(diff), 197 GetChangeCategory(diff), 198 MetaPath.GetMetaPath(diff.DiffWithMount.Difference.Path)); 199 } 200 201 internal static string BuildCacheKey( 202 CategoryGroup categoryGroup, 203 ChangeCategory changeCategory, 204 string path) 205 { 206 string result = string.Concat(changeCategory.Type, ":", path); 207 208 if (categoryGroup == null) 209 return result; 210 211 return string.Concat(categoryGroup.GetHeaderText(), ":", result); 212 } 213 214 internal static ChangeCategory GetChangeCategory(ClientDiffInfo diff) 215 { 216 return (ChangeCategory)diff.GetParent(); 217 } 218 219 internal static CategoryGroup GetCategoryGroup(ClientDiffInfo diff) 220 { 221 ChangeCategory changeCategory = GetChangeCategory(diff); 222 223 ITreeViewNode categoryGroup = changeCategory.GetParent(); 224 225 if (categoryGroup == null) 226 return null; 227 228 return (CategoryGroup)categoryGroup; 229 } 230 } 231 } 232 } 233}