131 lines
3.6 KiB
C#
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."
|
|
);
|
|
}
|
|
}
|