Skip to content

Commit

Permalink
fix: MonoSingleton (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
stan-osipov authored Jul 30, 2020
1 parent 8d696f3 commit 27143d0
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 46 deletions.
76 changes: 42 additions & 34 deletions Runtime/Patterns/Singleton/MonoSingleton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@

namespace StansAssets.Foundation.Patterns
{
/// <summary>
/// <summary>
/// Singleton pattern implementation.
/// Can be used with classes extended from a MonoBehaviour.
/// Once instance is found or created, game object will be marked as DontDestroyOnLoadю
/// </summary>
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
static T s_Instance;
static bool s_ApplicationIsQuitting;
{
static T s_Instance;
static bool s_ApplicationIsQuitting;
static bool s_IsDestroyed;


protected virtual void Awake()
{
Expand All @@ -25,11 +27,13 @@ protected virtual void Awake()
/// </summary>
public static T Instance
{
get
{
if (s_ApplicationIsQuitting)
{
Debug.LogError($"{typeof(T)} [MonoSingleton] is already destroyed. Please check HasInstance before accessing instance in the destructor.");
get
{
if (s_ApplicationIsQuitting)
{
Debug.LogError(
$"{typeof(T)} [MonoSingleton] is already destroyed. " +
$"Please check {nameof(HasInstance)} or {nameof(IsDestroyed)} before accessing instance in the destructor.");
return null;
}

Expand All @@ -39,9 +43,10 @@ public static T Instance
if (s_Instance == null)
Instantiate();
}
return s_Instance;
}
}

return s_Instance;
}
}

/// <summary>
/// Methods will create new object Instantiate
Expand All @@ -57,33 +62,36 @@ public static void Instantiate()
}

/// <summary>
/// True if Singleton Instance exists
/// Returns `true` if Singleton Instance exists.
/// </summary>
public static bool HasInstance => !IsDestroyed;
public static bool HasInstance => s_Instance != null;

/// <summary>
/// True if Singleton Instance doesn't exist
/// If this property returns `true` it means that object with explicitly destroyed.
/// This could happen if Destroy function was called for this object or if it was
/// automatically destroyed during the `ApplicationQuit`.
/// </summary>
public static bool IsDestroyed => s_Instance == null;
public static bool IsDestroyed => s_IsDestroyed;

/// <summary>
/// When Unity quits, it destroys objects in a random order.
/// In principle, a Singleton is only destroyed when application quits.
/// If any script calls Instance after it have been destroyed,
/// it will create a buggy ghost object that will stay on the Editor scene
/// even after stopping playing the Application. Really bad!
/// So, this was made to be sure we're not creating that buggy ghost object.
/// </summary>
protected virtual void OnDestroy ()
/// When Unity quits, it destroys objects in a random order.
/// In principle, a Singleton is only destroyed when application quits.
/// If any script calls Instance after it have been destroyed,
/// it will create a buggy ghost object that will stay on the Editor scene
/// even after stopping playing the Application. Really bad!
/// So, this was made to be sure we're not creating that buggy ghost object.
/// </summary>
protected virtual void OnDestroy()
{
s_Instance = null;
s_ApplicationIsQuitting = true;
}
s_Instance = null;
s_IsDestroyed = true;
}

protected virtual void OnApplicationQuit ()
{
s_Instance = null;
s_ApplicationIsQuitting = true;
}
}
}
protected virtual void OnApplicationQuit()
{
s_Instance = null;
s_IsDestroyed = true;
s_ApplicationIsQuitting = true;
}
}
}
24 changes: 12 additions & 12 deletions Runtime/Patterns/Singleton/Singleton.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
namespace StansAssets.Foundation.Patterns
{
/// <summary>
/// Singleton pattern implementation.
/// </summary>
public abstract class Singleton<T> where T : Singleton<T>, new()
{
static T s_Instance;
/// <summary>
/// Singleton pattern implementation.
/// </summary>
public abstract class Singleton<T> where T : Singleton<T>, new()
{
static T s_Instance;

/// <summary>
/// Returns a singleton class instance.
/// </summary>
public static T Instance => s_Instance ?? (s_Instance = new T());
}
}
/// <summary>
/// Returns a singleton class instance.
/// </summary>
public static T Instance => s_Instance ?? (s_Instance = new T());
}
}

0 comments on commit 27143d0

Please sign in to comment.