1
0
Fork 0
mirror of https://github.com/sbrl/Nibriboard.git synced 2018-01-10 21:33:49 +00:00

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 HttpServer httpServer;
private ClientSettings clientSettings; 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 readonly CancellationTokenSource clientManagerCanceller = new CancellationTokenSource();
private NibriClientManager clientManager; private NibriClientManager clientManager;

View file

@ -216,20 +216,25 @@ namespace Nibriboard.RippleSpace
public static async Task<Chunk> FromFile(Plane plane, string filename) 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); 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.plane = plane;
loadedChunk.OnChunkUpdate += plane.HandleChunkUpdate;
return loadedChunk; 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) public void OnDeserialization(object sender)

View file

@ -158,7 +158,7 @@ namespace Nibriboard.RippleSpace
loadedChunk = await Chunk.FromFile(this, chunkFilePath); loadedChunk = await Chunk.FromFile(this, chunkFilePath);
else // Ooooh! It's a _new_, never-before-seen one! Create a brand new chunk :D else // Ooooh! It's a _new_, never-before-seen one! Create a brand new chunk :D
loadedChunk = new Chunk(this, ChunkSize, chunkLocation); loadedChunk = new Chunk(this, ChunkSize, chunkLocation);
loadedChunk.OnChunkUpdate += handleChunkUpdate; loadedChunk.OnChunkUpdate += HandleChunkUpdate;
loadedChunkspace.Add(chunkLocation, loadedChunk); loadedChunkspace.Add(chunkLocation, loadedChunk);
return loadedChunk; return loadedChunk;
@ -189,7 +189,11 @@ namespace Nibriboard.RippleSpace
Chunk chunk = loadedChunkspace[chunkLocation]; Chunk chunk = loadedChunkspace[chunkLocation];
string chunkFilePath = Path.Combine(StorageDirectory, chunkLocation.AsFilename()); 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) 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); WriterOptions packingOptions = new WriterOptions(CompressionType.GZip);
IEnumerable<string> chunkFiles = Directory.GetFiles(StorageDirectory); IEnumerable<string> chunkFiles = Directory.GetFiles(StorageDirectory);
@ -264,7 +282,7 @@ namespace Nibriboard.RippleSpace
/// </summary> /// </summary>
/// <param name="sender">The chunk responsible for the update.</param> /// <param name="sender">The chunk responsible for the update.</param>
/// <param name="eventArgs">The event arguments associated with the chunk 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; Chunk updatingChunk = sender as Chunk;
if(updatingChunk == null) if(updatingChunk == null)

View file

@ -6,15 +6,23 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using SharpCompress.Readers; using SharpCompress.Readers;
using Nibriboard.Utilities; using Nibriboard.Utilities;
using SharpCompress.Writers;
using SharpCompress.Common;
namespace Nibriboard.RippleSpace namespace Nibriboard.RippleSpace
{ {
public class RippleSpaceManager 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> /// <summary>
/// The temporary directory in which we are currently storing our unpacked planes temporarily. /// The temporary directory in which we are currently storing our unpacked planes temporarily.
/// </summary> /// </summary>
public string UnpackedDirectory; public string UnpackedDirectory { get; set; }
/// <summary> /// <summary>
/// The master list of planes that this PlaneManager is in charge of. /// 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 // Create a temporary directory in which to store our unpacked planes
UnpackedDirectory = Path.GetTempFileName(); UnpackedDirectory = Path.GetTempFileName();
File.Delete(UnpackedDirectory); File.Delete(UnpackedDirectory);
UnpackedDirectory += "/"; UnpackedDirectory = Path.GetDirectoryName(UnpackedDirectory) + "/ripplespace-" + Path.GetFileName(UnpackedDirectory) + "/";
Directory.CreateDirectory(UnpackedDirectory); Directory.CreateDirectory(UnpackedDirectory);
Log.WriteLine("[RippleSpace] New blank ripplespace initialised."); Log.WriteLine("[RippleSpace] New blank ripplespace initialised.");
} }
~RippleSpaceManager()
{
Directory.Delete(UnpackedDirectory, true);
}
/// <summary> /// <summary>
/// Gets the plane with the specified name from this RippleSpace. /// Gets the plane with the specified name from this RippleSpace.
@ -110,7 +122,30 @@ namespace Nibriboard.RippleSpace
public async Task Save() 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) 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}"); throw new FileNotFoundException($"Error: Couldn't find the packed ripplespace at {filename}");
RippleSpaceManager rippleSpace = new RippleSpaceManager(); RippleSpaceManager rippleSpace = new RippleSpaceManager();
rippleSpace.SourceFilename = filename;
using(Stream packedRippleSpaceStream = File.OpenRead(filename)) using(Stream packedRippleSpaceStream = File.OpenRead(filename))
using(IReader rippleSpaceUnpacker = ReaderFactory.Open(packedRippleSpaceStream)) using(IReader rippleSpaceUnpacker = ReaderFactory.Open(packedRippleSpaceStream))

View file

@ -1,4 +1,5 @@
using System; using System;
using Nibriboard.RippleSpace;
namespace Nibriboard.Utilities namespace Nibriboard.Utilities
{ {
@ -34,7 +35,13 @@ namespace Nibriboard.Utilities
/// <returns>The path to the packed plane file.</returns> /// <returns>The path to the packed plane file.</returns>
public static string UnpackedPlaneFile(string unpackingDir, string planeName) 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()}";
} }
} }
} }