1
0
Fork 0

Reworkt he saving system a bit.

This commit is contained in:
Starbeamrainbowlabs 2017-07-20 20:02:50 +01:00
parent 3d013e208c
commit 99ac0634ad
5 changed files with 81 additions and 15 deletions

View File

@ -23,7 +23,7 @@ namespace Nibriboard
private HttpServer httpServer;
private ClientSettings clientSettings;
private RippleSpaceManager planeManager = new RippleSpaceManager();
private RippleSpaceManager planeManager = new RippleSpaceManager() { SourceFilename = "./test.ripplespace.tar.gz" };
private readonly CancellationTokenSource clientManagerCanceller = new CancellationTokenSource();
private NibriClientManager clientManager;

View File

@ -216,20 +216,25 @@ namespace Nibriboard.RippleSpace
public static async Task<Chunk> FromFile(Plane plane, string filename)
{
FileStream chunkSource = new FileStream(filename, FileMode.Open);
StreamReader chunkSource = new StreamReader(filename);
return await FromStream(plane, chunkSource);
}
public static async Task<Chunk> FromStream(Plane plane, Stream chunkSource)
public static async Task<Chunk> FromStream(Plane plane, StreamReader chunkSource)
{
Chunk loadedChunk = await BinaryIO.DeserialiseBinaryObject<Chunk>(chunkSource);
Chunk loadedChunk = JsonConvert.DeserializeObject<Chunk>(await chunkSource.ReadToEndAsync());
loadedChunk.plane = plane;
loadedChunk.OnChunkUpdate += plane.HandleChunkUpdate;
return loadedChunk;
}
public async Task SaveTo(Stream destination)
/// <summary>
/// Saves this chunk to the specified stream.
/// </summary>
/// <param name="destination">The destination stream to save the chunk to.</param>
public async Task SaveTo(StreamWriter destination)
{
throw new NotImplementedException("Error: Chunk saving hasn't been implemented yet!");
await destination.WriteLineAsync(JsonConvert.SerializeObject(this));
}
public void OnDeserialization(object sender)

View File

@ -158,7 +158,7 @@ namespace Nibriboard.RippleSpace
loadedChunk = await Chunk.FromFile(this, chunkFilePath);
else // Ooooh! It's a _new_, never-before-seen one! Create a brand new chunk :D
loadedChunk = new Chunk(this, ChunkSize, chunkLocation);
loadedChunk.OnChunkUpdate += handleChunkUpdate;
loadedChunk.OnChunkUpdate += HandleChunkUpdate;
loadedChunkspace.Add(chunkLocation, loadedChunk);
return loadedChunk;
@ -189,7 +189,11 @@ namespace Nibriboard.RippleSpace
Chunk chunk = loadedChunkspace[chunkLocation];
string chunkFilePath = Path.Combine(StorageDirectory, chunkLocation.AsFilename());
await chunk.SaveTo(File.OpenWrite(chunkFilePath));
using(StreamWriter chunkDestination = new StreamWriter(chunkFilePath))
{
await chunk.SaveTo(chunkDestination);
}
}
public async Task AddLine(DrawnLine newLine)
@ -242,10 +246,24 @@ namespace Nibriboard.RippleSpace
}
}
public void Save(Stream destination)
public async Task Save(Stream destination)
{
// Save all the chunks to disk
List<Task> chunkSavers = new List<Task>();
foreach(KeyValuePair<ChunkReference, Chunk> loadedChunkItem in loadedChunkspace)
{
// Figure out where to put the chunk and create the relevant directories
string chunkDestinationFilename = CalcPaths.ChunkFilepath(StorageDirectory, loadedChunkItem.Key);
Directory.CreateDirectory(Path.GetDirectoryName(chunkDestinationFilename));
// Ask the chunk to save itself
using(StreamWriter chunkDestination = new StreamWriter(chunkDestinationFilename))
{
chunkSavers.Add(loadedChunkItem.Value.SaveTo(chunkDestination));
}
}
await Task.WhenAll(chunkSavers);
// Pack the chunks into an nplane file
WriterOptions packingOptions = new WriterOptions(CompressionType.GZip);
IEnumerable<string> chunkFiles = Directory.GetFiles(StorageDirectory);
@ -264,7 +282,7 @@ namespace Nibriboard.RippleSpace
/// </summary>
/// <param name="sender">The chunk responsible for the update.</param>
/// <param name="eventArgs">The event arguments associated with the chunk update.</param>
protected void handleChunkUpdate(object sender, ChunkUpdateEventArgs eventArgs)
public void HandleChunkUpdate(object sender, ChunkUpdateEventArgs eventArgs)
{
Chunk updatingChunk = sender as Chunk;
if(updatingChunk == null)

View File

@ -6,15 +6,23 @@ using System.Diagnostics;
using System.Linq;
using SharpCompress.Readers;
using Nibriboard.Utilities;
using SharpCompress.Writers;
using SharpCompress.Common;
namespace Nibriboard.RippleSpace
{
public class RippleSpaceManager
{
/// <summary>
/// The filename from which this ripplespace was loaded, and the filename to which it should be saved again.
/// </summary>
/// <value>The source filename.</value>
public string SourceFilename { get; set; }
/// <summary>
/// The temporary directory in which we are currently storing our unpacked planes temporarily.
/// </summary>
public string UnpackedDirectory;
public string UnpackedDirectory { get; set; }
/// <summary>
/// The master list of planes that this PlaneManager is in charge of.
@ -38,11 +46,15 @@ namespace Nibriboard.RippleSpace
// Create a temporary directory in which to store our unpacked planes
UnpackedDirectory = Path.GetTempFileName();
File.Delete(UnpackedDirectory);
UnpackedDirectory += "/";
UnpackedDirectory = Path.GetDirectoryName(UnpackedDirectory) + "/ripplespace-" + Path.GetFileName(UnpackedDirectory) + "/";
Directory.CreateDirectory(UnpackedDirectory);
Log.WriteLine("[RippleSpace] New blank ripplespace initialised.");
}
~RippleSpaceManager()
{
Directory.Delete(UnpackedDirectory, true);
}
/// <summary>
/// Gets the plane with the specified name from this RippleSpace.
@ -110,7 +122,30 @@ namespace Nibriboard.RippleSpace
public async Task Save()
{
throw new NotImplementedException();
// Save the planes to disk
List<Task> planeSavers = new List<Task>();
foreach(Plane item in Planes)
{
// Figure out where the plane should save itself to and create the appropriate directories
string planeSavePath = CalcPaths.UnpackedPlaneFile(UnpackedDirectory, item.Name);
Directory.CreateDirectory(Path.GetDirectoryName(planeSavePath));
// Ask the plane to save to the directory
planeSavers.Add(item.Save(File.OpenWrite(planeSavePath)));
}
await Task.WhenAll(planeSavers);
// Pack the planes into the ripplespace archive
Stream destination = File.OpenWrite(SourceFilename);
string[] planeFiles = Directory.GetFiles(UnpackedDirectory, "*.nplane.tar.gz", SearchOption.TopDirectoryOnly);
using(IWriter rippleSpacePacker = WriterFactory.Open(destination, ArchiveType.Tar, new WriterOptions(CompressionType.GZip)))
{
foreach(string planeFilename in planeFiles)
{
rippleSpacePacker.Write(Path.GetFileName(planeFilename), planeFilename);
}
}
}
public async Task<RippleSpaceManager> FromFile(string filename)
@ -119,6 +154,7 @@ namespace Nibriboard.RippleSpace
throw new FileNotFoundException($"Error: Couldn't find the packed ripplespace at {filename}");
RippleSpaceManager rippleSpace = new RippleSpaceManager();
rippleSpace.SourceFilename = filename;
using(Stream packedRippleSpaceStream = File.OpenRead(filename))
using(IReader rippleSpaceUnpacker = ReaderFactory.Open(packedRippleSpaceStream))

View File

@ -1,4 +1,5 @@
using System;
using Nibriboard.RippleSpace;
namespace Nibriboard.Utilities
{
@ -34,7 +35,13 @@ namespace Nibriboard.Utilities
/// <returns>The path to the packed plane file.</returns>
public static string UnpackedPlaneFile(string unpackingDir, string planeName)
{
return $"{unpackingDir}/{planeName}.nplane";
return $"{unpackingDir}/{planeName}.nplane.tar.gz";
}
public static string ChunkFilepath(string planeStorageDirectory, ChunkReference chunkRef)
{
return $"{planeStorageDirectory}/{chunkRef.AsFilename()}";
}
}
}