diff --git a/Assets/_DDD/_Scripts/GameController/GameController.cs b/Assets/_DDD/_Scripts/GameController/GameController.cs index e55d54ab9..2b22a55cd 100644 --- a/Assets/_DDD/_Scripts/GameController/GameController.cs +++ b/Assets/_DDD/_Scripts/GameController/GameController.cs @@ -10,22 +10,22 @@ public class GameController : Singleton, IManager, IGameFlowHand { [SerializeField] private AssetReference _gameData; - public GameData GameData { get; private set; } - public GameState GameState { get; private set; } + public GameData GetGameData() => GameData.Instance; + public GameState GetGameState() => GameState.Instance; private List _gameFlowControllers = new(); private static readonly List GameFlowControllerTypes = new(); public void PreInit() { - LoadOrCreateRestaurantState(); + CreateGameState(); RegisterFlowHandler(); } public async Task Init() { await LoadData(); - await GameData.LoadData(); + await GetGameData().LoadData(); await InitializeAllFlowControllers(); } @@ -33,10 +33,9 @@ public void PostInit() { } - private void LoadOrCreateRestaurantState() + private void CreateGameState() { - // TODO : Load states from saved files. if none, create them. - GameState = ScriptableObject.CreateInstance(); + GameState.CreateScriptSingleton(); } private void RegisterFlowHandler() @@ -49,7 +48,7 @@ private async Task InitializeAllFlowControllers() // Create controllers and initialize them foreach (var gameFlowControllerType in GameFlowControllerTypes) { - // create new controllers from restaurantFlowControllerType + // create new controllers from gameFlowControllerType var newController = ScriptableObject.CreateInstance(gameFlowControllerType); var newFlowController = newController as FlowController; _gameFlowControllers.Add(newFlowController); @@ -64,14 +63,6 @@ private async Task InitializeAllFlowControllers() private async Task LoadData() { - var gameDataHandle = _gameData.LoadAssetAsync(); - - await gameDataHandle.Task; - - GameData = gameDataHandle.Result; - - Debug.Assert(GameData != null, "GameData is null"); - await Task.CompletedTask; } diff --git a/Assets/_DDD/_Scripts/GameData/GameData.cs b/Assets/_DDD/_Scripts/GameData/GameData.cs index f6bc5666c..e25d84940 100644 --- a/Assets/_DDD/_Scripts/GameData/GameData.cs +++ b/Assets/_DDD/_Scripts/GameData/GameData.cs @@ -5,7 +5,7 @@ namespace DDD { [CreateAssetMenu(fileName = "GameData", menuName = "GameData/GameData")] - public class GameData : ScriptableObject + public class GameData : ScriptSingleton { [SerializeField] private AssetReference _gameLocalizationData; diff --git a/Assets/_DDD/_Scripts/GameFramework/Localization/LocalizationManager.cs b/Assets/_DDD/_Scripts/GameFramework/Localization/LocalizationManager.cs index 5d04adfdd..e43ed2d8a 100644 --- a/Assets/_DDD/_Scripts/GameFramework/Localization/LocalizationManager.cs +++ b/Assets/_DDD/_Scripts/GameFramework/Localization/LocalizationManager.cs @@ -97,7 +97,7 @@ public string GetString(string key) var entryRef = key; var locale = LocalizationSettings.SelectedLocale; - VariablesGroupAsset variables = GameController.Instance.GameData.LocalizationData.SmartStringVariableGroup; + VariablesGroupAsset variables = GameData.Instance.LocalizationData.SmartStringVariableGroup; if (variables != null) { _singleArgBuffer.Clear(); diff --git a/Assets/_DDD/_Scripts/GameFramework/Localization/SmartStringVariables.cs b/Assets/_DDD/_Scripts/GameFramework/Localization/SmartStringVariables.cs index 8234cca30..2ee3199b6 100644 --- a/Assets/_DDD/_Scripts/GameFramework/Localization/SmartStringVariables.cs +++ b/Assets/_DDD/_Scripts/GameFramework/Localization/SmartStringVariables.cs @@ -50,8 +50,8 @@ public void PreInit() { } public async Task Init() { - var gameLevelStateSo = GameController.Instance.GameState.LevelState; - var restaurantStateSo = RestaurantController.Instance.RestaurantState.ManagementState; + var gameLevelStateSo = GameState.Instance.LevelState; + var restaurantStateSo = RestaurantState.Instance.ManagementState; // 예시: day 초기 세팅 (없으면 생성, 타입 다르면 교체) Set(_smartStringKeys[smartStringKey.Day], gameLevelStateSo.Level); @@ -71,7 +71,7 @@ public void PostInit() EventBus.Register(this); } - private RestaurantManagementState GetRestaurantState() => RestaurantController.Instance.RestaurantState.ManagementState; + private RestaurantManagementState GetRestaurantState() => RestaurantState.Instance.ManagementState; public void Invoke(SmartVariablesDirtyEvent evt) { @@ -113,7 +113,7 @@ public void RefreshChecklistTargets() public void RefreshDay() { - var gameLevelStateSo = GameController.Instance.GameState.LevelState; + var gameLevelStateSo = GameState.Instance.LevelState; Set(_smartStringKeys[smartStringKey.Day], gameLevelStateSo.Level); } @@ -179,7 +179,7 @@ public void SetEnum(string key, TEnum value) where TEnum : struct return null; } - var smartStringVariableGroup = GameController.Instance.GameData.LocalizationData.SmartStringVariableGroup; + var smartStringVariableGroup = GameData.Instance.LocalizationData.SmartStringVariableGroup; if (smartStringVariableGroup.TryGetValue(key, out var existing)) { diff --git a/Assets/_DDD/_Scripts/GameState/GameState.cs b/Assets/_DDD/_Scripts/GameState/GameState.cs index e87610fc5..70dfbc792 100644 --- a/Assets/_DDD/_Scripts/GameState/GameState.cs +++ b/Assets/_DDD/_Scripts/GameState/GameState.cs @@ -3,7 +3,7 @@ namespace DDD { - public class GameState : ScriptableObject + public class GameState : ScriptSingleton { [SerializeField] private AssetReference _gameLevelState; diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/ChecklistView.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/ChecklistView.cs index 5ebdb649c..5e079848f 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/ChecklistView.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/ChecklistView.cs @@ -29,7 +29,7 @@ public class ChecklistView : MonoBehaviour, IEventHandler, public void Initalize() { - restaurantManagementStateSo = RestaurantController.Instance.RestaurantState.ManagementState; + restaurantManagementStateSo = RestaurantState.Instance.ManagementState; _checklistDatas = new List(3); _checklistDatas = GetComponentsInChildren().ToList(); diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/InventoryUi/InventorySlotUiStrategy.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/InventoryUi/InventorySlotUiStrategy.cs index e179eb69a..03aa32396 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/InventoryUi/InventorySlotUiStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/InventoryUi/InventorySlotUiStrategy.cs @@ -40,7 +40,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model) public RuntimeAnimatorController GetAnimatorController() { - return RestaurantController.Instance.RestaurantData.ManagementData.InventorySlotUiAnimatorController; + return RestaurantData.Instance.ManagementData.InventorySlotUiAnimatorController; } public void OnInventoryChanged(ItemSlotUi ui) diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/InventoryUi/InventoryView.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/InventoryUi/InventoryView.cs index 13b7c0912..5217129a9 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/InventoryUi/InventoryView.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/InventoryUi/InventoryView.cs @@ -38,8 +38,8 @@ private void OnDisable() public void Initialize() { - restaurantManagementStateSo = RestaurantController.Instance.RestaurantState.ManagementState; - restaurantManagementDataSo = RestaurantController.Instance.RestaurantData.ManagementData; + restaurantManagementStateSo = RestaurantState.Instance.ManagementState; + restaurantManagementDataSo = RestaurantData.Instance.ManagementData; Debug.Assert(restaurantManagementDataSo != null, "_todayMenuDataSo != null"); Clear(); diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/ItemDetailView.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/ItemDetailView.cs index dcc9dfa26..5cd0a253a 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/ItemDetailView.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/ItemDetailView.cs @@ -49,7 +49,7 @@ private void OnDisable() public void Initialize() { - restaurantManagementDataSo = RestaurantController.Instance.RestaurantData.ManagementData; + restaurantManagementDataSo = RestaurantData.Instance.ManagementData; } public void Invoke(ItemSlotSelectedEvent evt) diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/RestaurantManagementUi.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/RestaurantManagementUi.cs index 28977f600..573a78fe6 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/RestaurantManagementUi.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/RestaurantManagementUi.cs @@ -60,7 +60,7 @@ private void UpdateHoldProgress() private void ProcessCompleteBatchAction() { - if (RestaurantController.Instance.RestaurantState.ManagementState.GetChecklistStates().Any(state => state == false)) + if (RestaurantState.Instance.ManagementState.GetChecklistStates().Any(state => state == false)) { ShowChecklistFailedPopup(); } diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuInteractorStrategy.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuInteractorStrategy.cs index 32ff38f3d..5a3987a33 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuInteractorStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuInteractorStrategy.cs @@ -10,7 +10,7 @@ public void OnAdded(ItemSlotUi itemSlotUi) if (inventorySlotUiStrategy.CanCrafting(itemSlotUi)) { - RestaurantController.Instance.RestaurantState.ManagementState.TryAddTodayMenu(itemSlotUi.Model); + RestaurantState.Instance.ManagementState.TryAddTodayMenu(itemSlotUi.Model); } else { @@ -25,7 +25,7 @@ public void OnRemoved(ItemSlotUi itemSlotUi) { if (itemSlotUi.Strategy is InventorySlotUiStrategy) return; - RestaurantController.Instance.RestaurantState.ManagementState.TryRemoveTodayMenu(itemSlotUi.Model); + RestaurantState.Instance.ManagementState.TryRemoveTodayMenu(itemSlotUi.Model); } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuSlotUiStrategy.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuSlotUiStrategy.cs index 47a9bf655..3403b5020 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuSlotUiStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuSlotUiStrategy.cs @@ -35,7 +35,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model) } string markSpriteKey = null; - if (RestaurantController.Instance.RestaurantState.ManagementState.IsCookwareMatched(ui.Model.Id)) + if (RestaurantState.Instance.ManagementState.IsCookwareMatched(ui.Model.Id)) { markSpriteKey = SpriteConstants.CheckYesSpriteKey; } @@ -51,7 +51,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model) public RuntimeAnimatorController GetAnimatorController() { - return RestaurantController.Instance.RestaurantData.ManagementData.TodayMenuSlotUiAnimatorController; + return RestaurantData.Instance.ManagementData.TodayMenuSlotUiAnimatorController; } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuView.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuView.cs index cb08f7142..977cf8ba2 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuView.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayMenuUi/TodayMenuView.cs @@ -23,8 +23,8 @@ private void OnDestroy() public void Initialize() { - restaurantManagementStateSo = RestaurantController.Instance.RestaurantState.ManagementState; - restaurantManagementDataSo = RestaurantController.Instance.RestaurantData.ManagementData; + restaurantManagementStateSo = RestaurantState.Instance.ManagementState; + restaurantManagementDataSo = RestaurantData.Instance.ManagementData; foreach (Transform child in _todayFoodContent) { diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareInteractorStrategy.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareInteractorStrategy.cs index 443aef47a..9d18d85b9 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareInteractorStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareInteractorStrategy.cs @@ -10,7 +10,7 @@ public void OnAdded(ItemSlotUi itemSlotUi) if (inventorySlotUiStrategy.CanCrafting(itemSlotUi)) { - RestaurantController.Instance.RestaurantState.ManagementState.TryAddTodayCookware(itemSlotUi.Model); + RestaurantState.Instance.ManagementState.TryAddTodayCookware(itemSlotUi.Model); } else { @@ -25,7 +25,7 @@ public void OnRemoved(ItemSlotUi itemSlotUi) { if (itemSlotUi.Strategy is InventorySlotUiStrategy) return; - RestaurantController.Instance.RestaurantState.ManagementState.TryRemoveTodayCookware(itemSlotUi.Model); + RestaurantState.Instance.ManagementState.TryRemoveTodayCookware(itemSlotUi.Model); } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareSlotUiStrategy.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareSlotUiStrategy.cs index 92830d63c..fff5e0830 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareSlotUiStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareSlotUiStrategy.cs @@ -18,7 +18,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model) } string markSpriteKey = null; - if (RestaurantController.Instance.RestaurantState.ManagementState.IsTodayMenuMatched(ui.Model.Id)) + if (RestaurantState.Instance.ManagementState.IsTodayMenuMatched(ui.Model.Id)) { markSpriteKey = SpriteConstants.CheckYesSpriteKey; } @@ -34,7 +34,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model) public RuntimeAnimatorController GetAnimatorController() { - return RestaurantController.Instance.RestaurantData.ManagementData.TodayMenuSlotUiAnimatorController; + return RestaurantData.Instance.ManagementData.TodayMenuSlotUiAnimatorController; } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs index c97db971e..55ec2df61 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs @@ -23,8 +23,8 @@ private void OnDestroy() public void Initialize() { - restaurantManagementStateSo = RestaurantController.Instance.RestaurantState.ManagementState; - restaurantManagementDataSo = RestaurantController.Instance.RestaurantData.ManagementData; + restaurantManagementStateSo = RestaurantState.Instance.ManagementState; + restaurantManagementDataSo = RestaurantData.Instance.ManagementData; foreach (Transform child in _todayWorkerContent) { diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayWorkerSlotUiStrategy.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayWorkerSlotUiStrategy.cs index 82a01cb85..f403f9aef 100644 --- a/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayWorkerSlotUiStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayWorkerSlotUiStrategy.cs @@ -26,7 +26,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model) public RuntimeAnimatorController GetAnimatorController() { - return RestaurantController.Instance.RestaurantData.ManagementData.TodayMenuSlotUiAnimatorController; + return RestaurantData.Instance.ManagementData.TodayMenuSlotUiAnimatorController; } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerInput.cs b/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerInput.cs index 4d5160068..dc22b7dcb 100644 --- a/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerInput.cs +++ b/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerInput.cs @@ -9,7 +9,7 @@ public class RestaurantPlayerInput : MonoBehaviour private void Start() { - _playerDataSo = RestaurantController.Instance.RestaurantData.PlayerData; + _playerDataSo = RestaurantData.Instance.PlayerData; _playerDataSo.OpenManagementUiAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.OpenManagementUi)); _playerDataSo.OpenManagementUiAction.performed += OnOpenManagementUi; diff --git a/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerInteraction.cs b/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerInteraction.cs index 7ea8e0740..8f648cef9 100644 --- a/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerInteraction.cs +++ b/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerInteraction.cs @@ -17,7 +17,7 @@ protected override void Start() private Task Initialize() { - _restaurantPlayerDataSo = RestaurantController.Instance.RestaurantData.PlayerData; + _restaurantPlayerDataSo = RestaurantData.Instance.PlayerData; Debug.Assert(_restaurantPlayerDataSo != null, "_restaurantPlayerDataSo is null"); _restaurantPlayerDataSo!.InteractAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Interact)); diff --git a/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerMovement.cs b/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerMovement.cs index 578d6779c..f564d2ae6 100644 --- a/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerMovement.cs +++ b/Assets/_DDD/_Scripts/RestaurantCharacter/Player/RestaurantPlayerMovement.cs @@ -81,7 +81,7 @@ private System.Threading.Tasks.Task InitializePlayerData() { try { - _playerDataSo = RestaurantController.Instance.RestaurantData.PlayerData; + _playerDataSo = RestaurantData.Instance.PlayerData; SubscribeToInputEvents(); _isInitialized = true; } diff --git a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantEnvironmentController.cs b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantEnvironmentController.cs index 609f59a57..b45a751c0 100644 --- a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantEnvironmentController.cs +++ b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantEnvironmentController.cs @@ -13,7 +13,7 @@ public override Task InitializeController() public override Task InitializeState() { - _environmentState = RestaurantController.Instance.RestaurantState.EnvironmentState; + _environmentState = RestaurantState.Instance.EnvironmentState; return Task.CompletedTask; } diff --git a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantManagementController.cs b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantManagementController.cs index e16b28c25..0237687fd 100644 --- a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantManagementController.cs +++ b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantManagementController.cs @@ -13,7 +13,7 @@ public override Task InitializeController() public override Task InitializeState() { // Load default asset - RestaurantController.Instance.RestaurantState.ManagementState.InitializeReadyForRestaurant(); + RestaurantState.Instance.ManagementState.InitializeReadyForRestaurant(); return Task.CompletedTask; } diff --git a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantRunController.cs b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantRunController.cs index ca7338ba9..5b48a8551 100644 --- a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantRunController.cs +++ b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/RestaurantRunController.cs @@ -8,14 +8,13 @@ public class RestaurantRunController : FlowController RestaurantCustomerState _restaurantCustomerStateSo; public override Task InitializeController() { - _restaurantCustomerStateSo = RestaurantController.Instance.RestaurantState.CustomerState; - return Task.CompletedTask; + _restaurantCustomerStateSo = RestaurantState.Instance.CustomerState; + return Task.CompletedTask; } public override Task InitializeState() { return Task.CompletedTask; - } public override async Task OnReadyNewFlow(GameFlowState newFlowState) diff --git a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/Tasks/CreateRestaurantEnvironment.cs b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/Tasks/CreateRestaurantEnvironment.cs index e61d338a5..e8372b8ad 100644 --- a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/Tasks/CreateRestaurantEnvironment.cs +++ b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/Tasks/CreateRestaurantEnvironment.cs @@ -15,7 +15,7 @@ public override Task RunFlowTask() { // TODO : Base prefab from EnvironmentDataSo - var props = RestaurantController.Instance.RestaurantState.EnvironmentState.Props; + var props = RestaurantState.Instance.EnvironmentState.Props; foreach (var prop in props) { // TODO : Instantiate and Initialize diff --git a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/Tasks/CreateRestaurantPlayer.cs b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/Tasks/CreateRestaurantPlayer.cs index fbee756b5..f5ac043ea 100644 --- a/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/Tasks/CreateRestaurantPlayer.cs +++ b/Assets/_DDD/_Scripts/RestaurantController/Conrtollers/Tasks/CreateRestaurantPlayer.cs @@ -20,7 +20,7 @@ public override Task RunFlowTask() return Task.CompletedTask; } - var playerPrefab = RestaurantController.Instance.RestaurantData.PlayerData.PlayerPrefab; + var playerPrefab = RestaurantData.Instance.PlayerData.PlayerPrefab; if (playerPrefab == null) { Debug.LogError("PlayerPrefab이 설정되지 않았습니다!"); diff --git a/Assets/_DDD/_Scripts/RestaurantController/RestaurantController.cs b/Assets/_DDD/_Scripts/RestaurantController/RestaurantController.cs index e3d82a1a2..0069fff33 100644 --- a/Assets/_DDD/_Scripts/RestaurantController/RestaurantController.cs +++ b/Assets/_DDD/_Scripts/RestaurantController/RestaurantController.cs @@ -10,8 +10,8 @@ public class RestaurantController : Singleton, IManager, I { [SerializeField] private AssetReference _restaurantData; - public RestaurantData RestaurantData { get; private set; } - public RestaurantState RestaurantState { get; private set; } + public RestaurantData GetRestaurantData() => RestaurantData.Instance; + public RestaurantState GetRestaurantState() => RestaurantState.Instance; private List _restaurantFlowControllers = new(); @@ -27,14 +27,14 @@ public class RestaurantController : Singleton, IManager, I public void PreInit() { - LoadOrCreateRestaurantState(); + CreateRestaurantState(); RegisterFlowHandler(); } public async Task Init() { await LoadData(); - await RestaurantData.LoadData(); + await GetRestaurantData().LoadData(); await InitializeAllFlowControllers(); } @@ -42,10 +42,9 @@ public void PostInit() { } - private void LoadOrCreateRestaurantState() + private void CreateRestaurantState() { - // TODO : Load states from saved files. if none, create them. - RestaurantState = ScriptableObject.CreateInstance(); + RestaurantState.CreateScriptSingleton(); } private void RegisterFlowHandler() @@ -73,13 +72,7 @@ private async Task InitializeAllFlowControllers() private async Task LoadData() { - var restaurantDataHandle = _restaurantData.LoadAssetAsync(); - - await restaurantDataHandle.Task; - - RestaurantData = restaurantDataHandle.Result; - - Debug.Assert(RestaurantData != null, "RestaurantData is null"); + await Task.CompletedTask; } public async Task OnReadyNewFlow(GameFlowState newFlowState) diff --git a/Assets/_DDD/_Scripts/RestaurantData/RestaurantData.cs b/Assets/_DDD/_Scripts/RestaurantData/RestaurantData.cs index c87be817e..3f8892c30 100644 --- a/Assets/_DDD/_Scripts/RestaurantData/RestaurantData.cs +++ b/Assets/_DDD/_Scripts/RestaurantData/RestaurantData.cs @@ -5,7 +5,7 @@ namespace DDD { [CreateAssetMenu(fileName = "RestaurantData", menuName = "RestaurantData/RestaurantData", order = 0)] - public class RestaurantData : ScriptableObject + public class RestaurantData : ScriptSingleton { [SerializeField] private AssetReference _restaurantPlayerData; [SerializeField] private AssetReference _restaurantManagementData; diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOpenEventSolver.cs b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOpenEventSolver.cs index ec7aaa66d..516d49444 100644 --- a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOpenEventSolver.cs +++ b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOpenEventSolver.cs @@ -15,7 +15,7 @@ public bool ExecuteInteraction(IInteractor interactor, IInteractable interactabl private RestaurantManagementState GetManagementState() { - return RestaurantController.Instance.RestaurantState.ManagementState; + return RestaurantState.Instance.ManagementState; } public bool CanExecuteInteraction(IInteractor interactor = null, IInteractable interactable = null, ScriptableObject payloadSo = null) diff --git a/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantCustomerState.cs b/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantCustomerState.cs index 9e9f1ca13..26daa3568 100644 --- a/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantCustomerState.cs +++ b/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantCustomerState.cs @@ -51,7 +51,7 @@ private async Task InitializeRunRestaurant() { _iCustomerFactory = new CustomerFactory(); - var currentGameLevel = GameController.Instance.GameState.LevelState.Level; + var currentGameLevel = GameState.Instance.LevelState.Level; if (_levelDataSo == null) { _levelDataSo = DataManager.Instance.GetDataSo(); diff --git a/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantManagementState.cs b/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantManagementState.cs index 7b375b979..1ad52ed1b 100644 --- a/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantManagementState.cs +++ b/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantManagementState.cs @@ -86,7 +86,7 @@ public bool IsOpenable() public RestaurantManagementData GetManagementData() { - return RestaurantController.Instance.RestaurantData.ManagementData; + return RestaurantData.Instance.ManagementData; } public bool TryAddTodayMenu(ItemViewModel model) diff --git a/Assets/_DDD/_Scripts/RestaurantState/RestaurantState.cs b/Assets/_DDD/_Scripts/RestaurantState/RestaurantState.cs index 1d3533637..9370ee616 100644 --- a/Assets/_DDD/_Scripts/RestaurantState/RestaurantState.cs +++ b/Assets/_DDD/_Scripts/RestaurantState/RestaurantState.cs @@ -2,7 +2,7 @@ namespace DDD { - public class RestaurantState : ScriptableObject + public class RestaurantState : ScriptSingleton { public RestaurantManagementState ManagementState { get; private set; } public RestaurantRunState RunState { get; private set; } diff --git a/Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs b/Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs new file mode 100644 index 000000000..9cffb682e --- /dev/null +++ b/Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs @@ -0,0 +1,128 @@ +using System; +using JetBrains.Annotations; +using UnityEngine; +using UnityEngine.AddressableAssets; +using UnityEngine.ResourceManagement.AsyncOperations; + +namespace DDD +{ + /// + /// Addressables를 통해 ScriptableObject 에셋을 로드하여 싱글톤으로 제공하는 베이스 클래스. + /// - 첫 접근 시 Addressables에서 타입명(네임스페이스 제외)을 키로 동기 로드합니다. + /// - 로드에 실패하면 예외를 발생합니다. (새로 생성하지 않습니다) + /// - 이미 로드된 경우 캐시된 인스턴스를 반환합니다. + /// + /// 구현 타입 + public abstract class ScriptSingleton : ScriptableObject where T : ScriptSingleton + { + #region Fields + [CanBeNull] + private static T _instance; + + [NotNull] + private static readonly object _lock = new(); + + private static bool _isQuitting; + #endregion + + #region Properties + [NotNull] + public static T Instance + { + get + { + if (_instance != null) + return _instance; + + if (_isQuitting) + throw new InvalidOperationException($"애플리케이션 종료 중에는 '{typeof(T).Name}' 인스턴스를 로드할 수 없습니다."); + + lock (_lock) + { + // 이중 체크 락킹 패턴 + if (_instance != null) + return _instance; + + try + { + var key = ResolveAddressKey(); + var handle = Addressables.LoadAssetAsync(key); + + // 동기 로드: 메인 스레드에서 호출할 것을 권장합니다. + var loaded = handle.WaitForCompletion(); + + if (handle.Status != AsyncOperationStatus.Succeeded || loaded == null) + { + throw new InvalidOperationException($"Addressables 로드 실패: 타입='{typeof(T).Name}', key='{key}'"); + } + + _instance = loaded; + _instance.hideFlags = HideFlags.DontUnloadUnusedAsset; + _instance.OnInstanceLoaded(); + + return _instance; + } + catch (Exception) + { + throw; + } + } + } + } + #endregion + + #region Methods + /// + /// 새로운 인스턴스를 생성하고 싱글톤으로 등록합니다. + /// Addressables에 등록되지 않은 경우 사용합니다. + /// + public static T CreateScriptSingleton() + { + if (_instance != null) + { + Debug.LogWarning($"[ScriptSingleton] {typeof(T).Name} 인스턴스가 이미 존재합니다. 기존 인스턴스를 반환합니다."); + return _instance; + } + + lock (_lock) + { + if (_instance != null) + return _instance; + + var newInstance = ScriptableObject.CreateInstance(); + _instance = newInstance; + _instance.hideFlags = HideFlags.DontUnloadUnusedAsset; + _instance.OnInstanceLoaded(); + + Debug.Log($"[ScriptSingleton] {typeof(T).Name} 인스턴스를 생성하고 싱글톤으로 등록했습니다."); + return _instance; + } + } + + /// + /// 사용자 정의 초기화 훅. 인스턴스가 로드된 뒤 1회 호출됩니다. + /// + protected virtual void OnInstanceLoaded() { } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + private static void RegisterQuitHandler() + { + Application.quitting -= OnApplicationQuitting; + Application.quitting += OnApplicationQuitting; + } + + private static void OnApplicationQuitting() + { + _isQuitting = true; + } + + /// + /// Address Key를 해석합니다. 요구사항에 따라 타입명(네임스페이스 제외) 그대로를 사용합니다. + /// + private static string ResolveAddressKey() + { + return typeof(T).Name; + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs.meta b/Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs.meta new file mode 100644 index 000000000..528f97b45 --- /dev/null +++ b/Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0544b64d4ef0a744dbd9ee6bcf4ecc00 \ No newline at end of file