using System; using System.Collections.Generic; using System.Threading.Tasks; using System.IO; namespace Nibriboard.RippleSpace { /// /// Represents an infinite plane. /// public class Plane { /// /// The name of this plane. /// public readonly string Name; /// /// The size of the chunks on this plane. /// public readonly int ChunkSize; /// /// The path to the directory that the plane's information will be stored in. /// public readonly string StorageDirectory; /// /// The number of milliseconds that should pass since a chunk's last /// access in order for it to be considered inactive. /// public int InactiveMillisecs = 60 * 1000; /// /// The number of chunks in a square around (0, 0) that should always be /// loaded. /// public int PrimaryChunkAreaSize = 10; /// /// The chunkspace that holds the currently loaded and active chunks. /// protected Dictionary loadedChunkspace = new Dictionary(); public Plane(string inName, int inChunkSize) { Name = inName; ChunkSize = inChunkSize; StorageDirectory = $"./Planes/{Name}"; } public async Task FetchChunk(ChunkReference chunkLocation) { // If the chunk is in the loaded chunk-space, then return it immediately if(loadedChunkspace.ContainsKey(chunkLocation)) { return loadedChunkspace[chunkLocation]; } // Uh-oh! The chunk isn't loaded at moment. Load it quick & then // return it fast. string chunkFilePath = Path.Combine(StorageDirectory, chunkLocation.AsFilename()); Chunk loadedChunk = await Chunk.FromFile(this, chunkFilePath); loadedChunkspace.Add(chunkLocation, loadedChunk); return loadedChunk; } public async Task AddLine(DrawnLine newLine) { List chunkedLine; // Split the line up into chunked pieces if neccessary if(newLine.SpansMultipleChunks) chunkedLine = newLine.SplitOnChunks(ChunkSize); else chunkedLine = new List() { newLine }; // Add each segment to the appropriate chunk foreach(DrawnLine newLineSegment in chunkedLine) { Chunk containingChunk = await FetchChunk(newLineSegment.ContainingChunk); containingChunk.Add(newLineSegment); } } } }