using System.Collections.Generic; using UnityEngine; using System.Linq; using System; namespace Amanotes.TripleSDK.Core { public partial class Bootstrap : MonoBehaviour { [SerializeField] private List m_Services = new List(); public GameObject[] dontDestroyObjects; public static Bootstrap Instance { get; private set; } private void Awake() { if (Instance != null) { GameObject.DestroyImmediate(gameObject); return; } Instance = this; LoadServiceConfigrations(); // inject runtime services ResolveRuntimeInjections(); foreach (GameObject o in dontDestroyObjects) { DontDestroyOnLoad(o); } DontDestroyOnLoad(gameObject); } private ServiceConfigurations serviceConfigurations; private void LoadServiceConfigrations() { var textAsset = Resources.Load("ServiceConfigurations"); if (textAsset == null) { serviceConfigurations = new ServiceConfigurations() { configs = new ServiceConfiguration[0] }; } else { serviceConfigurations = JsonUtility.FromJson(textAsset.text); if (serviceConfigurations.configs == null) serviceConfigurations.configs = new ServiceConfiguration[0]; } } // Use this for initialization void Start() { // inject services var comps = GetComponentsInChildren(); m_Services.AddRange(comps); var startups = Utils.FindTypesWithAttribute(); foreach (var type in startups) { var service = GetRequiredService(type); var startup = service as IStartup; if (startup != null) { startup.Startup(); } } } private void ResolveRuntimeInjections() { var types = Utils.FindTypesWithAttribute(); types = types.OrderBy(e => { var attr = (InjectServiceAttribute)Attribute.GetCustomAttribute(e, typeof(InjectServiceAttribute)); return attr.Order; }); foreach (var type in types) { InjectService(type); } } public bool IsServiceEnable(string serviceName) => serviceConfigurations.IsEnable(serviceName); private void InjectService(Type type) { InjectServiceAttribute attr = (InjectServiceAttribute)Attribute.GetCustomAttribute(type, typeof(InjectServiceAttribute)); var enable = serviceConfigurations.IsEnable(attr.Package); if (attr.Enable && enable) { if (attr.TargetPlatform == -1 || attr.TargetPlatform == (int)Application.platform) { if (type.IsSubclassOf(typeof(MonoBehaviour))) { var serviceObject = new GameObject(type.Name); if (String.IsNullOrEmpty(attr.GameObjectName)) { serviceObject.name = type.Name; } else { serviceObject.name = attr.GameObjectName; } var comp = serviceObject.AddComponent(type); DontDestroyOnLoad(serviceObject); m_Services.Add(comp); Development.Log("Inject " + type.Name); } else { AddService(type); } } } } public T GetRequiredService() { return m_Services.OfType().FirstOrDefault(); } public object GetRequiredService(Type type) { return m_Services.FirstOrDefault(t => type.IsInstanceOfType(t)); } public void AddService() where T : new() { var service = new T(); m_Services.Add(service); } public void AddService(Type type) { var service = Activator.CreateInstance(type); m_Services.Add(service); } public static T GetService() { return Instance.GetRequiredService(); } } }