Studio 모달 완료
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UVC.Core
|
||||
@@ -18,7 +19,7 @@ namespace UVC.Core
|
||||
/// <para><b>[ 역할 ]</b></para>
|
||||
/// <list type="bullet">
|
||||
/// <item><description>Injector 인스턴스 생성 및 관리</description></item>
|
||||
/// <item><description>App 라이프사이클 서비스 등록</description></item>
|
||||
/// <item><description>App 라이프사이클 서비스 등록 (동기/비동기)</description></item>
|
||||
/// <item><description>씬 로드 시 자동 의존성 주입 (선택적)</description></item>
|
||||
/// <item><description>서비스 해결을 위한 편의 메서드 제공</description></item>
|
||||
/// </list>
|
||||
@@ -30,31 +31,41 @@ namespace UVC.Core
|
||||
/// <item><description>Inspector에서 App Prefab 목록 설정 (선택)</description></item>
|
||||
/// </list>
|
||||
///
|
||||
/// <para><b>[ 사용 방법 - 상속 ]</b></para>
|
||||
/// <para><b>[ 사용 방법 - 동기 등록 ]</b></para>
|
||||
/// <code>
|
||||
/// public class MyAppContext : InjectorAppContext
|
||||
/// {
|
||||
/// [SerializeField] private UIManager uiManagerPrefab;
|
||||
///
|
||||
/// protected override void RegisterServices()
|
||||
/// {
|
||||
/// base.RegisterServices();
|
||||
///
|
||||
/// // Type A: 순수 C# 클래스
|
||||
/// Injector.Register<ILogService, ConsoleLogger>(ServiceLifetime.App);
|
||||
///
|
||||
/// // Type B: MonoBehaviour 동적 생성
|
||||
/// Injector.Register<IAudioManager, AudioManager>(ServiceLifetime.App);
|
||||
///
|
||||
/// // Type C: Prefab 기반
|
||||
/// Injector.RegisterPrefab<IUIManager>(uiManagerPrefab.gameObject, ServiceLifetime.App);
|
||||
///
|
||||
/// // Type D: Singleton 연동
|
||||
/// Injector.RegisterSingleton<SettingsManager>();
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
///
|
||||
/// <para><b>[ 사용 방법 - 비동기 등록 ]</b></para>
|
||||
/// <code>
|
||||
/// public class MyAppContext : InjectorAppContext
|
||||
/// {
|
||||
/// protected override async UniTask RegisterServicesAsync()
|
||||
/// {
|
||||
/// // 비동기 로드가 필요한 서비스
|
||||
/// var setting = new Setting();
|
||||
/// var library = new Library();
|
||||
///
|
||||
/// await UniTask.WhenAll(
|
||||
/// setting.LoadAsync(),
|
||||
/// library.LoadAllParallelAsync()
|
||||
/// );
|
||||
///
|
||||
/// Injector.RegisterInstance<Setting>(setting);
|
||||
/// Injector.RegisterInstance<Library>(library);
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
///
|
||||
/// <para><b>[ 서비스 접근 방법 ]</b></para>
|
||||
/// <code>
|
||||
/// // 방법 1: [Inject] 어트리뷰트 (권장)
|
||||
@@ -69,8 +80,20 @@ namespace UVC.Core
|
||||
///
|
||||
/// <para><b>[ 이벤트 ]</b></para>
|
||||
/// <list type="bullet">
|
||||
/// <item><description>OnInjectorInitialized: Injector 생성 직후 발생</description></item>
|
||||
/// <item><description>OnServicesRegistered: 서비스 등록 완료 후 발생</description></item>
|
||||
/// <item><description>OnInjectorInitialized: Injector 생성 및 모든 서비스 등록 완료 후 발생</description></item>
|
||||
/// <item><description>OnServicesRegistered: 동기 서비스 등록 완료 후 발생</description></item>
|
||||
/// <item><description>OnServicesRegisteredAsync: 비동기 서비스 등록 완료 후 발생</description></item>
|
||||
/// </list>
|
||||
///
|
||||
/// <para><b>[ 초기화 순서 ]</b></para>
|
||||
/// <list type="number">
|
||||
/// <item><description>Injector 인스턴스 생성</description></item>
|
||||
/// <item><description>RegisterServices() 호출 (동기)</description></item>
|
||||
/// <item><description>OnServicesRegistered 이벤트 발생</description></item>
|
||||
/// <item><description>RegisterServicesAsync() 호출 (비동기) - await 대기</description></item>
|
||||
/// <item><description>OnServicesRegisteredAsync 이벤트 발생</description></item>
|
||||
/// <item><description>IsInitialized = true</description></item>
|
||||
/// <item><description>OnInjectorInitialized 이벤트 발생</description></item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Injector"/>
|
||||
@@ -108,7 +131,7 @@ namespace UVC.Core
|
||||
/// 초기화 완료 여부
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Init() 완료 후 true가 됩니다.</para>
|
||||
/// <para>동기 및 비동기 서비스 등록이 모두 완료된 후 true가 됩니다.</para>
|
||||
/// <para>InjectorSceneContext는 이 값이 true가 될 때까지 대기합니다.</para>
|
||||
/// </remarks>
|
||||
public bool IsInitialized { get; private set; }
|
||||
@@ -121,19 +144,27 @@ namespace UVC.Core
|
||||
/// Injector 초기화 완료 시 발생
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Injector 인스턴스가 생성되고 서비스 등록이 완료된 직후 발생합니다.</para>
|
||||
/// <para>동기 및 비동기 서비스 등록이 모두 완료된 직후 발생합니다.</para>
|
||||
/// </remarks>
|
||||
public event System.Action OnInjectorInitialized;
|
||||
|
||||
/// <summary>
|
||||
/// 서비스 등록 완료 시 발생
|
||||
/// 동기 서비스 등록 완료 시 발생
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>RegisterServices() 메서드 완료 후 발생합니다.</para>
|
||||
/// <para>이 이벤트 이후부터 등록된 서비스들을 Resolve할 수 있습니다.</para>
|
||||
/// <para>비동기 등록 전에 발생합니다.</para>
|
||||
/// </remarks>
|
||||
public event System.Action OnServicesRegistered;
|
||||
|
||||
/// <summary>
|
||||
/// 비동기 서비스 등록 완료 시 발생
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>RegisterServicesAsync() 메서드 완료 후 발생합니다.</para>
|
||||
/// </remarks>
|
||||
public event System.Action OnServicesRegisteredAsync;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lifecycle
|
||||
@@ -142,12 +173,24 @@ namespace UVC.Core
|
||||
{
|
||||
base.Init();
|
||||
|
||||
// 비동기 초기화 시작
|
||||
InitializeAsync().Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 비동기 초기화 수행
|
||||
/// </summary>
|
||||
private async UniTaskVoid InitializeAsync()
|
||||
{
|
||||
// Injector 인스턴스 생성
|
||||
Injector = new Injector();
|
||||
|
||||
// 서비스 등록
|
||||
// 동기 서비스 등록
|
||||
RegisterServices();
|
||||
|
||||
// 비동기 서비스 등록
|
||||
await RegisterServicesAsync();
|
||||
|
||||
// 씬 로드 이벤트 구독
|
||||
if (autoInjectOnSceneLoad)
|
||||
{
|
||||
@@ -175,11 +218,12 @@ namespace UVC.Core
|
||||
#region Service Registration
|
||||
|
||||
/// <summary>
|
||||
/// 서비스 등록을 수행합니다. 자식 클래스에서 오버라이드하여 추가 서비스를 등록하세요.
|
||||
/// 동기 서비스 등록을 수행합니다. 자식 클래스에서 오버라이드하여 추가 서비스를 등록하세요.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para><b>[ 호출 시점 ]</b></para>
|
||||
/// <para>Init() 메서드에서 Injector 인스턴스 생성 직후 호출됩니다.</para>
|
||||
/// <para>InitializeAsync()에서 Injector 인스턴스 생성 직후 호출됩니다.</para>
|
||||
/// <para>RegisterServicesAsync() 이전에 호출됩니다.</para>
|
||||
///
|
||||
/// <para><b>[ 오버라이드 시 주의사항 ]</b></para>
|
||||
/// <para>base.RegisterServices()를 먼저 호출하여 Inspector에서 할당한 Prefab들이 등록되도록 하세요.</para>
|
||||
@@ -190,13 +234,8 @@ namespace UVC.Core
|
||||
/// {
|
||||
/// base.RegisterServices(); // Inspector Prefab 등록
|
||||
///
|
||||
/// // Type A: 순수 C# 클래스
|
||||
/// // 동기 등록이 적합한 서비스들
|
||||
/// Injector.Register<ILogService, ConsoleLogger>(ServiceLifetime.App);
|
||||
///
|
||||
/// // Type B: MonoBehaviour 동적 생성
|
||||
/// Injector.Register<IAudioManager, AudioManager>(ServiceLifetime.App);
|
||||
///
|
||||
/// // Type D: Singleton 연동
|
||||
/// Injector.RegisterSingleton<SettingsManager>();
|
||||
/// }
|
||||
/// </code>
|
||||
@@ -218,6 +257,45 @@ namespace UVC.Core
|
||||
OnServicesRegistered?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 비동기 서비스 등록을 수행합니다. 자식 클래스에서 오버라이드하여 비동기 로드가 필요한 서비스를 등록하세요.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para><b>[ 호출 시점 ]</b></para>
|
||||
/// <para>RegisterServices() 완료 후 호출됩니다.</para>
|
||||
/// <para>이 메서드가 완료될 때까지 IsInitialized는 false입니다.</para>
|
||||
///
|
||||
/// <para><b>[ 사용 예시 ]</b></para>
|
||||
/// <code>
|
||||
/// protected override async UniTask RegisterServicesAsync()
|
||||
/// {
|
||||
/// // JSON 설정 파일 비동기 로드
|
||||
/// var setting = new Setting();
|
||||
/// var library = new Library();
|
||||
///
|
||||
/// // 병렬 로드로 성능 최적화
|
||||
/// await UniTask.WhenAll(
|
||||
/// setting.LoadAsync(),
|
||||
/// library.LoadAllParallelAsync()
|
||||
/// );
|
||||
///
|
||||
/// // 로드 완료 후 등록
|
||||
/// Injector.RegisterInstance<Setting>(setting);
|
||||
/// Injector.RegisterInstance<Library>(library);
|
||||
/// }
|
||||
/// </code>
|
||||
///
|
||||
/// <para><b>[ 주의사항 ]</b></para>
|
||||
/// <para>base.RegisterServicesAsync()를 호출할 필요는 없습니다 (기본 구현은 비어있음).</para>
|
||||
/// <para>이 메서드 완료 전까지 InjectorSceneContext는 대기합니다.</para>
|
||||
/// </remarks>
|
||||
/// <returns>비동기 작업</returns>
|
||||
protected virtual UniTask RegisterServicesAsync()
|
||||
{
|
||||
OnServicesRegisteredAsync?.Invoke();
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prefab을 해당 타입으로 등록합니다.
|
||||
/// </summary>
|
||||
@@ -318,6 +396,22 @@ namespace UVC.Core
|
||||
return Injector?.TryResolve<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 초기화가 완료될 때까지 대기합니다.
|
||||
/// </summary>
|
||||
/// <returns>초기화 완료 대기 태스크</returns>
|
||||
/// <remarks>
|
||||
/// <para>비동기 서비스 등록이 완료될 때까지 대기해야 할 때 사용합니다.</para>
|
||||
/// <code>
|
||||
/// await InjectorAppContext.Instance.WaitForInitializationAsync();
|
||||
/// var setting = InjectorAppContext.Instance.Get<Setting>();
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public async UniTask WaitForInitializationAsync()
|
||||
{
|
||||
await UniTask.WaitUntil(() => IsInitialized);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace UVC.Core
|
||||
{
|
||||
@@ -149,6 +150,15 @@ namespace UVC.Core
|
||||
/// </remarks>
|
||||
public event System.Action OnSceneInjectionCompleted;
|
||||
|
||||
/// <summary>
|
||||
/// Scene 서비스 비동기 등록 완료 시 발생
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>RegisterSceneServicesAsync() 메서드 완료 후 발생합니다.</para>
|
||||
/// <para>비동기로 로드가 필요한 Scene 서비스들의 등록이 완료된 상태를 나타냅니다.</para>
|
||||
/// </remarks>
|
||||
public event System.Action OnSceneServicesRegisteredAsync;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lifecycle
|
||||
@@ -157,44 +167,44 @@ namespace UVC.Core
|
||||
/// Unity Awake - InjectorAppContext 준비 확인 후 초기화
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
InitializeAsync().Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 비동기 초기화 수행 - AppContext 대기 후 서비스 등록 및 의존성 주입
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para><b>[ 실행 순서 ]</b></para>
|
||||
/// <list type="number">
|
||||
/// <item><description>InjectorAppContext 초기화 대기</description></item>
|
||||
/// <item><description>동기 서비스 등록 (RegisterSceneServices)</description></item>
|
||||
/// <item><description>비동기 서비스 등록 (RegisterSceneServicesAsync) - await</description></item>
|
||||
/// <item><description>자동 의존성 주입 (옵션)</description></item>
|
||||
/// <item><description>IsInitialized = true</description></item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
private async UniTaskVoid InitializeAsync()
|
||||
{
|
||||
// InjectorAppContext가 준비될 때까지 대기
|
||||
if (InjectorAppContext.Instance == null || !InjectorAppContext.Instance.IsInitialized)
|
||||
{
|
||||
Debug.LogWarning("[InjectorSceneContext] InjectorAppContext is not initialized. Waiting...");
|
||||
StartCoroutine(WaitForAppContext());
|
||||
return;
|
||||
await UniTask.WaitUntil(() => InjectorAppContext.Instance != null && InjectorAppContext.Instance.IsInitialized);
|
||||
}
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// InjectorAppContext가 준비될 때까지 대기하는 코루틴
|
||||
/// </summary>
|
||||
private System.Collections.IEnumerator WaitForAppContext()
|
||||
{
|
||||
while (InjectorAppContext.Instance == null || !InjectorAppContext.Instance.IsInitialized)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 실제 초기화 수행 - 서비스 등록 및 의존성 주입
|
||||
/// </summary>
|
||||
private void Initialize()
|
||||
{
|
||||
if (Injector == null)
|
||||
{
|
||||
Debug.LogError("[InjectorSceneContext] Injector is null. Make sure InjectorAppContext exists in the scene.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Scene 서비스 등록
|
||||
// Scene 서비스 등록 (동기)
|
||||
RegisterSceneServices();
|
||||
|
||||
// Scene 서비스 등록 (비동기) - 완료될 때까지 대기
|
||||
await RegisterSceneServicesAsync();
|
||||
|
||||
// 자동 의존성 주입
|
||||
if (autoInjectSceneObjects)
|
||||
{
|
||||
@@ -204,6 +214,32 @@ namespace UVC.Core
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 초기화가 완료될 때까지 대기합니다.
|
||||
/// </summary>
|
||||
/// <returns>초기화 완료 대기 UniTask</returns>
|
||||
/// <remarks>
|
||||
/// <para>다른 컴포넌트에서 SceneContext 초기화 완료를 기다릴 때 사용합니다.</para>
|
||||
/// <para><b>[ 사용 예시 ]</b></para>
|
||||
/// <code>
|
||||
/// public class MyComponent : MonoBehaviour
|
||||
/// {
|
||||
/// private async void Start()
|
||||
/// {
|
||||
/// var sceneContext = FindObjectOfType<InjectorSceneContext>();
|
||||
/// await sceneContext.WaitForInitializationAsync();
|
||||
///
|
||||
/// // 이제 모든 Scene 서비스가 준비됨
|
||||
/// var service = sceneContext.Injector.Resolve<IMyService>();
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public async UniTask WaitForInitializationAsync()
|
||||
{
|
||||
await UniTask.WaitUntil(() => IsInitialized);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unity OnDestroy - Scene 서비스 정리
|
||||
/// </summary>
|
||||
@@ -266,6 +302,48 @@ namespace UVC.Core
|
||||
OnSceneServicesRegistered?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scene 서비스 비동기 등록을 수행합니다. 자식 클래스에서 오버라이드하여 비동기 서비스를 등록하세요.
|
||||
/// </summary>
|
||||
/// <returns>비동기 등록 완료 UniTask</returns>
|
||||
/// <remarks>
|
||||
/// <para><b>[ 호출 시점 ]</b></para>
|
||||
/// <para>InitializeAsync()에서 RegisterSceneServices() 완료 후 호출됩니다.</para>
|
||||
/// <para>이 메서드는 await되므로 완료될 때까지 IsInitialized가 false로 유지됩니다.</para>
|
||||
///
|
||||
/// <para><b>[ 사용 시나리오 ]</b></para>
|
||||
/// <list type="bullet">
|
||||
/// <item><description>씬별 설정 파일 비동기 로드</description></item>
|
||||
/// <item><description>씬별 리소스 비동기 로드</description></item>
|
||||
/// <item><description>씬별 네트워크 초기화</description></item>
|
||||
/// </list>
|
||||
///
|
||||
/// <para><b>[ 사용 예시 ]</b></para>
|
||||
/// <code>
|
||||
/// public class BattleSceneContext : InjectorSceneContext
|
||||
/// {
|
||||
/// protected override async UniTask RegisterSceneServicesAsync()
|
||||
/// {
|
||||
/// await base.RegisterSceneServicesAsync();
|
||||
///
|
||||
/// // 씬별 설정 비동기 로드
|
||||
/// var battleConfig = new BattleConfig();
|
||||
/// await battleConfig.LoadAsync();
|
||||
/// Injector.RegisterInstance<BattleConfig>(battleConfig, ServiceLifetime.Scene);
|
||||
///
|
||||
/// // 씬별 리소스 비동기 로드
|
||||
/// var enemyData = await Resources.LoadAsync<EnemyDatabase>("EnemyData");
|
||||
/// Injector.RegisterInstance<EnemyDatabase>(enemyData as EnemyDatabase, ServiceLifetime.Scene);
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
protected virtual UniTask RegisterSceneServicesAsync()
|
||||
{
|
||||
OnSceneServicesRegisteredAsync?.Invoke();
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prefab을 해당 타입으로 등록합니다. (리플렉션 사용)
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user