/// <summary> /// Returns a chunk and its 4 neighbours /// </summary> public void GetChunkRef(ChunkPositionDimension pos, AccessMode mode, [NotNull] ChunkRefFunc chunkRefFunc) { var positions = new[] { pos, new ChunkPositionDimension(pos.ChunkX + 1, pos.ChunkZ, pos.Dimension), new ChunkPositionDimension(pos.ChunkX - 1, pos.ChunkZ, pos.Dimension), new ChunkPositionDimension(pos.ChunkX, pos.ChunkZ + 1, pos.Dimension), new ChunkPositionDimension(pos.ChunkX, pos.ChunkZ - 1, pos.Dimension) }; // translate the ChunksFunc to a ChunkRefFunc and call it. GetChunks(positions, mode, chunks => { var chunksList = chunks.ToList(); chunkRefFunc(chunksList[0], chunksList[1], chunksList[2], chunksList[3], chunksList[4]); }); // notify the chunk has changed if the mode is write var chunksEvent = ChunksModified; if (mode == AccessMode.ReadWrite || chunksEvent == null) { return; } chunksEvent(this, new ChunksModifiedEventArgs(positions)); }
// TODO: comment it up so that plebs know how to dougie // TODO: universal undo (Do(), Undo()) // TODO: access tracking; output in the UI, also for going read-only we have to block new accesses and wait on running ones. /* TODO: Modify substrate to use cached scratch memory to reduce garbage compaction * Caching byte[] (4kb and other sizes) is the main priority, but caching tag nodes is good too. * byte[] pool: https://stackoverflow.com/questions/15726214/scratch-memory-in-a-managed-environment * Careful of memory leaks if using a singleton and with ICopyable<T>.Copy() ... */ // TODO: all out object pooling https://stackoverflow.com/questions/2510975/c-sharp-object-pooling-pattern-implementation // TODO: Substrate: deterministic discovery of dimensions instead of guessing with int #region Chunks public void GetChunk(ChunkPositionDimension pos, AccessMode mode, [NotNull] Action <IChunk> chunkFunction) { // get the resource and its lock var chunkLock = GetChunkLock(pos); // run the func chunkLock.Access(mode, chunkFunction); // notify the chunk has changed if the mode is write var chunksEvent = ChunksModified; if (mode != AccessMode.ReadWrite || chunksEvent == null) { return; } chunksEvent(this, new ChunksModifiedEventArgs(new[] { pos })); }
ReaderWriterObjectLock <IChunk> GetChunkLock(ChunkPositionDimension pos) { lock (_chunkAccessLock) { ReaderWriterObjectLock <IChunk> chunkLock; if (_chunkAccess.TryGetValue(pos, out chunkLock)) { return(chunkLock); } // create a new chunkLock if (NbtWorld == null) { return(_chunkAccess[pos] = new ReaderWriterObjectLock <IChunk>(null)); } var chunk = NbtWorld.GetChunkManager(pos.Dimension).GetChunk(pos.ChunkX, pos.ChunkZ); return(_chunkAccess[pos] = new ReaderWriterObjectLock <IChunk>(chunk)); } }