Skip to content

Commit

Permalink
Fix saving empty delays and flags in meta.json
Browse files Browse the repository at this point in the history
  • Loading branch information
DrSmugleaf committed Aug 7, 2021
1 parent c5c3f00 commit 679f37d
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using Importer.RSI;
using NUnit.Framework;

namespace Importer.Tests.RSI.State
namespace Importer.Tests.RSI
{
[TestFixture]
[TestOf(typeof(RsiState))]
public class RsiStateTests
public class RsiDimensionsTest
{
[Test]
[TestCase(1, 1, 1)]
Expand Down
118 changes: 118 additions & 0 deletions Importer.Tests/RSI/RsiSaveTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Importer.Directions;
using Importer.RSI;
using NUnit.Framework;

namespace Importer.Tests.RSI
{
[TestFixture]
[TestOf(typeof(Rsi))]
public class RsiSaveTest
{
[Test]
public async Task EmptyIgnoredTest()
{
var state = new RsiState
{
Delays = new List<List<float>>(),
Flags = new Dictionary<string, object>()
};
var states = new List<RsiState>() {state};

Assert.IsEmpty(states[0].Delays);
Assert.IsEmpty(states[0].Flags);

var rsi = new Rsi(states: states);
var stream = new MemoryStream();

await rsi.SaveRsiToStream(stream);
var json = await new StreamReader(stream).ReadToEndAsync();
await stream.DisposeAsync();

Assert.That(json, Is.Not.Empty);
Assert.That(json, Does.Not.Contain("delays"));
Assert.That(json, Does.Not.Contain("flags"));
}

[Test]
public async Task NotEmptySerializedTest()
{
var state = new RsiState
{
Delays = new List<List<float>> {new() {5}},
Flags = new Dictionary<string, object> {["Key"] = "Value"}
};
var states = new List<RsiState>() {state};

Assert.IsNotEmpty(states[0].Delays);
Assert.IsNotEmpty(states[0].Flags);

var rsi = new Rsi(states: states);
var stream = new MemoryStream();

await rsi.SaveRsiToStream(stream);
var json = await new StreamReader(stream).ReadToEndAsync();
await stream.DisposeAsync();

Assert.That(json, Is.Not.Empty);

Assert.That(json, Does.Contain("delays"));
Assert.That(json, Does.Contain("5"));

Assert.That(json, Does.Contain("flags"));
Assert.That(json, Does.Contain("Key"));
Assert.That(json, Does.Contain("Value"));
}

[Test]
public async Task ConsistencyTest()
{
var state = new RsiState
{
Name = "RsiState",
Directions = DirectionType.Diagonal,
Delays = new List<List<float>> {new() {5}},
Flags = new Dictionary<string, object> {["Key"] = "Value"},
};
var states = new List<RsiState>() {state};

Assert.IsNotEmpty(states[0].Delays);
Assert.IsNotEmpty(states[0].Flags);

var rsi = new Rsi(x: 42, y: 42)
{
Version = 5,
License = "License",
Copyright = "Copyright",
States = states
};
var stream = new MemoryStream();

await rsi.SaveRsiToStream(stream);
rsi = await Rsi.FromMetaJson(stream);
await stream.DisposeAsync();

Assert.That(rsi.Version, Is.EqualTo(5));
Assert.That(rsi.License, Is.EqualTo("License"));
Assert.That(rsi.Copyright, Is.EqualTo("Copyright"));
Assert.That(rsi.Size, Is.EqualTo(new RsiSize(42, 42)));

Assert.That(rsi.States.Count, Is.EqualTo(1));

state = rsi.States[0];
Assert.That(state.Name, Is.EqualTo("RsiState"));
Assert.That(state.Directions, Is.EqualTo(DirectionType.Diagonal));

Assert.NotNull(state.Delays);
Assert.That(state.Delays.Count, Is.EqualTo(1));
Assert.That(state.Delays[0].Count, Is.EqualTo(1));
Assert.That(state.Delays[0][0], Is.EqualTo(5));

Assert.NotNull(state.Flags);
Assert.That(state.Flags.Count, Is.EqualTo(1));
Assert.That(state.Flags["Key"].ToString(), Is.EqualTo("Value"));
}
}
}
76 changes: 73 additions & 3 deletions Importer/RSI/Rsi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using SixLabors.ImageSharp;
Expand Down Expand Up @@ -56,7 +58,28 @@ public class Rsi : IDisposable
[JsonPropertyName("states")]
public List<RsiState> States { get; set; }

public async Task LoadFolderImages(string rsiFolder)
public static async Task<Rsi> FromFolder(
string rsiFolder,
JsonSerializerOptions? options = null,
CancellationToken token = default)
{
var metaJsonPath = $"{rsiFolder}{Path.DirectorySeparatorChar}meta.json";
await using var metaJsonStream = File.OpenRead(metaJsonPath);

return await FromMetaJson(metaJsonStream, options, token);
}

public static async Task<Rsi> FromMetaJson(
Stream metaJson,
JsonSerializerOptions? options = null,
CancellationToken token = default)
{
var rsi = await JsonSerializer.DeserializeAsync<Rsi>(metaJson, options, token);

return rsi ?? throw new NullReferenceException();
}

public async Task TryLoadFolderImages(string rsiFolder)
{
if (!Directory.Exists(rsiFolder))
{
Expand All @@ -77,14 +100,61 @@ public async Task LoadFolderImages(string rsiFolder)
}
}

public async Task SaveTo(string rsiFolder)
public async Task SaveToFolder(string rsiFolder, JsonSerializerOptions? options = null)
{
Directory.CreateDirectory(rsiFolder);

await SaveImagesToFolder(rsiFolder);
await SaveRsiToFolder(rsiFolder, options);
}

public async Task SaveToStream(Stream stream, JsonSerializerOptions? options = null)
{
await SaveImagesToStream(stream);
await SaveRsiToStream(stream, options);
}

public async Task SaveImagesToFolder(string rsiFolder)
{
foreach (var state in States)
{
var image = state.GetFullImage(Size);
var path = $"{rsiFolder}{Path.DirectorySeparatorChar}{state.Name}.png";

await image.SaveAsPngAsync(path);
}
}

await image.SaveAsync($"{rsiFolder}{Path.DirectorySeparatorChar}{state.Name}.png");
public async Task SaveImagesToStream(Stream stream)
{
foreach (var state in States)
{
var image = state.GetFullImage(Size);
await image.SaveAsPngAsync(stream);
}

await stream.FlushAsync();
stream.Seek(0, SeekOrigin.Begin);
}

public async Task SaveRsiToFolder(string rsiFolder, JsonSerializerOptions? options = null)
{
var metaJsonPath = $"{rsiFolder}{Path.DirectorySeparatorChar}meta.json";
await File.WriteAllTextAsync(metaJsonPath, string.Empty);

await using var metaJsonFile = File.OpenWrite(metaJsonPath);
await SaveRsiToStream(metaJsonFile, options);
}

public async Task SaveRsiToStream(Stream stream, JsonSerializerOptions? options = null)
{
options ??= new JsonSerializerOptions();
options.Converters.Add(RsiStateConverter.Instance);

await JsonSerializer.SerializeAsync(stream, this, options);
await stream.FlushAsync();

stream.Seek(0, SeekOrigin.Begin);
}

public void Dispose()
Expand Down
6 changes: 3 additions & 3 deletions Importer/RSI/RsiState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class RsiState : IDisposable
string name,
DirectionType directions = DirectionType.None,
List<List<float>>? delays = null,
Dictionary<object, object>? flags = null,
Dictionary<string, object>? flags = null,
Image<Rgba32>[,]? frames = null,
string? invalidCharacterReplace = "_")
{
Expand All @@ -46,7 +46,7 @@ public class RsiState : IDisposable
string name,
DirectionType directions = DirectionType.None,
List<List<float>>? delays = null,
Dictionary<object, object>? flags = null)
Dictionary<string, object>? flags = null)
: this (name, directions, delays, flags, null, null)
{
}
Expand All @@ -65,7 +65,7 @@ public RsiState(string name = "") : this(name, DirectionType.None, null, null)
public List<List<float>>? Delays { get; set; }

[JsonPropertyName("flags")]
public Dictionary<object, object>? Flags { get; set; }
public Dictionary<string, object>? Flags { get; set; }

[JsonIgnore]
public int DelayLength { get; private set; }
Expand Down
58 changes: 58 additions & 0 deletions Importer/RSI/RsiStateConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Importer.RSI
{
public class RsiStateConverter : JsonConverter<RsiState>
{
public static readonly RsiStateConverter Instance = new();

public override RsiState Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException();
}

public override void Write(Utf8JsonWriter writer, RsiState value, JsonSerializerOptions options)
{
writer.WriteStartObject();

writer.WriteString("name", value.Name);
writer.WriteNumber("directions", (int) value.Directions);

if (value.Delays is {Count: > 0})
{
writer.WriteStartArray("delays");

foreach (var delays in value.Delays)
{
writer.WriteStartArray();

foreach (var delay in delays)
{
writer.WriteNumberValue(delay);
}

writer.WriteEndArray();
}

writer.WriteEndArray();
}

if (value.Flags is {Count: > 0})
{
writer.WriteStartObject("flags");

foreach (var kvPair in value.Flags)
{
writer.WriteString(kvPair.Key.ToString()!, kvPair.Value.ToString());
}

writer.WriteEndObject();
}

writer.WriteEndObject();
}
}
}

0 comments on commit 679f37d

Please sign in to comment.