61 lines
1.8 KiB
C#
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;
|
|
}
|
|
}
|
|
} |