Skip to content

Commit f0b62cb

Browse files
committed
Compound sorting
1 parent 31ed61f commit f0b62cb

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

fNbt/Tags/NbtCompound.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,98 @@ public bool Contains([NotNull] string tagName) {
197197
return tags.ContainsKey(tagName);
198198
}
199199

200+
public void Sort(IComparer<NbtTag> sorter, bool recursive)
201+
{
202+
if (recursive)
203+
{
204+
var restore_sort = (NbtCompound)this.Clone();
205+
PerformAction(new DescriptionHolder("Sort {0}", this),
206+
() => { DoSort(sorter, true); },
207+
() => { DoUnsortRecursive(restore_sort); }
208+
);
209+
}
210+
else
211+
{
212+
var restore_sort = this.Tags.ToList();
213+
PerformAction(new DescriptionHolder("Sort {0}", this),
214+
() => { DoSort(sorter, false); },
215+
() => { DoUnsortRoot(restore_sort); }
216+
);
217+
}
218+
}
219+
220+
private void DoUnsortRecursive(NbtCompound reference)
221+
{
222+
var order = Tags.OrderBy(x => reference.IndexOf(x.Name)).ToList();
223+
foreach (var tag in order)
224+
{
225+
if (tag is NbtCompound sub)
226+
sub.DoUnsortRecursive((NbtCompound)reference[tag.Name]);
227+
else if (tag is NbtList list)
228+
UnsortListChildren(list, (NbtList)reference[tag.Name]);
229+
}
230+
DoUnsortRoot(order);
231+
}
232+
233+
private static void UnsortListChildren(NbtList list, NbtList reference)
234+
{
235+
if (list.ListType == NbtTagType.Compound)
236+
{
237+
for (int i = 0; i < list.Count; i++)
238+
{
239+
((NbtCompound)list[i]).DoUnsortRecursive((NbtCompound)reference[i]);
240+
}
241+
}
242+
else if (list.ListType == NbtTagType.List)
243+
{
244+
for (int i = 0; i < list.Count; i++)
245+
{
246+
UnsortListChildren((NbtList)list[i], (NbtList)reference[i]);
247+
}
248+
}
249+
}
250+
251+
private void DoUnsortRoot(List<NbtTag> order)
252+
{
253+
DoClear();
254+
DoAddRange(order);
255+
}
256+
257+
private void DoSort(IComparer<NbtTag> sorter, bool recursive)
258+
{
259+
var tags = Tags.OrderBy(x => x, sorter).ToList();
260+
foreach (var tag in tags)
261+
{
262+
if (recursive)
263+
{
264+
if (tag is NbtCompound sub)
265+
sub.DoSort(sorter, true);
266+
else if (tag is NbtList list)
267+
SortListChildren(list, sorter);
268+
}
269+
}
270+
DoClear();
271+
DoAddRange(tags);
272+
}
273+
274+
private static void SortListChildren(NbtList list, IComparer<NbtTag> sorter)
275+
{
276+
if (list.ListType == NbtTagType.Compound)
277+
{
278+
foreach (NbtCompound item in list)
279+
{
280+
item.DoSort(sorter, true);
281+
}
282+
}
283+
else if (list.ListType == NbtTagType.List)
284+
{
285+
foreach (NbtList item in list)
286+
{
287+
SortListChildren(item, sorter);
288+
}
289+
}
290+
}
291+
200292

201293
/// <summary> Removes the tag with the specified name from this NbtCompound. </summary>
202294
/// <param name="tagName"> The name of the tag to remove. </param>

0 commit comments

Comments
 (0)