// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using UnityEngine;

namespace XRTool.Util
{
    /// <summary>
    /// Unity的单例
    /// Singleton behaviour class, used for components that should only have one instance
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class UnitySingleton<T> : MonoBehaviour where T : UnitySingleton<T>
    {
        public static event Action InitComplte;
        public static event Action DeleteSingle;
        private static T instance;
        public static T Instance
        {
            get
            {

                return instance;
            }
        }

        /// <summary>
        /// Returns whether the instance has been initialized or not.
        /// </summary>
        public static bool IsInitialized
        {
            get
            {
                return instance != null;
            }
        }

        /// <summary>
        /// 强制实例化某对象
        /// 注意，尽量避免在多处使用或者在awake中使用，避免产生多个实例化多项
        /// </summary>
        public static T ForceInstance()
        {
            if (!instance)
            {
                GameObject obj = new GameObject();
                instance= obj.AddComponent<T>();
            }
            return instance;
        }

        /// <summary>
        /// Base awake method that sets the singleton's unique instance.
        /// </summary>
        protected virtual void Awake()
        {
            if (instance != null && instance.gameObject != gameObject)
            {
                Debug.LogErrorFormat("{0}为单例对象，但是场景中存在多个{0}，已删除本对象", GetType().Name);
                Destroy(gameObject);
            }
            else
            {
                DeleteSingle = null;
                instance = (T)this;
                InitComplte?.Invoke();
            }
        }
        /// <summary>
        /// 对象被销毁时的事件传递
        /// </summary>
        protected virtual void OnDestroy()
        {
            if (instance == this)
            {
                instance = null;
                DeleteSingle?.Invoke();
            }
            InitComplte = null;
        }
    }
}