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:
parent
3d013e208c
commit
99ac0634ad
5 changed files with 81 additions and 15 deletions
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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()}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue