106 lines
3.3 KiB
C#
106 lines
3.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using mROA.Abstract;
|
|
using mROA.Implementation.Attributes;
|
|
|
|
namespace mROA.Implementation.Backend
|
|
{
|
|
public class ContextRepository : IContextRepository
|
|
{
|
|
private int _debugId = -1;
|
|
private static int LastDebugId = -1;
|
|
// [CanBeNull]
|
|
private Dictionary<int, object?> _singletons;
|
|
private object?[] _storage;
|
|
|
|
private Task<int> _lastIndexFinder = Task.FromResult(0);
|
|
|
|
private const int StartupSize = 1024;
|
|
private const int GrowSize = 128;
|
|
|
|
|
|
public ContextRepository()
|
|
{
|
|
_storage = new object[StartupSize];
|
|
}
|
|
|
|
public void FillSingletons(params Assembly[] assembly)
|
|
{
|
|
var types = assembly.SelectMany(x => x.GetTypes()).Where(type =>
|
|
type is { IsClass: true, IsAbstract: false, IsGenericType: false } &&
|
|
type.GetCustomAttributes(typeof(SharedObjectSingletonAttribute), true).Length > 0);
|
|
_singletons =
|
|
types.ToDictionary(
|
|
t => t.GetInterfaces().FirstOrDefault(i =>
|
|
i.GetCustomAttributes(typeof(SharedObjectInterfaceAttribute), true).Length > 0)!.GetHashCode(),
|
|
Activator.CreateInstance);
|
|
}
|
|
|
|
public int ResisterObject(object o)
|
|
{
|
|
if (!_lastIndexFinder.IsCompleted)
|
|
_lastIndexFinder.Wait();
|
|
|
|
_storage[_lastIndexFinder.Result] = o;
|
|
|
|
var last = _lastIndexFinder.Result;
|
|
_lastIndexFinder = Task.Run(FindLastIndex);
|
|
|
|
return last;
|
|
}
|
|
|
|
public void ClearObject(int id)
|
|
{
|
|
_storage[id] = null;
|
|
_lastIndexFinder = Task.FromResult(id);
|
|
}
|
|
|
|
public T GetObjectBySharedObject<T>(SharedObject<T> sharedObject)
|
|
{
|
|
return (T)GetObject(sharedObject.Identifier.ContextId);
|
|
}
|
|
|
|
public object GetObject(int id)
|
|
{
|
|
// Debug.Log($"Reading object {id} from repository with debug ID {_debugId}");
|
|
return (id == -1 || _storage.Length <= id ? null : _storage[id]) ?? throw new NullReferenceException();
|
|
}
|
|
|
|
public T GetObject<T>(int id)
|
|
{
|
|
return id == -1 || _storage.Length <= id ? throw new NullReferenceException("Cannot find that object. It is null"): (T)_storage[id]!;
|
|
}
|
|
|
|
public object GetSingleObject(Type type)
|
|
{
|
|
return _singletons.GetValueOrDefault(type.GetHashCode()) ?? throw new ArgumentException("Unregistered singleton type");
|
|
}
|
|
|
|
public int GetObjectIndex(object o)
|
|
{
|
|
var index = Array.IndexOf(_storage, o);
|
|
return index == -1 ? ResisterObject(o) : index;
|
|
}
|
|
|
|
private int FindLastIndex()
|
|
{
|
|
for (var i = 0; i < _storage.Length; i++)
|
|
{
|
|
if (_storage[i] is null)
|
|
return i;
|
|
}
|
|
|
|
var nextStorage = new object[_storage.Length + GrowSize];
|
|
Array.Copy(_storage, nextStorage, _storage.Length);
|
|
_storage = nextStorage;
|
|
return _storage.Length;
|
|
}
|
|
public void Inject<T>(T dependency)
|
|
{
|
|
}
|
|
|
|
}
|
|
} |