Sort regions by ordinal position in enumerator
Sukasa opened this issue · 2 comments
The default enumerator code for IEnumerator does not sort the .mcr/.mca files when loading them for enumeration, which means client code cannot assume that chunks will be processed in any specific order.
The following snippets of code are a "fix" for this behaviour, and sort the region filenames to ensure that they are loaded in a coherent order (From -X to +X, and then from -Z to +Z every time X wraps)
The following function is added to the Substrate.Core.RegionManager.Enumerator class:
private int RegionSort(string A, string B)
{
Regex R = new Regex(".+r\\.(?<x>-?\\d+)\\.(?<y>-?\\d+)\\.mca", RegexOptions.None);
Match MC = R.Match(A);
int AX = int.Parse(MC.Groups[1].Value);
int AZ = int.Parse(MC.Groups[2].Value);
MC = R.Match(B);
int BX = int.Parse(MC.Groups[1].Value);
int BZ = int.Parse(MC.Groups[2].Value);
if (AZ < BZ)
return -1;
if (AZ > BZ)
return 1;
if (AX < BX)
return -1;
if (AX > BX)
return 1;
return 0;
}
and the Enumerator (RegionManager rm) function is replaced with this:
public Enumerator (RegionManager rm)
{
_regions = new List<IRegion>();
_pos = -1;
if (!Directory.Exists(rm.GetRegionPath())) {
throw new DirectoryNotFoundException();
}
List<string> Files = new List<string>(Directory.GetFiles(rm.GetRegionPath()));
_regions.Capacity = Files.Count;
Files.Sort(RegionSort);
foreach (string file in Files)
{
try {
IRegion r = rm.GetRegion(file);
_regions.Add(r);
}
catch (ArgumentException) {
continue;
}
}
}
Adding this in would be a benefit as it would allow code that uses Substrate to safely assume that chunks will be loaded in a specific order, and make any corresponding algorithmic optimizations.
I've integrated your code (with a few fixes/changes in the regex handling), and it's now included in the 1.3.8 release.