Files
Pf2eDataScrapper/Pf2eViewer/Converters/EntityConverter.cs
T

131 lines
3.6 KiB
C#

using System.ComponentModel;
using Newtonsoft.Json;
using Pf2eModel;
using Pf2eModel.Model;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Common.I18n;
using Pf2eModel.Model.Structure;
namespace Pf2eViewer.Converters;
internal class EntityConverter : JsonConverter
{
private readonly Pf2eDbContext _context = new();
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Entity) || objectType.IsAssignableTo(typeof(IEntity));
}
private Dictionary<string, object?> DictionarySerialization(object source)
{
Dictionary<string, object?> dictionary = [];
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
{
if (property.Attributes.OfType<JsonIgnoreAttribute>().Any())
{
continue;
}
object? v = property.GetValue(source);
dictionary.Add(property.Name, v);
}
return dictionary;
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
serializer.Serialize(writer, null);
return;
}
Dictionary<string, object?> dictionary = DictionarySerialization(value);
if (value.GetType() != typeof(Entity))
{
dictionary.Remove("Entity");
Processor? processor = _processors.FirstOrDefault(p => p.Type == value.GetType());
processor?.Process(dictionary, (IEntity)value, this);
}
else
{
dictionary.Remove("Description");
}
serializer.Serialize(writer, dictionary);
}
private abstract class Processor
{
public abstract Type Type { get; }
public abstract void Process(
Dictionary<string, object?> dictionary,
IEntity entity,
EntityConverter converter
);
}
private class Processor<T>(Action<Dictionary<string, object?>, T, EntityConverter> method)
: Processor
where T : IEntity
{
public override Type Type { get; } = typeof(T);
public override void Process(
Dictionary<string, object?> dictionary,
IEntity entity,
EntityConverter converter
)
{
method.Invoke(dictionary, (T)entity, converter);
}
}
private readonly ICollection<Processor> _processors =
[
new Processor<Trait>(
(dictionary, trait, converter) =>
{
LocaleString name =
// ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract
trait.Entity?.Name
?? converter
._context.Entities.Where(e => e.Id == trait.Id)
.Select(e => e.Name)
.FirstOrDefault()!;
dictionary.Remove("Entity");
dictionary.Remove("Entities");
dictionary.Add("Name", name.ToString());
}
),
new Processor<Subclass>(
(dictionary, _, _) =>
{
dictionary.Remove("Group");
}
),
];
public override bool CanRead => false;
public override object ReadJson(
JsonReader reader,
Type objectType,
object? existingValue,
JsonSerializer serializer
)
{
throw new NotImplementedException(
"Unnecessary because CanRead is false. The type will skip the converter."
);
}
}