【Unity Epitome】C#泛型單例模塊

SingletonCreator:單例創建

using System.Reflection;
using UnityEngine;

namespace Epitome
{
    /// <summary>
    /// Singleton Creator.
    /// </summary>
    public static class SingletonCreator
    {
        /// <summary>
        /// Build a Singleton.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T CreateSingleton<T>() where T : class, ISingleton
        {
            // 獲取私有構造函數
            var ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);

            // 獲取無參構造函數
            var ctor = Array.Find(ctors, a => a.GetParameters().Length == 0);

            if (ctor == null)
            {
                throw new SingletonException("Non-Public Constructor() not found! in " + typeof(T));
            }

            T value = ctor.Invoke(null) as T;

            value.OnSingletonInit();

            return value;
        }

        /// <summary>
        /// Build a MonoSingleton.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T CreateMonoSingleton<T>() where T : MonoBehaviour
        {
            T value = MonoBehaviour.FindObjectOfType<T>();

            if (MonoBehaviour.FindObjectsOfType<T>().Length > 1)
            {
                throw new SingletonException(typeof(T) + " object more than 1!");
            }

            if (value == null)
            {
                string name = typeof(T).Name;
                GameObject game = GameObject.Find(name);
                if (game == null) game = new GameObject(name);

                value = game.AddComponent<T>();
            }

            return value;
        }
    }
}

Singleton:單例類

namespace Epitome
{
    /// <summary>
    /// Singleton interface.
    /// </summary>
    public interface ISingleton
    {
        /// <summary>
        /// Singleton initialize.
        /// </summary>
        void OnSingletonInit();
    }

    /// <summary>
    /// Singleton base class. Based on the reflection. Thread safety.
    /// </summary>
    public abstract class Singleton<T>: ISingleton where T : Singleton<T>
    {
        /// <summary>
        /// Initializes a new instance of the Epitome.Singleton class.
        /// </summary>
        protected Singleton() { }

        private static T _Instance = null;

        private static readonly object sysLock = new object();

        /// <summary>
        /// Get an instance of the Epitome.Singleton class
        /// </summary>
        public static T Instance
        {
            get
            {
                lock (sysLock)
                {
                    if (_Instance == null)
                    {
                        _Instance = SingletonCreator.CreateSingleton<T>();
                    }
                }

                return _Instance;
            }
        }

        /// <summary>
        /// Singleton initialize.
        /// </summary>
        public virtual void OnSingletonInit() { }
    }
}

MonoSingleton:MonoBehaviour單例類

using UnityEngine;

namespace Epitome
{
    /// <summary>
    /// MonoBehaviour singleton base class. Thread safety.
    /// </summary>
    public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
    {
        private static T _Instance = null;

        private static readonly object sysLock = new object();

        /// <summary>
        /// Get an instance of the Epitome.MonoSingletond class.
        /// </summary>
        public static T Instance
        {
            get
            {
                lock (sysLock)
                {
                    if (_Instance == null)
                    {
                        _Instance = SingletonCreator.CreateMonoSingleton<T>();
                    }
                }
                return _Instance;
            }
        }

        /// <summary>
        /// Makes the Epitome.MonoSingleton object not be destroyed automatically when loading a new scene.
        /// </summary>
        protected void DontDestroyOnLoad()
        {
            DontDestroyOnLoad(this);
        }

        /// <summary>
        /// This function is called when the Epitome.MonoSingleton object is destroyed.
        /// </summary>
        protected virtual void OnDestroy()
        {
            _Instance = null;
        }
    }
}

SingletonException:單例錯誤處理類

using System;

namespace Epitome
{
    /// <summary>
    /// Represents an error that occurred during the execution of the singleton.
    /// </summary>
    public class SingletonException : Exception
    {
        /// <summary>
        /// Initializes a new instance of the Epitome.SingletonException class with a specified error message.
        /// </summary>
        /// <param name="message">The message that describes the error.</param>
        public SingletonException(string message) : base(message)
        {

        }
    }
}

Examples:單例使用範例

using System;

public class Examples : Singleton<Examples>
{
	private Examples() { }

	public override void OnSingletonInit() { }
}
using System;

public class Examples : MonoSingleton<Examples>
{
	private void Awake() { }
	private void Start() { }
	private void Update() { }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章