fix(core): Fixes generic persistence (#544)
- [X] Fixes generic persistence, making the API for writing from a static class much easier.
Example:
```cs
namespace Server
{
public static class ExampleSystem
{
public static void Configure()
{
GenericPersistence.Register("ExampleSystem", Serialize, Deserialize);
}
public static void Serialize(IGenericWriter writer)
{
// Do serialization here
writer.WriteEncodedInt(0); // version
}
public static void Deserialize(IGenericReader reader)
{
// Do deserialization here
var version = reader.ReadEncodedInt();
}
}
}
```
This commit is contained in:
parent
3c88331607
commit
432f8d2b70
2 changed files with 56 additions and 25 deletions
|
|
@ -20,35 +20,64 @@ namespace Server
|
||||||
{
|
{
|
||||||
public static class GenericPersistence
|
public static class GenericPersistence
|
||||||
{
|
{
|
||||||
public static void Serialize(Action<IGenericWriter> serializer) => serializer(new BufferWriter(true));
|
public static void Register(
|
||||||
|
string name,
|
||||||
public static void WriteSnapshot(string path, Action<IGenericWriter> serializer)
|
Action<IGenericWriter> serializer,
|
||||||
|
Action<IGenericReader> deserializer
|
||||||
|
)
|
||||||
{
|
{
|
||||||
AssemblyHandler.EnsureDirectory(Path.GetDirectoryName(path));
|
BufferWriter saveBuffer = null;
|
||||||
|
|
||||||
using var fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.None);
|
void Serialize()
|
||||||
serializer(new BinaryFileWriter(fs, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Deserialize(string path, Action<IGenericReader> deserializer, bool ensure = true)
|
|
||||||
{
|
|
||||||
AssemblyHandler.EnsureDirectory(Path.GetDirectoryName(path));
|
|
||||||
|
|
||||||
if (!File.Exists(path))
|
|
||||||
{
|
{
|
||||||
if (ensure)
|
saveBuffer ??= new BufferWriter(true);
|
||||||
{
|
saveBuffer.Seek(0, SeekOrigin.Begin);
|
||||||
new FileInfo(path).Create().Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
serializer(saveBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
using FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
void WriterSnapshot(string savePath)
|
||||||
// TODO: Support files larger than 2GB
|
{
|
||||||
var buffer = GC.AllocateUninitializedArray<byte>((int)fs.Length);
|
var path = Path.Combine(savePath, name);
|
||||||
|
|
||||||
deserializer(new BufferReader(buffer));
|
AssemblyHandler.EnsureDirectory(path);
|
||||||
|
|
||||||
|
string binPath = Path.Combine(path, $"{name}.bin");
|
||||||
|
using var bin = new BinaryFileWriter(binPath, true);
|
||||||
|
|
||||||
|
saveBuffer!.Resize((int)saveBuffer.Position);
|
||||||
|
bin.Write(saveBuffer.Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Deserialize(string savePath)
|
||||||
|
{
|
||||||
|
var path = Path.Combine(savePath, name);
|
||||||
|
|
||||||
|
AssemblyHandler.EnsureDirectory(path);
|
||||||
|
|
||||||
|
string binPath = Path.Combine(path, $"{name}.bin");
|
||||||
|
|
||||||
|
if (!File.Exists(binPath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using FileStream bin = new FileStream(binPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
|
var br = new BufferReader(GC.AllocateUninitializedArray<byte>((int)bin.Length));
|
||||||
|
deserializer(br);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Utility.PushColor(ConsoleColor.Red);
|
||||||
|
Persistence.WriteConsoleLine($"***** Bad deserialize of {name} *****");
|
||||||
|
Persistence.WriteConsoleLine(e.ToString());
|
||||||
|
Utility.PopColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Persistence.Register(Serialize, WriterSnapshot, Deserialize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -276,10 +276,12 @@ namespace Server
|
||||||
private static void SerializeTo(this ISerializable entity, IGenericWriter writer)
|
private static void SerializeTo(this ISerializable entity, IGenericWriter writer)
|
||||||
{
|
{
|
||||||
var saveBuffer = entity.SaveBuffer;
|
var saveBuffer = entity.SaveBuffer;
|
||||||
writer.Write(saveBuffer.Buffer.AsSpan(0, (int)saveBuffer.Position));
|
|
||||||
|
|
||||||
// Resize to exact buffer size
|
// Resize to the exact size
|
||||||
entity.SaveBuffer.Resize((int)entity.SaveBuffer.Position);
|
saveBuffer.Resize((int)saveBuffer.Position);
|
||||||
|
|
||||||
|
// Write that amount
|
||||||
|
writer.Write(saveBuffer.Buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue