A game about forced loneliness, made by TACStudios
1using System.Collections.Generic;
2
3using PlasticGui;
4using PlasticGui.WorkspaceWindow.Merge;
5
6namespace Unity.PlasticSCM.Editor.Views.Merge.Developer
7{
8 internal class UnityMergeTree
9 {
10 internal static UnityMergeTree BuildMergeCategories(
11 MergeChangesTree tree)
12 {
13 return new UnityMergeTree(tree);
14 }
15
16 UnityMergeTree(
17 MergeChangesTree tree)
18 {
19 mInnerTree = tree;
20
21 mMetaCache.Build(mInnerTree.GetNodes());
22 }
23
24 internal List<MergeChangesCategory> GetNodes()
25 {
26 return mInnerTree.GetNodes();
27 }
28
29 internal bool HasMeta(MergeChangeInfo changeInfo)
30 {
31 return mMetaCache.ContainsMeta(changeInfo);
32 }
33
34 internal MergeChangeInfo GetMetaChange(MergeChangeInfo change)
35 {
36 return mMetaCache.GetExistingMeta(change);
37 }
38
39 internal void FillWithMeta(List<MergeChangeInfo> changes)
40 {
41 changes.AddRange(
42 mMetaCache.GetExistingMeta(changes));
43 }
44
45 internal void Filter(Filter filter, List<string> columnNames)
46 {
47 mInnerTree.Filter(filter, columnNames);
48 }
49
50 internal void Sort(string key, bool isAscending)
51 {
52 mInnerTree.Sort(key, isAscending);
53 }
54
55 internal void ResolveUserNames(
56 MergeChangesTree.ResolveUserName resolveUserName)
57 {
58 mInnerTree.ResolveUserNames(resolveUserName);
59 }
60
61 MetaCache mMetaCache = new MetaCache();
62 MergeChangesTree mInnerTree;
63
64 class MetaCache
65 {
66 internal bool ContainsMeta(MergeChangeInfo changeInfo)
67 {
68 string key = BuildKey.ForMetaChange(changeInfo);
69
70 return mCache.ContainsKey(key);
71 }
72
73 internal MergeChangeInfo GetExistingMeta(MergeChangeInfo change)
74 {
75 MergeChangeInfo result;
76
77 if (!mCache.TryGetValue(BuildKey.ForMetaChange(change), out result))
78 return null;
79
80 return result;
81 }
82
83 internal List<MergeChangeInfo> GetExistingMeta(
84 List<MergeChangeInfo> changes)
85 {
86 List<MergeChangeInfo> result = new List<MergeChangeInfo>();
87
88 foreach (MergeChangeInfo change in changes)
89 {
90 string key = BuildKey.ForMetaChange(change);
91
92 MergeChangeInfo metaChange;
93 if (!mCache.TryGetValue(key, out metaChange))
94 continue;
95
96 result.Add(metaChange);
97 }
98
99 return result;
100 }
101
102 internal void Build(List<MergeChangesCategory> mergeChangesCategories)
103 {
104 mCache.Clear();
105
106 foreach (MergeChangesCategory category in mergeChangesCategories)
107 {
108 ExtractMetaToCache(category, mCache);
109 }
110 }
111
112 static void ExtractMetaToCache(
113 MergeChangesCategory category,
114 Dictionary<string, MergeChangeInfo> cache)
115 {
116 List<MergeChangeInfo> changes = category.GetChanges();
117
118 HashSet<string> indexedKeys = BuildIndexedKeys(
119 changes);
120
121 for (int i = changes.Count - 1; i >= 0; i--)
122 {
123 MergeChangeInfo currentChange = changes[i];
124
125 string path = currentChange.GetPath();
126
127 if (!MetaPath.IsMetaPath(path))
128 continue;
129
130 string realPath = MetaPath.GetPathFromMetaPath(path);
131
132 if (!indexedKeys.Contains(BuildKey.BuildCacheKey(
133 currentChange.CategoryType, realPath)))
134 continue;
135
136 // found foo.c and foo.c.meta - move .meta to cache
137 cache.Add(BuildKey.ForChange(currentChange), currentChange);
138 changes.RemoveAt(i);
139 }
140 }
141
142 static HashSet<string> BuildIndexedKeys(
143 List<MergeChangeInfo> changes)
144 {
145 HashSet<string> result = new HashSet<string>();
146
147 foreach (MergeChangeInfo change in changes)
148 {
149 if (MetaPath.IsMetaPath(change.GetPath()))
150 continue;
151
152 result.Add(BuildKey.ForChange(change));
153 }
154
155 return result;
156 }
157
158 Dictionary<string, MergeChangeInfo> mCache =
159 new Dictionary<string, MergeChangeInfo>();
160
161 static class BuildKey
162 {
163 internal static string ForChange(
164 MergeChangeInfo change)
165 {
166 return BuildCacheKey(
167 change.CategoryType,
168 change.GetPath());
169 }
170
171 internal static string ForMetaChange(
172 MergeChangeInfo change)
173 {
174 return BuildCacheKey(
175 change.CategoryType,
176 MetaPath.GetMetaPath(change.GetPath()));
177 }
178
179 internal static string BuildCacheKey(
180 MergeChangesCategory.Type type,
181 string path)
182 {
183 return string.Concat(type, ":", path);
184 }
185 }
186 }
187 }
188}