Movement/Config/MovementFactory.cs

84 lines
2.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace Syntriax.Modules.Movement.Config
{
public class MovementFactory : MonoBehaviour
{
private const string Name = "Movement Factory";
private const int InitialCapacity = 64;
private static MovementFactory _instance = null;
public static MovementFactory Instance
{
get
{
if (_instance == null)
_instance = new GameObject(Name).AddComponent<MovementFactory>();
return _instance;
}
}
private Dictionary<string, Type> _types = null;
public Dictionary<string, Type> Types
{
get
{
if (_types == null)
Initialize();
return _types;
}
}
private Func<Type, bool> predicate = type => !type.IsAbstract && type.IsSubclassOf(typeof(MonoBehaviour));
private void Start()
{
if (_instance == this)
return;
Destroy(this);
}
public void Initialize()
{
if (_types == null)
_types = new Dictionary<string, Type>(InitialCapacity);
Reset();
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
AddAssemblyToFactory(assembly);
}
public void Reset() => _types?.Clear();
public void AddAssemblyToFactory(Assembly assembly)
{
foreach (Type type in assembly.GetTypes().Where(predicate))
Types.Add(GetTypeName(type), type);
}
public Component AddToGameObject(GameObject gameObject, string name)
{
if (!Types.ContainsKey(name))
throw new ArgumentException($"The key \"{ name }\" does not exists in the current { Name }");
return gameObject.AddComponent(Types[name]);
}
public string GetTypeName(Type type)
{
if (string.IsNullOrEmpty(type.Namespace))
return type.Name;
return $"{ type.Namespace }.{ type.Name }";
}
}
}