Skip to content

Instantly share code, notes, and snippets.

@ruslux
Last active February 16, 2021 13:23
Show Gist options
  • Save ruslux/f97eac825fe5ae3099212dacb1e1bc32 to your computer and use it in GitHub Desktop.
Save ruslux/f97eac825fe5ae3099212dacb1e1bc32 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Reflection;
using Cysharp.Threading.Tasks;
using Oneman.DI;
using Object = UnityEngine.Object;
namespace Oneman
{
public class TeseHelper
{
public static Dictionary<Type, Object> Cache = new Dictionary<Type, Object>();
private static Dictionary<Type, bool> CacheWIP = new Dictionary<Type, bool>();
public static async UniTask<Object> FindOne(Type t)
{
while (CacheWIP.ContainsKey(t))
{
await UniTask.Delay(10);
}
if (!Cache.ContainsKey(t))
{
CacheWIP.Add(t, true);
Object obj = Object.FindObjectOfType(t, true);
Cache[t] = obj;
CacheWIP.Remove(t);
}
return Cache.ContainsKey(t) ? Cache[t] : null;
}
}
public class TeseBehaviour : MonoBehaviour
{
public bool IsInitializedTese;
public async void Start() {
Type t = GetType();
TeseHelper.Cache[t] = this;
await InjectDependencies();
CallStart();
}
private bool _injected = false;
private bool _injectWIP = false;
public bool IsInjected()
{
return _injected;
}
public async UniTask InjectDependencies()
{
if (_injected) return;
_injectWIP = true;
int triesToResolve = 200;
int delay = 5;
TypeInfo typeInfo = GetType().GetTypeInfo();
List<FieldInfo> injected = new List<FieldInfo>();
foreach (var field in typeInfo.GetFields(FieldsLookup))
{
var attr = field.GetCustomAttribute<Inject>();
if (attr != null)
{
Type t = field.FieldType;
Object obj = null;
while (obj == null && triesToResolve > 0)
{
triesToResolve--;
await UniTask.Delay(delay);
obj = await TeseHelper.FindOne(t);
if (obj != null)
{
field.SetValue(this, obj);
injected.Add(field);
break;
}
}
}
}
_injected = true;
_injectWIP = false;
}
void CallStart() {
if (IsInitializedTese) return;
OnStart();
IsInitializedTese = true;
}
public virtual async UniTask OnStart() {}
private const BindingFlags FieldsLookup =
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment