riversong code showcase
This commit is contained in:
61
Source/Engine/GameData/GameDatabase.cs
Normal file
61
Source/Engine/GameData/GameDatabase.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user