using System;
using UnityEngine;
namespace UVC.Core
{
#region Singleton
///
/// MonoBehaviour가 아닌 일반 클래스를 위한 싱글톤 패턴
/// 지연 초기화(lazy initialization)를 사용하여 필요할 때만 인스턴스 생성
///
/// 싱글톤으로 구현할 클래스 타입(반드시 기본 생성자가 있어야 함)
///
///
/// public class JournalClass
/// {
/// // 클래스 내용
/// }
///
/// // 싱글톤 사용 예시
/// var journalSingleton = Singleton.Instance;
///
///
public class Singleton where T : class, new()
{
///
/// 싱글톤 인스턴스를 지연 초기화 방식으로 생성
///
protected static readonly Lazy instance = new Lazy(() => new T());
///
/// 외부에서 생성자 직접 호출 방지
///
protected Singleton(){}
///
/// 싱글톤 인스턴스에 접근하기 위한 전역 접근점
///
///
///
/// // 싱글톤 인스턴스 접근 방법
/// MyClass instance = Singleton.Instance;
///
///
public static T Instance { get { return instance.Value; } }
}
#endregion
#region SingletonApp
///
/// 씬 전환 시에도 유지되는 MonoBehaviour 기반 싱글톤
/// DontDestroyOnLoad를 통해 씬 전환 시에도 객체가 파괴되지 않음
///
/// MonoBehaviour를 상속받는 컴포넌트 타입
///
///
/// // 사용 예시
/// public class AppMain : SingletonApp
/// {
/// protected override void Init()
/// {
/// // 초기화 코드 작성
/// Debug.Log("AppMain 초기화 완료");
/// }
/// }
///
/// // 접근 방법
/// AppMain.Instance.SomeMethod();
///
///
public abstract class SingletonApp : UnityEngine.MonoBehaviour where T : UnityEngine.Component
{
///
/// 싱글톤 인스턴스
///
private static T instance;
///
/// 싱글톤 인스턴스에 접근하기 위한 전역 접근점
/// 인스턴스가 없는 경우 자동으로 생성함
///
///
///
/// // 접근 방법
/// MyAppSingleton.Instance.DoSomething();
///
///
public static T Instance
{
get
{
if (instance == null)
{
instance = (T)GameObject.FindFirstObjectByType(typeof(T)); // Updated to use FindFirstObjectByType
if (instance == null)
{
// 씬에 인스턴스가 없으면 새로 생성
instance = new GameObject(string.Format(typeof(T) + "")).AddComponent();
}
}
return instance;
}
}
///
/// 컴포넌트가 활성화될 때 호출되는 Unity 메소드
/// 인스턴스 설정 및 씬 전환 시 객체 유지 설정
///
protected virtual void Awake()
{
if (instance == null)
{
instance = this as T;
}
// 인스턴스 초기화 호출
(instance as SingletonApp).Init();
//if (transform.parent != null && transform.root != null)
//{
// DontDestroyOnLoad(transform.root.gameObject);
//}
//else
{
// 씬 전환 시에도 파괴되지 않도록 설정
DontDestroyOnLoad(gameObject);
}
}
///
/// 인스턴스화될 때 호출되는 초기화 메소드
/// 자식 클래스에서 오버라이드하여 초기화 로직 구현
///
///
///
/// protected override void Init()
/// {
/// // 초기화 코드 작성
/// playerData = new PlayerData();
/// LoadSettings();
/// }
///
///
protected virtual void Init() { }
}
#endregion
#region SingletonScene
///
/// 현재 씬 내에서만 유지되는 MonoBehaviour 기반 싱글톤
/// 씬 전환 시 인스턴스가 파괴됨
///
/// MonoBehaviour를 상속받는 컴포넌트 타입
///
///
/// // 사용 예시
/// public class SceneMain : SingletonScene
/// {
/// protected override void Init()
/// {
/// // 초기화 코드 작성
/// Debug.Log("SceneMain 초기화 완료");
/// }
/// }
///
/// // 접근 방법
/// SceneMain.Instance.SomeMethod();
///
///
public abstract class SingletonScene : UnityEngine.MonoBehaviour where T : UnityEngine.Component
{
///
/// 싱글톤 인스턴스
///
private static T instance;
///
/// 싱글톤 인스턴스에 접근하기 위한 전역 접근점
/// 인스턴스가 없는 경우 자동으로 생성함
///
///
///
/// // 접근 방법
/// MySceneSingleton.Instance.DoSomething();
///
///
public static T Instance
{
get
{
if (instance == null)
{
instance = (T)GameObject.FindFirstObjectByType(typeof(T)); // Updated to use FindFirstObjectByType
if (instance == null)
{
// 씬에 인스턴스가 없으면 새로 생성
instance = new GameObject(string.Format(typeof(T) + "")).AddComponent();
}
}
return instance;
}
}
///
/// 컴포넌트가 활성화될 때 호출되는 Unity 메소드
/// 인스턴스 설정 및 초기화
///
protected virtual void Awake()
{
if (instance == null)
{
instance = this as T;
}
// 인스턴스 초기화 호출
(instance as SingletonScene).Init();
}
///
/// 인스턴스화될 때 호출되는 초기화 메소드
/// 자식 클래스에서 오버라이드하여 초기화 로직 구현
///
///
///
/// protected override void Init()
/// {
/// // 초기화 코드 작성
/// uiManager = GetComponent();
/// SetupEventListeners();
/// }
///
///
protected virtual void Init() { }
///
/// 컴포넌트가 파괴될 때 호출되는 Unity 메소드
/// 싱글톤 인스턴스 참조 해제
///
protected virtual void OnDestroy()
{
instance = null;
}
}
#endregion
}