ChunkRef enumerators moved into Manager class namespaces; Manager classes now offer enumerators directly.

This commit is contained in:
Justin Aquadro 2011-04-08 20:52:28 +00:00
parent f1c79f6312
commit 0cf047c51d
15 changed files with 245 additions and 422 deletions

View file

@ -97,7 +97,9 @@ namespace NBToolkit
public override void Run ()
{
World world = new World(opt.OPT_WORLD);
ChunkManager cm = world.GetChunkManager() as ChunkManager;
FilteredChunkManager fcm = new FilteredChunkManager(cm, opt.GetChunkFilter());
StreamWriter fstr;
try {
@ -111,7 +113,7 @@ namespace NBToolkit
fstr.WriteLine("[");
bool first = true;
foreach (ChunkRef chunk in new FilteredChunkList(cm, opt.GetChunkFilter())) {
foreach (ChunkRef chunk in fcm) {
if (!first) {
fstr.Write(",");
}

View file

@ -1,116 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Substrate;
namespace NBToolkit
{
public class FilteredChunkList : ChunkList
{
protected IChunkFilter _filter;
public FilteredChunkList (ChunkManager cm, IChunkFilter filter)
: base(cm)
{
_filter = filter;
}
public FilteredChunkList (ChunkManager cm, Region reg, IChunkFilter filter)
: base(cm, reg)
{
_filter = filter;
}
public override ChunkEnumerator GetEnumerator ()
{
return new FilteredChunkEnumerator(_cm, _region, _filter);
}
}
public class FilteredChunkEnumerator : ChunkEnumerator
{
protected IChunkFilter _filter;
public FilteredChunkEnumerator (ChunkManager cm, IChunkFilter filter)
: base(cm)
{
_filter = filter;
}
public FilteredChunkEnumerator (ChunkManager cm, Region reg, IChunkFilter filter)
: base(cm, reg)
{
_filter = filter;
}
public override bool MoveNext ()
{
while (true) {
if (base.MoveNext() == false) {
return false;
}
// Filter by coordinates
if (_filter.InvertXZ) {
if (_filter.XAboveEq != null && _filter.XBelowEq != null &&
_filter.ZAboveEq != null && _filter.ZBelowEq != null &&
Current.X >= _filter.XAboveEq && Current.X <= _filter.XBelowEq &&
Current.Z >= _filter.ZAboveEq && Current.Z <= _filter.ZBelowEq) {
continue;
}
}
else {
if (_filter.XAboveEq != null && Current.X < _filter.XAboveEq) {
continue;
}
if (_filter.XBelowEq != null && Current.X > _filter.XBelowEq) {
continue;
}
if (_filter.ZAboveEq != null && Current.Z < _filter.ZAboveEq) {
continue;
}
if (_filter.ZBelowEq != null && Current.Z > _filter.ZBelowEq) {
continue;
}
}
// Filter out chunks that do not contain required blocks (included list)
if (_filter.IncludedBlockCount > 0) {
int matchCount = 0;
foreach (int block in _filter.IncludedBlocks) {
if (Current.CountBlockID(block) > 0) {
matchCount++;
}
}
if (_filter.IncludeMatchAny && matchCount == 0) {
continue;
}
if (_filter.IncludeMatchAll && matchCount != _filter.IncludedBlockCount) {
continue;
}
}
// Filter out chunks that contain forbiddon blocks (excluded list)
if (_filter.ExcludedBlockCount > 0) {
int matchCount = 0;
foreach (int block in _filter.ExcludedBlocks) {
if (Current.CountBlockID(block) > 0) {
matchCount++;
}
}
if (_filter.ExcludeMatchAny && matchCount > 0) {
continue;
}
if (_filter.ExcludeMatchAll && matchCount == _filter.ExcludedBlockCount) {
continue;
}
}
return true;
}
}
}
}

View file

@ -54,11 +54,12 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Dump.cs" />
<Compile Include="ChunkFilter.cs" />
<Compile Include="FilteredChunkEnumerator.cs" />
<Compile Include="FilteredChunkManager.cs" />
<Compile Include="GenOres.cs" />
<Compile Include="MathHelper.cs" />
<Compile Include="NDesk\Options.cs" />

View file

@ -182,10 +182,12 @@ namespace NBToolkit
public override void Run ()
{
World world = new World(opt.OPT_WORLD);
ChunkManager cm = world.GetChunkManager() as ChunkManager;
FilteredChunkManager fcm = new FilteredChunkManager(cm, opt.GetChunkFilter());
int affectedChunks = 0;
foreach (ChunkRef chunk in new FilteredChunkList(cm, opt.GetChunkFilter())) {
foreach (ChunkRef chunk in fcm) {
if (chunk == null || !chunk.IsTerrainPopulated) {
continue;
}

View file

@ -72,9 +72,10 @@ namespace NBToolkit
World world = new World(opt.OPT_WORLD);
ChunkManager cm = world.GetChunkManager() as ChunkManager;
FilteredChunkManager fcm = new FilteredChunkManager(cm, opt.GetChunkFilter());
int affectedChunks = 0;
foreach (ChunkRef chunk in new FilteredChunkList(cm, opt.GetChunkFilter())) {
foreach (ChunkRef chunk in fcm) {
affectedChunks++;
world.GetChunkManager().DeleteChunk(chunk.X, chunk.Z);
}

View file

@ -152,8 +152,10 @@ namespace NBToolkit
World world = new World(opt.OPT_WORLD);
ChunkManager cm = world.GetChunkManager() as ChunkManager;
FilteredChunkManager fcm = new FilteredChunkManager(cm, opt.GetChunkFilter());
int affectedChunks = 0;
foreach (ChunkRef chunk in new FilteredChunkList(cm, opt.GetChunkFilter())) {
foreach (ChunkRef chunk in fcm) {
affectedChunks++;
ApplyChunk(world, chunk);

View file

@ -73,7 +73,7 @@ namespace NBToolkit
throw new TKOptionException();
}
if (!File.Exists(Path.Combine(OPT_WORLD, "level.dat"))) {
/*if (!File.Exists(Path.Combine(OPT_WORLD, "level.dat"))) {
Console.WriteLine("Error: The supplied world path is invalid");
Console.WriteLine();
this.PrintUsage();
@ -87,7 +87,7 @@ namespace NBToolkit
this.PrintUsage();
throw new TKOptionException();
}
}*/
}
}

View file

@ -1,156 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace Substrate
{
public class ChunkList : IEnumerable<ChunkRef>
{
//private List<Region> _regions;
protected ChunkManager _cm = null;
protected Region _region = null;
// Constructor to enumerate a single region
public ChunkList (ChunkManager cm, Region region)
{
_cm = cm;
_region = region;
}
// Constructor to enumerate all regions
public ChunkList (ChunkManager cm)
{
_cm = cm;
}
IEnumerator IEnumerable.GetEnumerator ()
{
return (IEnumerator)GetEnumerator();
}
IEnumerator<ChunkRef> IEnumerable<ChunkRef>.GetEnumerator ()
{
return (IEnumerator<ChunkRef>)GetEnumerator();
}
public virtual ChunkEnumerator GetEnumerator ()
{
return new ChunkEnumerator(_cm, _region);
}
}
public class ChunkEnumerator : IEnumerator<ChunkRef>
{
protected Region _region;
protected ChunkManager _cm;
protected ChunkRef _chunk;
protected RegionEnumerator _enum = null;
protected int _x = 0;
protected int _z = -1;
public ChunkEnumerator (ChunkManager cm, Region region)
{
_cm = cm;
_region = region;
if (_region == null) {
_enum = new RegionEnumerator(_cm.GetRegionManager());
_enum.MoveNext();
_region = _enum.Current;
}
}
public ChunkEnumerator (ChunkManager cm)
{
_cm = cm;
_enum = new RegionEnumerator(_cm.GetRegionManager());
_enum.MoveNext();
_region = _enum.Current;
}
public virtual bool MoveNext ()
{
if (_enum == null) {
return MoveNextInRegion();
}
else {
while (true) {
if (_x >= ChunkManager.REGION_XLEN) {
if (!_enum.MoveNext()) {
return false;
}
_x = 0;
_z = -1;
_region = _enum.Current;
}
if (MoveNextInRegion()) {
_chunk = _cm.GetChunkRefInRegion(_region, _x, _z);
return true;
}
}
}
}
protected bool MoveNextInRegion ()
{
for (; _x < ChunkManager.REGION_XLEN; _x++) {
for (_z++; _z < ChunkManager.REGION_ZLEN; _z++) {
if (_region.ChunkExists(_x, _z)) {
goto FoundNext;
}
}
_z = -1;
}
FoundNext:
return (_x < ChunkManager.REGION_XLEN);
}
public void Reset ()
{
if (_enum != null) {
_enum.Reset();
_enum.MoveNext();
_region = _enum.Current;
}
_x = 0;
_z = -1;
}
void IDisposable.Dispose () { }
object IEnumerator.Current
{
get
{
return Current;
}
}
ChunkRef IEnumerator<ChunkRef>.Current
{
get
{
return Current;
}
}
public ChunkRef Current
{
get
{
if (_x >= ChunkManager.REGION_XLEN) {
throw new InvalidOperationException();
}
return _chunk;
}
}
}
}

View file

@ -184,5 +184,23 @@ namespace Substrate
#endregion
#region IEnumerable<ChunkRef> Members
public IEnumerator<ChunkRef> GetEnumerator ()
{
return null;
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
{
return null;
}
#endregion
}
}

View file

@ -48,7 +48,7 @@ namespace Substrate
bool SaveChunk (Chunk chunk);
}
public interface IChunkManager : IChunkContainer
public interface IChunkManager : IChunkContainer, IEnumerable<ChunkRef>
{
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace Substrate
{
@ -28,6 +28,13 @@ namespace Substrate
_dirty = new Dictionary<RegionKey, Region>();
}
public ChunkManager (ChunkManager cm)
{
_regionMan = cm._regionMan;
_cache = new Dictionary<RegionKey, Region>();
_dirty = new Dictionary<RegionKey, Region>();
}
public int ChunkGlobalX (int cx)
{
return cx;
@ -170,6 +177,7 @@ namespace Substrate
return _regionMan.GetRegion(cx, cz);
}
#region IEnumerable<ChunkRef> Members
public IEnumerator<ChunkRef> GetEnumerator ()
@ -179,6 +187,7 @@ namespace Substrate
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
@ -187,6 +196,108 @@ namespace Substrate
}
#endregion
public class ChunkEnumerator : IEnumerator<ChunkRef>
{
private ChunkManager _cm;
private IEnumerator<Region> _enum;
private Region _region;
private ChunkRef _chunk;
private int _x = 0;
private int _z = -1;
//protected RegionEnumerator _enum = null;
public ChunkEnumerator (ChunkManager cm)
{
_cm = cm;
_enum = _cm.GetRegionManager().GetEnumerator();
_enum.MoveNext();
_region = _enum.Current;
}
public virtual bool MoveNext ()
{
if (_enum == null) {
return MoveNextInRegion();
}
else {
while (true) {
if (_x >= ChunkManager.REGION_XLEN) {
if (!_enum.MoveNext()) {
return false;
}
_x = 0;
_z = -1;
_region = _enum.Current;
}
if (MoveNextInRegion()) {
_chunk = _cm.GetChunkRefInRegion(_region, _x, _z);
return true;
}
}
}
}
protected bool MoveNextInRegion ()
{
for (; _x < ChunkManager.REGION_XLEN; _x++) {
for (_z++; _z < ChunkManager.REGION_ZLEN; _z++) {
if (_region.ChunkExists(_x, _z)) {
goto FoundNext;
}
}
_z = -1;
}
FoundNext:
return (_x < ChunkManager.REGION_XLEN);
}
public void Reset ()
{
if (_enum != null) {
_enum.Reset();
_enum.MoveNext();
_region = _enum.Current;
}
_x = 0;
_z = -1;
}
void IDisposable.Dispose () { }
object IEnumerator.Current
{
get
{
return Current;
}
}
ChunkRef IEnumerator<ChunkRef>.Current
{
get
{
return Current;
}
}
public ChunkRef Current
{
get
{
if (_x >= ChunkManager.REGION_XLEN) {
throw new InvalidOperationException();
}
return _chunk;
}
}
}
}
public class MissingChunkException : Exception

View file

@ -1,131 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace Substrate
{
public class RegionList : IEnumerable<Region>
{
private List<Region> _regions;
public RegionList (List<Region> regs)
{
_regions = regs;
}
public RegionList (RegionManager rm)
{
_regions = new List<Region>();
if (!Directory.Exists(rm.GetRegionPath())) {
throw new DirectoryNotFoundException();
}
string[] files = Directory.GetFiles(rm.GetRegionPath());
_regions.Capacity = files.Length;
foreach (string file in files) {
try {
Region r = rm.GetRegion(file);
_regions.Add(r);
}
catch (ArgumentException) {
continue;
}
}
}
IEnumerator IEnumerable.GetEnumerator () {
return (IEnumerator)GetEnumerator();
}
IEnumerator<Region> IEnumerable<Region>.GetEnumerator ()
{
return (IEnumerator<Region>)GetEnumerator();
}
public RegionEnumerator GetEnumerator ()
{
return new RegionEnumerator(_regions);
}
}
public class RegionEnumerator : IEnumerator<Region>
{
protected List<Region> _regions;
protected int _pos = -1;
public RegionEnumerator (List<Region> regs)
{
_regions = regs;
}
public RegionEnumerator (RegionManager rm)
{
_regions = new List<Region>();
if (!Directory.Exists(rm.GetRegionPath())) {
throw new DirectoryNotFoundException();
}
string[] files = Directory.GetFiles(rm.GetRegionPath());
_regions.Capacity = files.Length;
foreach (string file in files) {
try {
Region r = rm.GetRegion(file);
_regions.Add(r);
}
catch (ArgumentException) {
continue;
}
}
}
public bool MoveNext ()
{
_pos++;
return (_pos < _regions.Count);
}
public void Reset ()
{
_pos = -1;
}
void IDisposable.Dispose () { }
object IEnumerator.Current
{
get
{
return Current;
}
}
Region IEnumerator<Region>.Current
{
get
{
return Current;
}
}
public Region Current
{
get
{
try {
return _regions[_pos];
}
catch (IndexOutOfRangeException) {
throw new InvalidOperationException();
}
}
}
}
}

View file

@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
namespace Substrate
{
public class RegionManager
public class RegionManager : IEnumerable<Region>
{
protected string _regionPath;
@ -72,5 +72,102 @@ namespace Substrate
return true;
}
#region IEnumerable<Region> Members
public IEnumerator<Region> GetEnumerator ()
{
return new RegionEnumerator(this);
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator ()
{
return new RegionEnumerator(this);
}
#endregion
public class RegionEnumerator : IEnumerator<Region>
{
protected List<Region> _regions;
protected int _pos = -1;
public RegionEnumerator (List<Region> regs)
{
_regions = regs;
}
public RegionEnumerator (RegionManager rm)
{
_regions = new List<Region>();
if (!Directory.Exists(rm.GetRegionPath())) {
throw new DirectoryNotFoundException();
}
string[] files = Directory.GetFiles(rm.GetRegionPath());
_regions.Capacity = files.Length;
foreach (string file in files) {
try {
Region r = rm.GetRegion(file);
_regions.Add(r);
}
catch (ArgumentException) {
continue;
}
}
}
public bool MoveNext ()
{
_pos++;
return (_pos < _regions.Count);
}
public void Reset ()
{
_pos = -1;
}
void IDisposable.Dispose () { }
object IEnumerator.Current
{
get
{
return Current;
}
}
Region IEnumerator<Region>.Current
{
get
{
return Current;
}
}
public Region Current
{
get
{
try {
return _regions[_pos];
}
catch (IndexOutOfRangeException) {
throw new InvalidOperationException();
}
}
}
}
}
}

View file

@ -73,7 +73,6 @@
<Compile Include="Source\BlockManager.cs" />
<Compile Include="Source\BlockRef.cs" />
<Compile Include="Source\Chunk.cs" />
<Compile Include="Source\ChunkEnumerator.cs" />
<Compile Include="Source\ChunkFile.cs" />
<Compile Include="Source\ChunkFileManager.cs" />
<Compile Include="Source\ChunkInterface.cs" />
@ -118,7 +117,6 @@
<Compile Include="Source\NBT\NBTVerifier.cs" />
<Compile Include="Source\Player.cs" />
<Compile Include="Source\Region.cs" />
<Compile Include="Source\RegionEnumerator.cs" />
<Compile Include="Source\RegionFile.cs" />
<Compile Include="Source\RegionKey.cs" />
<Compile Include="Source\RegionManager.cs" />

View file

@ -5,8 +5,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate", "Substrate.cspr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBToolkit", "..\..\NBToolkit\NBToolkit.csproj", "{68207314-C080-4823-97F1-A6623145AA00}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ionic.Zlib", "..\..\Ionic.Zlib\Ionic.Zlib.csproj", "{5A137E43-7E7B-4696-8BFC-844CACAB144B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -21,10 +19,6 @@ Global
{68207314-C080-4823-97F1-A6623145AA00}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68207314-C080-4823-97F1-A6623145AA00}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68207314-C080-4823-97F1-A6623145AA00}.Release|Any CPU.Build.0 = Release|Any CPU
{5A137E43-7E7B-4696-8BFC-844CACAB144B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A137E43-7E7B-4696-8BFC-844CACAB144B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A137E43-7E7B-4696-8BFC-844CACAB144B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A137E43-7E7B-4696-8BFC-844CACAB144B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE