From 89e2ccafd2539321d54abbf9b12994c7b2748400 Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Fri, 6 Jan 2017 21:14:31 +0000
Subject: [PATCH] Set up initial chunk loading skeleton.

---
 Nibriboard/RippleSpace/Chunk.cs          | 71 +++++++++++++++++++++++-
 Nibriboard/RippleSpace/ChunkReference.cs |  5 ++
 Nibriboard/RippleSpace/Plane.cs          | 25 ++++++++-
 3 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/Nibriboard/RippleSpace/Chunk.cs b/Nibriboard/RippleSpace/Chunk.cs
index c981743..ba67166 100644
--- a/Nibriboard/RippleSpace/Chunk.cs
+++ b/Nibriboard/RippleSpace/Chunk.cs
@@ -1,11 +1,22 @@
 ﻿using System;
+using System.IO;
+using System.Threading.Tasks;
+using System.Runtime.CompilerServices;
+using System.Collections.Generic;
+using System.Collections;
+
 namespace Nibriboard.RippleSpace
 {
 	/// <summary>
 	/// Represents a single chunk of an infinite <see cref="Nibriboard.RippleSpace.Plane" />.
 	/// </summary>
-	public class Chunk
+	public class Chunk : IEnumerable<DrawnLine>
 	{
+		/// <summary>
+		/// The lines that this chunk currently contains.
+		/// </summary>
+		private List<DrawnLine> lines = new List<DrawnLine>();
+
 		/// <summary>
 		/// The plane that this chunk is located on.
 		/// </summary>
@@ -16,10 +27,68 @@ namespace Nibriboard.RippleSpace
 		/// </summary>
 		public readonly int Size;
 
+		/// <summary>
+		/// The time at which this chunk was loaded.
+		/// </summary>
+		public readonly DateTime TimeLoaded = DateTime.Now;
+		/// <summary>
+		/// The time at which this chunk was last accessed.
+		/// </summary>
+		public DateTime TimeLastAccessed { get; private set; } = DateTime.Now;
+
 		public Chunk(Plane inPlane, int inSize)
 		{
 			Plane = inPlane;
 			Size = inSize;
 		}
+
+		public void UpdateAccessTime()
+		{
+			TimeLastAccessed = DateTime.Now;
+		}
+
+		public DrawnLine this[int i]
+		{
+			get {
+				UpdateAccessTime();
+				return lines[i];
+			}
+			set {
+				UpdateAccessTime();
+				lines[i] = value;
+			}
+		}
+
+		public IEnumerator<DrawnLine> GetEnumerator()
+		{
+			UpdateAccessTime();
+			return lines.GetEnumerator();
+		}
+		IEnumerator IEnumerable.GetEnumerator()
+		{
+			UpdateAccessTime();
+			return GetEnumerator();
+		}
+
+		public static async Task<Chunk> FromFile(Plane plane, string filename)
+		{
+			StreamReader chunkSource = new StreamReader(filename);
+			return await FromStream(plane, chunkSource);
+		}
+		public static async Task<Chunk> FromStream(Plane plane, StreamReader chunkSource)
+		{
+			Chunk result = new Chunk(
+				plane,
+				int.Parse(chunkSource.ReadLine())
+			);
+
+			string nextLine = string.Empty;
+			while((nextLine = await chunkSource.ReadLineAsync()) != null)
+			{
+				throw new NotImplementedException();
+			}
+
+			return result;
+		}
 	}
 }
diff --git a/Nibriboard/RippleSpace/ChunkReference.cs b/Nibriboard/RippleSpace/ChunkReference.cs
index cfe1f51..a768070 100644
--- a/Nibriboard/RippleSpace/ChunkReference.cs
+++ b/Nibriboard/RippleSpace/ChunkReference.cs
@@ -29,5 +29,10 @@ namespace Nibriboard.RippleSpace
 				Y / Plane.ChunkSize
 			);
 		}
+
+		public string AsFilename()
+		{
+			return $"{Plane.Name}-{X},{Y}.chunk";
+		}
 	}
 }
diff --git a/Nibriboard/RippleSpace/Plane.cs b/Nibriboard/RippleSpace/Plane.cs
index a2bcb7b..792915b 100644
--- a/Nibriboard/RippleSpace/Plane.cs
+++ b/Nibriboard/RippleSpace/Plane.cs
@@ -1,5 +1,6 @@
 ﻿using System;
 using System.Collections.Generic;
+using System.Threading.Tasks;
 namespace Nibriboard.RippleSpace
 {
 	/// <summary>
@@ -7,6 +8,11 @@ namespace Nibriboard.RippleSpace
 	/// </summary>
 	public class Plane
 	{
+		/// <summary>
+		/// The name of this plane.
+		/// </summary>
+		public readonly string Name;
+
 		/// <summary>
 		/// The size of the chunks on this plane.
 		/// </summary>
@@ -17,9 +23,26 @@ namespace Nibriboard.RippleSpace
 		/// </summary>
 		protected Dictionary<ChunkReference, Chunk> loadedChunkspace = new Dictionary<ChunkReference, Chunk>();
 
-		public Plane(int inChunkSize)
+		public Plane(string inName, int inChunkSize)
 		{
+			Name = inName;
 			ChunkSize = inChunkSize;
 		}
+
+		public async Task<Chunk> 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.
+			Chunk loadedChunk = await Chunk.FromFile(this, chunkLocation.AsFilename());
+			loadedChunkspace.Add(chunkLocation, loadedChunk);
+
+			return loadedChunk;
+		}
 	}
 }
