4 using System.Collections.Generic;
16 private readonly List<Range<int>>? srcRanges;
17 private readonly
int destOffset;
19 public IdRemap(XElement? parentElement,
int offset)
22 if (parentElement is { HasElements:
true })
24 srcRanges =
new List<Range<int>>();
25 foreach (var subElement
in parentElement.Elements())
27 int id = subElement.GetAttributeInt(
"ID", -1);
28 if (
id > 0) { InsertId(
id); }
30 maxId =
GetOffsetId(srcRanges.Any() ? srcRanges.Last().End : offset);
41 result = (ushort)maxId;
44 private void InsertId(
int id)
46 if (srcRanges is
null) {
throw new NullReferenceException(
"Called InsertId when srcRanges is null"); }
48 void tryMergeRangeWithNext(
int indexA)
50 int indexB = indexA + 1;
53 || indexB >= srcRanges.Count )
58 Range<int> rangeA = srcRanges[indexA];
59 Range<int> rangeB = srcRanges[indexB];
61 if ((rangeA.End+1) >= rangeB.Start)
63 srcRanges[indexA] =
new Range<int>(rangeA.Start, rangeB.End);
64 srcRanges.RemoveAt(indexB);
68 int insertIndex = srcRanges.Count;
69 for (
int i = 0; i < srcRanges.Count; i++)
71 if (srcRanges[i].Contains(
id))
73 throw new InvalidOperationException($
"Duplicate ID: {id}");
75 if (srcRanges[i].Start >
id)
81 srcRanges.Insert(insertIndex,
new Range<int>(
id,
id));
82 tryMergeRangeWithNext(insertIndex);
83 tryMergeRangeWithNext(insertIndex - 1);
88 return GetOffsetId(element.GetAttributeInt(
"ID", 0));
101 if (srcRanges is
null)
103 return (ushort)(
id + destOffset);
106 int rangeSize(in Range<int> r)
107 => r.End - r.Start + 1;
109 int currOffset = destOffset;
110 for (
int i = 0; i < srcRanges.Count; i++)
112 if (srcRanges[i].Contains(
id))
118 return (ushort)(
id - srcRanges[i].Start + currOffset);
120 currOffset += rangeSize(srcRanges[i]);
127 int largestEntityId = 0;
131 largestEntityId = Math.Max(largestEntityId, e.
ID);
133 return (ushort)(largestEntityId+1);
const ushort ReservedIDStart
static IReadOnlyCollection< Entity > GetEntities()
readonly ushort ID
Unique, but non-persistent identifier. Stays the same if the entities are created in the exactly same...
ushort GetOffsetId(XElement element)
IdRemap(XElement? parentElement, int offset)
void AssignMaxId(out ushort result)
static ushort DetermineNewOffset()
ushort GetOffsetId(int id)
static readonly IdRemap DiscardId