Files
riversong-code-showcase/Source/Engine/GameData/GameDatabase.cs
2026-05-21 16:04:49 +02:00

61 lines
1.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class GameDatabase : IGameDatabase
{
private Dictionary<int, object> _idLookup = new();
private Dictionary<Type, object> _typeLookup = new();
public void Add<T>(int id, T asset) where T : class
{
_idLookup.Add(id, asset);
InvokeAddToTypeLookupWithType(asset, asset.GetType());
if (asset is IGameDataRuntimeId runtimeId) runtimeId.RuntimeId = id;
}
private void InvokeAddToTypeLookupWithType(object asset, Type type)
{
var bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic;
var method = GetType().GetMethod(nameof(AddToTypeLookup), bindingAttr)!.MakeGenericMethod(type);
method.Invoke(this, new[] { asset });
}
private void AddToTypeLookup<T>(T asset)
{
var type = typeof(T);
if (!_typeLookup.TryGetValue(type, out var list))
{
list = new List<T>();
_typeLookup.Add(type, list);
}
((List<T>)list).Add(asset);
var nextType = type.BaseType;
if (nextType == typeof(object)) return;
InvokeAddToTypeLookupWithType(asset, nextType);
}
public T WithId<T>(int id) where T : class
{
return _idLookup.TryGetValue(id, out var asset) ? (T)asset : null;
}
public List<T> OfType<T>() where T : class
{
if (!_typeLookup.TryGetValue(typeof(T), out var assets))
{
assets = new List<T>();
_typeLookup.Add(typeof(T), assets);
}
return (List<T>)assets;
}
}
}