ChunkRef switched to factory method to fix performance defect

This commit is contained in:
Justin Aquadro 2011-04-19 01:24:26 +00:00
parent 324d997f52
commit 9355a016ca
6 changed files with 44 additions and 30 deletions

View file

@ -66,6 +66,11 @@ namespace Substrate
bool SetBlockLight (int x, int y, int z, int light); bool SetBlockLight (int x, int y, int z, int light);
bool SetBlockSkyLight (int x, int y, int z, int light); bool SetBlockSkyLight (int x, int y, int z, int light);
//---
//void ResetBlockLight ();
//void ResetSkyLight ();
} }
public interface IPropertyBlockContainer : IBlockContainer public interface IPropertyBlockContainer : IBlockContainer

View file

@ -113,14 +113,12 @@ namespace Substrate
return c; return c;
} }
try { c = ChunkRef.Create(this, this, cx, cz);
c = new ChunkRef(this, this, cx, cz); if (c != null) {
_cache[k].Target = c; _cache[k].Target = c;
return c;
}
catch (MissingChunkException) {
return null;
} }
return c;
} }
public ChunkRef CreateChunk (int cx, int cz) public ChunkRef CreateChunk (int cx, int cz)
@ -129,7 +127,7 @@ namespace Substrate
Chunk c = new Chunk(cx, cz); Chunk c = new Chunk(cx, cz);
c.Save(GetChunkOutStream(cx, cz)); c.Save(GetChunkOutStream(cx, cz));
ChunkRef cr = new ChunkRef(this, this, cx, cz); ChunkRef cr = ChunkRef.Create(this, this, cx, cz);
ChunkKey k = new ChunkKey(cx, cz); ChunkKey k = new ChunkKey(cx, cz);
_cache[k] = new WeakReference(cr); _cache[k] = new WeakReference(cr);

View file

@ -181,44 +181,47 @@ namespace Substrate
public void RelightDirtyChunks () public void RelightDirtyChunks ()
{ {
List<ChunkRef> dirty = new List<ChunkRef>(); //List<ChunkRef> dirty = new List<ChunkRef>();
Dictionary<ChunkKey, ChunkRef> dirty = new Dictionary<ChunkKey, ChunkRef>();
IEnumerator<ChunkRef> en = _cache.GetDirtyEnumerator(); IEnumerator<ChunkRef> en = _cache.GetDirtyEnumerator();
while (en.MoveNext()) { while (en.MoveNext()) {
dirty.Add(en.Current); ChunkKey key = new ChunkKey(en.Current.X, en.Current.Z);
dirty[key] = en.Current;
} }
foreach (ChunkRef chunk in dirty) { foreach (ChunkRef chunk in dirty.Values) {
chunk.ResetBlockLight(); chunk.ResetBlockLight();
chunk.ResetSkyLight(); chunk.ResetSkyLight();
} }
foreach (ChunkRef chunk in dirty) { foreach (ChunkRef chunk in dirty.Values) {
chunk.RebuildBlockLight(); chunk.RebuildBlockLight();
chunk.RebuildSkyLight(); chunk.RebuildSkyLight();
} }
foreach (ChunkRef chunk in dirty) { foreach (ChunkRef chunk in dirty.Values) {
ChunkRef east = chunk.GetEastNeighbor();
if (!east.IsDirty) { if (!dirty.ContainsKey(new ChunkKey(chunk.X, chunk.Z - 1))) {
ChunkRef east = chunk.GetEastNeighbor();
chunk.UpdateEdgeBlockLight(east); chunk.UpdateEdgeBlockLight(east);
chunk.UpdateEdgeSkyLight(east); chunk.UpdateEdgeSkyLight(east);
} }
ChunkRef west = chunk.GetWestNeighbor(); if (!dirty.ContainsKey(new ChunkKey(chunk.X, chunk.Z + 1))) {
if (!west.IsDirty) { ChunkRef west = chunk.GetWestNeighbor();
chunk.UpdateEdgeBlockLight(west); chunk.UpdateEdgeBlockLight(west);
chunk.UpdateEdgeSkyLight(west); chunk.UpdateEdgeSkyLight(west);
} }
ChunkRef north = chunk.GetNorthNeighbor(); if (!dirty.ContainsKey(new ChunkKey(chunk.X - 1, chunk.Z))) {
if (!north.IsDirty) { ChunkRef north = chunk.GetNorthNeighbor();
chunk.UpdateEdgeBlockLight(north); chunk.UpdateEdgeBlockLight(north);
chunk.UpdateEdgeSkyLight(north); chunk.UpdateEdgeSkyLight(north);
} }
ChunkRef south = chunk.GetSouthNeighbor(); if (!dirty.ContainsKey(new ChunkKey(chunk.X + 1, chunk.Z))) {
if (!south.IsDirty) { ChunkRef south = chunk.GetSouthNeighbor();
chunk.UpdateEdgeBlockLight(south); chunk.UpdateEdgeBlockLight(south);
chunk.UpdateEdgeSkyLight(south); chunk.UpdateEdgeSkyLight(south);
} }

View file

@ -52,16 +52,21 @@ namespace Substrate
get { return _dirty; } get { return _dirty; }
} }
public ChunkRef (IChunkContainer container, IChunkCache cache, int cx, int cz) private ChunkRef (IChunkContainer container, IChunkCache cache, int cx, int cz)
{ {
_container = container; _container = container;
_cache = cache; _cache = cache;
_cx = cx; _cx = cx;
_cz = cz; _cz = cz;
}
if (!_container.ChunkExists(cx, cz)) { public static ChunkRef Create (IChunkContainer container, IChunkCache cache, int cx, int cz)
throw new MissingChunkException(); {
if (!container.ChunkExists(cx, cz)) {
return null;
} }
return new ChunkRef(container, cache, cx, cz);
} }
public int BlockGlobalX (int x) public int BlockGlobalX (int x)

View file

@ -237,14 +237,12 @@ namespace Substrate
return c; return c;
} }
try { c = ChunkRef.Create(this, _cache, lcx, lcz);
c = new ChunkRef(this, _cache, lcx, lcz); if (c != null) {
_cache.Insert(c); _cache.Insert(c);
return c;
}
catch (MissingChunkException) {
return null;
} }
return c;
} }
public ChunkRef CreateChunk (int lcx, int lcz) public ChunkRef CreateChunk (int lcx, int lcz)
@ -262,7 +260,7 @@ namespace Substrate
Chunk c = new Chunk(cx, cz); Chunk c = new Chunk(cx, cz);
c.Save(GetChunkOutStream(lcx, lcz)); c.Save(GetChunkOutStream(lcx, lcz));
ChunkRef cr = new ChunkRef(this, _cache, lcx, lcz); ChunkRef cr = ChunkRef.Create(this, _cache, lcx, lcz);
_cache.Insert(cr); _cache.Insert(cr);
return cr; return cr;

View file

@ -59,9 +59,14 @@
<HintPath>Assemblies\Ionic.Zlib.dll</HintPath> <HintPath>Assemblies\Ionic.Zlib.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Source\ChunkCache.cs" /> <Compile Include="Source\ChunkCache.cs" />
<None Include="Source\Experimental\BlockInterface.cs" />
<Compile Include="Source\Level.cs" /> <Compile Include="Source\Level.cs" />
<Compile Include="Source\PlayerManager.cs" /> <Compile Include="Source\PlayerManager.cs" />
<Compile Include="Source\PlayerFile.cs" /> <Compile Include="Source\PlayerFile.cs" />