74 lines
2.6 KiB
C#
74 lines
2.6 KiB
C#
|
using System.Collections.Immutable;
|
|||
|
using System.Reflection;
|
|||
|
using System.Text.Json;
|
|||
|
using Microsoft.Extensions.Logging;
|
|||
|
using RPG.GameCore.Excel.Attributes;
|
|||
|
|
|||
|
namespace RPG.GameCore.Excel;
|
|||
|
public class ExcelTables
|
|||
|
{
|
|||
|
private readonly ILogger _logger;
|
|||
|
private ImmutableDictionary<ExcelType, ImmutableArray<ExcelRow>>? _tables;
|
|||
|
|
|||
|
public ExcelTables(ILogger<ExcelTables> logger)
|
|||
|
{
|
|||
|
_logger = logger;
|
|||
|
}
|
|||
|
|
|||
|
public TExcelRow? GetExcelRow<TExcelRow>(ExcelType type, int id) where TExcelRow : ExcelRow
|
|||
|
{
|
|||
|
if (_tables == null) throw new InvalidOperationException("GetExcelRow called when ExcelTables not loaded.");
|
|||
|
|
|||
|
if (_tables.TryGetValue(type, out ImmutableArray<ExcelRow> rows))
|
|||
|
{
|
|||
|
return rows.SingleOrDefault(row => row.Id == id) as TExcelRow;
|
|||
|
}
|
|||
|
|
|||
|
throw new ArgumentException($"GetExcelRow: table for excel type not found {type}");
|
|||
|
}
|
|||
|
|
|||
|
public IEnumerable<ExcelRow> GetAllRows(ExcelType type)
|
|||
|
{
|
|||
|
if (_tables == null) throw new InvalidOperationException("GetAllRows called when ExcelTables not loaded.");
|
|||
|
|
|||
|
if (_tables.TryGetValue(type, out ImmutableArray<ExcelRow> rows))
|
|||
|
{
|
|||
|
return rows;
|
|||
|
}
|
|||
|
|
|||
|
throw new ArgumentException($"GetAllRows: table for excel type not found {type}");
|
|||
|
}
|
|||
|
|
|||
|
public void Load()
|
|||
|
{
|
|||
|
ImmutableDictionary<ExcelType, ImmutableArray<ExcelRow>>.Builder tables = ImmutableDictionary.CreateBuilder<ExcelType, ImmutableArray<ExcelRow>>();
|
|||
|
|
|||
|
IEnumerable<Type> types = Assembly.GetExecutingAssembly().GetTypes()
|
|||
|
.Where(type => type.GetCustomAttribute<ExcelTableAttribute>() != null);
|
|||
|
|
|||
|
foreach (Type type in types)
|
|||
|
{
|
|||
|
ExcelTableAttribute attribute = type.GetCustomAttribute<ExcelTableAttribute>()!;
|
|||
|
|
|||
|
// TODO: asset provider
|
|||
|
|
|||
|
JsonDocument tableJson = JsonDocument.Parse(File.ReadAllText("data/excel/" + attribute.Path));
|
|||
|
ImmutableArray<ExcelRow>.Builder rows = ImmutableArray.CreateBuilder<ExcelRow>();
|
|||
|
|
|||
|
foreach (JsonProperty property in tableJson.RootElement.EnumerateObject())
|
|||
|
{
|
|||
|
if (property.Value.ValueKind != JsonValueKind.Object)
|
|||
|
throw new ArgumentException($"Failed to load excel: expected an object, got {property.Value.ValueKind}");
|
|||
|
|
|||
|
ExcelRow row = (property.Value.Deserialize(type) as ExcelRow)!;
|
|||
|
rows.Add(row);
|
|||
|
}
|
|||
|
|
|||
|
tables.Add(attribute.Type, rows.ToImmutable());
|
|||
|
}
|
|||
|
|
|||
|
_tables = tables.ToImmutable();
|
|||
|
_logger.LogInformation("Loaded {count} excel tables", _tables.Count);
|
|||
|
}
|
|||
|
}
|