using System; using System.Collections.Generic; using System.Reflection; namespace DanieleMarotta.RiversongCodeShowcase { public class GameDatabase : IGameDatabase { private Dictionary _idLookup = new(); private Dictionary _typeLookup = new(); public void Add(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 asset) { var type = typeof(T); if (!_typeLookup.TryGetValue(type, out var list)) { list = new List(); _typeLookup.Add(type, list); } ((List)list).Add(asset); var nextType = type.BaseType; if (nextType == typeof(object)) return; InvokeAddToTypeLookupWithType(asset, nextType); } public T WithId(int id) where T : class { return _idLookup.TryGetValue(id, out var asset) ? (T)asset : null; } public List OfType() where T : class { if (!_typeLookup.TryGetValue(typeof(T), out var assets)) { assets = new List(); _typeLookup.Add(typeof(T), assets); } return (List)assets; } } }