94 lines
3.0 KiB
C#
94 lines
3.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
|
|
namespace Syntriax.Modules.Movement
|
|
{
|
|
public abstract class TypeFactoryBaseMonoBehaviour<T, T2> : MonoBehaviour
|
|
where T : TypeFactoryBaseMonoBehaviour<T, T2>
|
|
where T2 : class
|
|
{
|
|
protected abstract int InitialCapacity { get; }
|
|
|
|
private Func<Type, bool> predicate => type => type.IsClass && !type.IsAbstract && type.IsSubclassOf(typeof(MonoBehaviour)) && type.GetInterfaces().Contains(typeof(T2));
|
|
private string factoryName => typeof(T).Name;
|
|
private static TypeFactoryBaseMonoBehaviour<T, T2> _instance = null;
|
|
public static TypeFactoryBaseMonoBehaviour<T, T2> Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
{
|
|
GameObject newGameObject = new GameObject();
|
|
TypeFactoryBaseMonoBehaviour<T, T2> typeFactoryBase = newGameObject.AddComponent<T>();
|
|
newGameObject.name = typeFactoryBase.factoryName;
|
|
_instance = typeFactoryBase;
|
|
}
|
|
|
|
return _instance;
|
|
}
|
|
}
|
|
|
|
private Dictionary<string, Type> _types = null;
|
|
public Dictionary<string, Type> Types
|
|
{
|
|
get
|
|
{
|
|
Initialize();
|
|
return _types;
|
|
}
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
if (_types != null)
|
|
return;
|
|
|
|
_types = new Dictionary<string, Type>(InitialCapacity);
|
|
|
|
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
foreach (Type type in assembly.GetTypes().Where(predicate))
|
|
_types.Add(GetTypeClassName(type), type);
|
|
}
|
|
|
|
|
|
public virtual void Start()
|
|
{
|
|
if (_instance != this)
|
|
Destroy(this);
|
|
}
|
|
|
|
public void AddTypes(List<(string ClassName, Type TypeReference)> types)
|
|
{
|
|
foreach (var pair in types)
|
|
AddType(pair.ClassName, pair.TypeReference);
|
|
}
|
|
|
|
public void AddType(string className, Type type)
|
|
{
|
|
if (Types.ContainsKey(className))
|
|
throw new ArgumentException($"Component with the key \"{ className }\" already been loaded!");
|
|
|
|
Types.Add(className, type);
|
|
}
|
|
|
|
public void LoadTypesFromAssembly(Assembly assembly)
|
|
{
|
|
foreach (Type type in assembly.GetTypes().Where(predicate))
|
|
AddType(GetTypeClassName(type), type);
|
|
}
|
|
|
|
public T2 AddComponentToGameObject(GameObject gameObject, string className)
|
|
{
|
|
if (!Types.ContainsKey(className))
|
|
throw new ArgumentException($"Component with the key \"{ className }\" does not exist!");
|
|
|
|
return gameObject.AddComponent(Types[className]) as T2;
|
|
}
|
|
|
|
private static string GetTypeClassName(Type type) => $"{ type.Namespace }.{ type.Name }";
|
|
}
|
|
}
|