Skip to content

Commit

Permalink
WIP: working on serialization for GameEventType
Browse files Browse the repository at this point in the history
  • Loading branch information
Konrad Jamrozik committed Jul 6, 2024
1 parent bf6b552 commit fff963e
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/api/ApiUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public static (int turnLimitVal, string? error) ParseTurnLimit(int? turnLimit, G
{
// Deserialization method invocation and configuration as explained by:
// https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/parameter-binding?view=aspnetcore-8.0#configure-json-deserialization-options-for-an-endpoint
// kja this should use GameSessionTurn.SerializerOptions not GameState
parsedTurn = (requestBody.FromJsonTo<GameSessionTurn>(GameState.StateJsonSerializerOptions));
// If the input game session turn would have advance time event, besides conceptually not making sense,
// it would throw off the NextEventId calculation, as game session could start appending player action events to current turn
Expand Down
11 changes: 8 additions & 3 deletions src/game-lib/Events/GameEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ namespace UfoGameLib.Events;
public abstract class GameEvent : IIdentifiable
{
public int Id { get; }
public readonly string Type;
public readonly GameEventType Type;

public GameEvent(int id, string type)
public GameEvent(int id, string type) : this(id, new GameEventType(type))
{
}

public GameEvent(int id, GameEventType type)
{
Id = id;
Type = type;
}


public abstract GameEvent Clone();
}
}
7 changes: 6 additions & 1 deletion src/game-lib/Events/GameEventType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,9 @@ public GameEventType(string type)
Contract.Assert(GameEventTypes.Contains(type) || PlayerAction.IsValidName(type));
_type = type;
}
}

public override string ToString()
{
return $"{_type}";
}
}
19 changes: 19 additions & 0 deletions src/game-lib/Events/GameEventTypeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace UfoGameLib.Events;

public class GameEventTypeConverter : JsonConverter<GameEventType>
{
public override GameEventType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Console.WriteLine("KJA GameEventTypeConverter.Read");
return new GameEventType(reader.GetString()!);
}

public override void Write(Utf8JsonWriter writer, GameEventType value, JsonSerializerOptions options)
{
Console.WriteLine("KJA GameEventTypeConverter.Write");
writer.WriteStringValue(value.ToString());
}
}
14 changes: 11 additions & 3 deletions src/game-lib/Events/PlayerActionEvent.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// ReSharper disable MemberCanBePrivate.Global
// Reason: public fields are being serialized to JSON.

using UfoGameLib.Controller;
using System.Text.Json.Serialization;

namespace UfoGameLib.Events;

Expand All @@ -10,11 +10,19 @@ public class PlayerActionEvent : GameEvent
public readonly List<int>? Ids;
public readonly int? TargetId;

public PlayerActionEvent(int id, string type, List<int>? ids = null, int? targetId = null) : base(id, type)
[JsonConstructor]
public PlayerActionEvent(int id, string type, List<int>? ids = null, int? targetId = null) : this(
id,
new GameEventType(type),
ids,
targetId)
{
}

public PlayerActionEvent(int id, GameEventType type, List<int>? ids = null, int? targetId = null) : base(id, type)
{
Ids = ids;
TargetId = targetId;
// kja PlayerAction.ValidateName(type);
}

public override PlayerActionEvent Clone()
Expand Down
17 changes: 14 additions & 3 deletions src/game-lib/Events/WorldEvent.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
// ReSharper disable MemberCanBePrivate.Global
// Reason: public fields are being serialized to JSON.

using System.Text.Json.Serialization;

namespace UfoGameLib.Events;

public class WorldEvent : GameEvent
{
public readonly List<int>? Ids;
public readonly int? TargetId;

public WorldEvent(int id, string type, List<int>? ids = null, int? targetId = null) : base(id, type)
[JsonConstructor]
public WorldEvent(int id, string type, List<int>? ids = null, int? targetId = null) : this(
id,
new GameEventType(type),
ids,
targetId)
{
}

public WorldEvent(int id, GameEventType type, List<int>? ids = null, int? targetId = null) : base(id, type)
{
Ids = ids;
TargetId = targetId;
// kja2-assert: that 'type' is one of the valid WorldEvents
TargetId = targetId;
}

public override WorldEvent Clone()
Expand Down
2 changes: 1 addition & 1 deletion src/game-lib/State/GameSessionTurn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void AssertInvariants()
EventsInTurn.Count == EndState.UpdateCount - StartState.UpdateCount,
"Number of events in turn must match the number of updates between the game states.");

Contract.Assert(EventsUntilStartState.Last().Type == GameEventType.ReportEvent);
Contract.Assert(EventsUntilStartState.Last().Type.ToString() == GameEventType.ReportEvent);
IdGen.AssertConsecutiveIds(GameEvents.ToList());
// kja all events in turn except the last one must be not AdvanceTime player action
// Contract.Assert(EventsInTurn.SkipLast(1).All(@event => @event.Type == "a"))
Expand Down
10 changes: 7 additions & 3 deletions src/game-lib/State/GameState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Text.Json.Serialization;
using Lib.Contracts;
using Lib.Json;
using UfoGameLib.Events;
using UfoGameLib.Lib;
using UfoGameLib.Model;
using File = Lib.OS.File;
Expand Down Expand Up @@ -136,10 +137,10 @@ private static JsonSerializerOptions GetJsonSerializerOptions()
{
// We return 'options' that:
// 1. use the 'converterOptions' as base options
// 2. have GameStateJsonConverter as a converter
// 3. the converter also uses 'converterOptions' as base options
// 2. have GameStateJsonConverter as a 'converter'
// 3. the 'converter' also uses 'converterOptions' as base options
//
// In other words, both 'options' and its converter use the same base options: 'converterOptions'.
// In other words, both 'options' and its 'converter' use the same base options: 'converterOptions'.
//
// Note: we couldn't collapse 'options' and 'converterOptions' into one instance, because it would
// result in an infinite loop: 'options' would use GameStateJsonConverter, which would use 'options', which
Expand All @@ -157,8 +158,11 @@ private static JsonSerializerOptions GetJsonSerializerOptions()
// Define the "top-level" options to be returned. They use "converterOptions".
var options = new JsonSerializerOptions(converterOptions);

options.Converters.Add(new GameEventTypeConverter());

// Attach GameStateJsonConverter to 'options'. Now both 'options' and its converter use 'converterOptions'.
options.Converters.Add(new GameStateJsonConverter());


return options;
}
Expand Down

0 comments on commit fff963e

Please sign in to comment.