so 싱글톤 추가
This commit is contained in:
parent
b8eec075ab
commit
9d57bcb040
@ -10,22 +10,22 @@ public class GameController : Singleton<GameController>, IManager, IGameFlowHand
|
|||||||
{
|
{
|
||||||
[SerializeField] private AssetReference _gameData;
|
[SerializeField] private AssetReference _gameData;
|
||||||
|
|
||||||
public GameData GameData { get; private set; }
|
public GameData GetGameData() => GameData.Instance;
|
||||||
public GameState GameState { get; private set; }
|
public GameState GetGameState() => GameState.Instance;
|
||||||
|
|
||||||
private List<FlowController> _gameFlowControllers = new();
|
private List<FlowController> _gameFlowControllers = new();
|
||||||
private static readonly List<Type> GameFlowControllerTypes = new();
|
private static readonly List<Type> GameFlowControllerTypes = new();
|
||||||
|
|
||||||
public void PreInit()
|
public void PreInit()
|
||||||
{
|
{
|
||||||
LoadOrCreateRestaurantState();
|
CreateGameState();
|
||||||
RegisterFlowHandler();
|
RegisterFlowHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Init()
|
public async Task Init()
|
||||||
{
|
{
|
||||||
await LoadData();
|
await LoadData();
|
||||||
await GameData.LoadData();
|
await GetGameData().LoadData();
|
||||||
await InitializeAllFlowControllers();
|
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.CreateScriptSingleton();
|
||||||
GameState = ScriptableObject.CreateInstance<GameState>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterFlowHandler()
|
private void RegisterFlowHandler()
|
||||||
@ -49,7 +48,7 @@ private async Task InitializeAllFlowControllers()
|
|||||||
// Create controllers and initialize them
|
// Create controllers and initialize them
|
||||||
foreach (var gameFlowControllerType in GameFlowControllerTypes)
|
foreach (var gameFlowControllerType in GameFlowControllerTypes)
|
||||||
{
|
{
|
||||||
// create new controllers from restaurantFlowControllerType
|
// create new controllers from gameFlowControllerType
|
||||||
var newController = ScriptableObject.CreateInstance(gameFlowControllerType);
|
var newController = ScriptableObject.CreateInstance(gameFlowControllerType);
|
||||||
var newFlowController = newController as FlowController;
|
var newFlowController = newController as FlowController;
|
||||||
_gameFlowControllers.Add(newFlowController);
|
_gameFlowControllers.Add(newFlowController);
|
||||||
@ -64,14 +63,6 @@ private async Task InitializeAllFlowControllers()
|
|||||||
|
|
||||||
private async Task LoadData()
|
private async Task LoadData()
|
||||||
{
|
{
|
||||||
var gameDataHandle = _gameData.LoadAssetAsync<GameData>();
|
|
||||||
|
|
||||||
await gameDataHandle.Task;
|
|
||||||
|
|
||||||
GameData = gameDataHandle.Result;
|
|
||||||
|
|
||||||
Debug.Assert(GameData != null, "GameData is null");
|
|
||||||
|
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
[CreateAssetMenu(fileName = "GameData", menuName = "GameData/GameData")]
|
[CreateAssetMenu(fileName = "GameData", menuName = "GameData/GameData")]
|
||||||
public class GameData : ScriptableObject
|
public class GameData : ScriptSingleton<GameData>
|
||||||
{
|
{
|
||||||
[SerializeField] private AssetReference _gameLocalizationData;
|
[SerializeField] private AssetReference _gameLocalizationData;
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ public string GetString(string key)
|
|||||||
var entryRef = key;
|
var entryRef = key;
|
||||||
var locale = LocalizationSettings.SelectedLocale;
|
var locale = LocalizationSettings.SelectedLocale;
|
||||||
|
|
||||||
VariablesGroupAsset variables = GameController.Instance.GameData.LocalizationData.SmartStringVariableGroup;
|
VariablesGroupAsset variables = GameData.Instance.LocalizationData.SmartStringVariableGroup;
|
||||||
if (variables != null)
|
if (variables != null)
|
||||||
{
|
{
|
||||||
_singleArgBuffer.Clear();
|
_singleArgBuffer.Clear();
|
||||||
|
@ -50,8 +50,8 @@ public void PreInit() { }
|
|||||||
|
|
||||||
public async Task Init()
|
public async Task Init()
|
||||||
{
|
{
|
||||||
var gameLevelStateSo = GameController.Instance.GameState.LevelState;
|
var gameLevelStateSo = GameState.Instance.LevelState;
|
||||||
var restaurantStateSo = RestaurantController.Instance.RestaurantState.ManagementState;
|
var restaurantStateSo = RestaurantState.Instance.ManagementState;
|
||||||
|
|
||||||
// 예시: day 초기 세팅 (없으면 생성, 타입 다르면 교체)
|
// 예시: day 초기 세팅 (없으면 생성, 타입 다르면 교체)
|
||||||
Set(_smartStringKeys[smartStringKey.Day], gameLevelStateSo.Level);
|
Set(_smartStringKeys[smartStringKey.Day], gameLevelStateSo.Level);
|
||||||
@ -71,7 +71,7 @@ public void PostInit()
|
|||||||
EventBus.Register<SmartVariablesDirtyEvent>(this);
|
EventBus.Register<SmartVariablesDirtyEvent>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RestaurantManagementState GetRestaurantState() => RestaurantController.Instance.RestaurantState.ManagementState;
|
private RestaurantManagementState GetRestaurantState() => RestaurantState.Instance.ManagementState;
|
||||||
|
|
||||||
public void Invoke(SmartVariablesDirtyEvent evt)
|
public void Invoke(SmartVariablesDirtyEvent evt)
|
||||||
{
|
{
|
||||||
@ -113,7 +113,7 @@ public void RefreshChecklistTargets()
|
|||||||
|
|
||||||
public void RefreshDay()
|
public void RefreshDay()
|
||||||
{
|
{
|
||||||
var gameLevelStateSo = GameController.Instance.GameState.LevelState;
|
var gameLevelStateSo = GameState.Instance.LevelState;
|
||||||
Set(_smartStringKeys[smartStringKey.Day], gameLevelStateSo.Level);
|
Set(_smartStringKeys[smartStringKey.Day], gameLevelStateSo.Level);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ public void SetEnum<TEnum>(string key, TEnum value) where TEnum : struct
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var smartStringVariableGroup = GameController.Instance.GameData.LocalizationData.SmartStringVariableGroup;
|
var smartStringVariableGroup = GameData.Instance.LocalizationData.SmartStringVariableGroup;
|
||||||
|
|
||||||
if (smartStringVariableGroup.TryGetValue(key, out var existing))
|
if (smartStringVariableGroup.TryGetValue(key, out var existing))
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public class GameState : ScriptableObject
|
public class GameState : ScriptSingleton<GameState>
|
||||||
{
|
{
|
||||||
[SerializeField] private AssetReference _gameLevelState;
|
[SerializeField] private AssetReference _gameLevelState;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ public class ChecklistView : MonoBehaviour, IEventHandler<TodayMenuAddedEvent>,
|
|||||||
|
|
||||||
public void Initalize()
|
public void Initalize()
|
||||||
{
|
{
|
||||||
restaurantManagementStateSo = RestaurantController.Instance.RestaurantState.ManagementState;
|
restaurantManagementStateSo = RestaurantState.Instance.ManagementState;
|
||||||
|
|
||||||
_checklistDatas = new List<ChecklistData>(3);
|
_checklistDatas = new List<ChecklistData>(3);
|
||||||
_checklistDatas = GetComponentsInChildren<ChecklistData>().ToList();
|
_checklistDatas = GetComponentsInChildren<ChecklistData>().ToList();
|
||||||
|
@ -40,7 +40,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
|
|||||||
|
|
||||||
public RuntimeAnimatorController GetAnimatorController()
|
public RuntimeAnimatorController GetAnimatorController()
|
||||||
{
|
{
|
||||||
return RestaurantController.Instance.RestaurantData.ManagementData.InventorySlotUiAnimatorController;
|
return RestaurantData.Instance.ManagementData.InventorySlotUiAnimatorController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnInventoryChanged(ItemSlotUi ui)
|
public void OnInventoryChanged(ItemSlotUi ui)
|
||||||
|
@ -38,8 +38,8 @@ private void OnDisable()
|
|||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
restaurantManagementStateSo = RestaurantController.Instance.RestaurantState.ManagementState;
|
restaurantManagementStateSo = RestaurantState.Instance.ManagementState;
|
||||||
restaurantManagementDataSo = RestaurantController.Instance.RestaurantData.ManagementData;
|
restaurantManagementDataSo = RestaurantData.Instance.ManagementData;
|
||||||
Debug.Assert(restaurantManagementDataSo != null, "_todayMenuDataSo != null");
|
Debug.Assert(restaurantManagementDataSo != null, "_todayMenuDataSo != null");
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
@ -49,7 +49,7 @@ private void OnDisable()
|
|||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
restaurantManagementDataSo = RestaurantController.Instance.RestaurantData.ManagementData;
|
restaurantManagementDataSo = RestaurantData.Instance.ManagementData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Invoke(ItemSlotSelectedEvent evt)
|
public void Invoke(ItemSlotSelectedEvent evt)
|
||||||
|
@ -60,7 +60,7 @@ private void UpdateHoldProgress()
|
|||||||
|
|
||||||
private void ProcessCompleteBatchAction()
|
private void ProcessCompleteBatchAction()
|
||||||
{
|
{
|
||||||
if (RestaurantController.Instance.RestaurantState.ManagementState.GetChecklistStates().Any(state => state == false))
|
if (RestaurantState.Instance.ManagementState.GetChecklistStates().Any(state => state == false))
|
||||||
{
|
{
|
||||||
ShowChecklistFailedPopup();
|
ShowChecklistFailedPopup();
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ public void OnAdded(ItemSlotUi itemSlotUi)
|
|||||||
|
|
||||||
if (inventorySlotUiStrategy.CanCrafting(itemSlotUi))
|
if (inventorySlotUiStrategy.CanCrafting(itemSlotUi))
|
||||||
{
|
{
|
||||||
RestaurantController.Instance.RestaurantState.ManagementState.TryAddTodayMenu(itemSlotUi.Model);
|
RestaurantState.Instance.ManagementState.TryAddTodayMenu(itemSlotUi.Model);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -25,7 +25,7 @@ public void OnRemoved(ItemSlotUi itemSlotUi)
|
|||||||
{
|
{
|
||||||
if (itemSlotUi.Strategy is InventorySlotUiStrategy) return;
|
if (itemSlotUi.Strategy is InventorySlotUiStrategy) return;
|
||||||
|
|
||||||
RestaurantController.Instance.RestaurantState.ManagementState.TryRemoveTodayMenu(itemSlotUi.Model);
|
RestaurantState.Instance.ManagementState.TryRemoveTodayMenu(itemSlotUi.Model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -35,7 +35,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
|
|||||||
}
|
}
|
||||||
|
|
||||||
string markSpriteKey = null;
|
string markSpriteKey = null;
|
||||||
if (RestaurantController.Instance.RestaurantState.ManagementState.IsCookwareMatched(ui.Model.Id))
|
if (RestaurantState.Instance.ManagementState.IsCookwareMatched(ui.Model.Id))
|
||||||
{
|
{
|
||||||
markSpriteKey = SpriteConstants.CheckYesSpriteKey;
|
markSpriteKey = SpriteConstants.CheckYesSpriteKey;
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
|
|||||||
|
|
||||||
public RuntimeAnimatorController GetAnimatorController()
|
public RuntimeAnimatorController GetAnimatorController()
|
||||||
{
|
{
|
||||||
return RestaurantController.Instance.RestaurantData.ManagementData.TodayMenuSlotUiAnimatorController;
|
return RestaurantData.Instance.ManagementData.TodayMenuSlotUiAnimatorController;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,8 +23,8 @@ private void OnDestroy()
|
|||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
restaurantManagementStateSo = RestaurantController.Instance.RestaurantState.ManagementState;
|
restaurantManagementStateSo = RestaurantState.Instance.ManagementState;
|
||||||
restaurantManagementDataSo = RestaurantController.Instance.RestaurantData.ManagementData;
|
restaurantManagementDataSo = RestaurantData.Instance.ManagementData;
|
||||||
|
|
||||||
foreach (Transform child in _todayFoodContent)
|
foreach (Transform child in _todayFoodContent)
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,7 @@ public void OnAdded(ItemSlotUi itemSlotUi)
|
|||||||
|
|
||||||
if (inventorySlotUiStrategy.CanCrafting(itemSlotUi))
|
if (inventorySlotUiStrategy.CanCrafting(itemSlotUi))
|
||||||
{
|
{
|
||||||
RestaurantController.Instance.RestaurantState.ManagementState.TryAddTodayCookware(itemSlotUi.Model);
|
RestaurantState.Instance.ManagementState.TryAddTodayCookware(itemSlotUi.Model);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -25,7 +25,7 @@ public void OnRemoved(ItemSlotUi itemSlotUi)
|
|||||||
{
|
{
|
||||||
if (itemSlotUi.Strategy is InventorySlotUiStrategy) return;
|
if (itemSlotUi.Strategy is InventorySlotUiStrategy) return;
|
||||||
|
|
||||||
RestaurantController.Instance.RestaurantState.ManagementState.TryRemoveTodayCookware(itemSlotUi.Model);
|
RestaurantState.Instance.ManagementState.TryRemoveTodayCookware(itemSlotUi.Model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
|
|||||||
}
|
}
|
||||||
|
|
||||||
string markSpriteKey = null;
|
string markSpriteKey = null;
|
||||||
if (RestaurantController.Instance.RestaurantState.ManagementState.IsTodayMenuMatched(ui.Model.Id))
|
if (RestaurantState.Instance.ManagementState.IsTodayMenuMatched(ui.Model.Id))
|
||||||
{
|
{
|
||||||
markSpriteKey = SpriteConstants.CheckYesSpriteKey;
|
markSpriteKey = SpriteConstants.CheckYesSpriteKey;
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
|
|||||||
|
|
||||||
public RuntimeAnimatorController GetAnimatorController()
|
public RuntimeAnimatorController GetAnimatorController()
|
||||||
{
|
{
|
||||||
return RestaurantController.Instance.RestaurantData.ManagementData.TodayMenuSlotUiAnimatorController;
|
return RestaurantData.Instance.ManagementData.TodayMenuSlotUiAnimatorController;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,8 +23,8 @@ private void OnDestroy()
|
|||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
restaurantManagementStateSo = RestaurantController.Instance.RestaurantState.ManagementState;
|
restaurantManagementStateSo = RestaurantState.Instance.ManagementState;
|
||||||
restaurantManagementDataSo = RestaurantController.Instance.RestaurantData.ManagementData;
|
restaurantManagementDataSo = RestaurantData.Instance.ManagementData;
|
||||||
|
|
||||||
foreach (Transform child in _todayWorkerContent)
|
foreach (Transform child in _todayWorkerContent)
|
||||||
{
|
{
|
||||||
|
@ -26,7 +26,7 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
|
|||||||
|
|
||||||
public RuntimeAnimatorController GetAnimatorController()
|
public RuntimeAnimatorController GetAnimatorController()
|
||||||
{
|
{
|
||||||
return RestaurantController.Instance.RestaurantData.ManagementData.TodayMenuSlotUiAnimatorController;
|
return RestaurantData.Instance.ManagementData.TodayMenuSlotUiAnimatorController;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ public class RestaurantPlayerInput : MonoBehaviour
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
_playerDataSo = RestaurantController.Instance.RestaurantData.PlayerData;
|
_playerDataSo = RestaurantData.Instance.PlayerData;
|
||||||
_playerDataSo.OpenManagementUiAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.OpenManagementUi));
|
_playerDataSo.OpenManagementUiAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.OpenManagementUi));
|
||||||
|
|
||||||
_playerDataSo.OpenManagementUiAction.performed += OnOpenManagementUi;
|
_playerDataSo.OpenManagementUiAction.performed += OnOpenManagementUi;
|
||||||
|
@ -17,7 +17,7 @@ protected override void Start()
|
|||||||
|
|
||||||
private Task Initialize()
|
private Task Initialize()
|
||||||
{
|
{
|
||||||
_restaurantPlayerDataSo = RestaurantController.Instance.RestaurantData.PlayerData;
|
_restaurantPlayerDataSo = RestaurantData.Instance.PlayerData;
|
||||||
Debug.Assert(_restaurantPlayerDataSo != null, "_restaurantPlayerDataSo is null");
|
Debug.Assert(_restaurantPlayerDataSo != null, "_restaurantPlayerDataSo is null");
|
||||||
|
|
||||||
_restaurantPlayerDataSo!.InteractAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Interact));
|
_restaurantPlayerDataSo!.InteractAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Interact));
|
||||||
|
@ -81,7 +81,7 @@ private System.Threading.Tasks.Task InitializePlayerData()
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_playerDataSo = RestaurantController.Instance.RestaurantData.PlayerData;
|
_playerDataSo = RestaurantData.Instance.PlayerData;
|
||||||
SubscribeToInputEvents();
|
SubscribeToInputEvents();
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ public override Task InitializeController()
|
|||||||
|
|
||||||
public override Task InitializeState()
|
public override Task InitializeState()
|
||||||
{
|
{
|
||||||
_environmentState = RestaurantController.Instance.RestaurantState.EnvironmentState;
|
_environmentState = RestaurantState.Instance.EnvironmentState;
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ public override Task InitializeController()
|
|||||||
public override Task InitializeState()
|
public override Task InitializeState()
|
||||||
{
|
{
|
||||||
// Load default asset
|
// Load default asset
|
||||||
RestaurantController.Instance.RestaurantState.ManagementState.InitializeReadyForRestaurant();
|
RestaurantState.Instance.ManagementState.InitializeReadyForRestaurant();
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,13 @@ public class RestaurantRunController : FlowController
|
|||||||
RestaurantCustomerState _restaurantCustomerStateSo;
|
RestaurantCustomerState _restaurantCustomerStateSo;
|
||||||
public override Task InitializeController()
|
public override Task InitializeController()
|
||||||
{
|
{
|
||||||
_restaurantCustomerStateSo = RestaurantController.Instance.RestaurantState.CustomerState;
|
_restaurantCustomerStateSo = RestaurantState.Instance.CustomerState;
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task InitializeState()
|
public override Task InitializeState()
|
||||||
{
|
{
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task OnReadyNewFlow(GameFlowState newFlowState)
|
public override async Task OnReadyNewFlow(GameFlowState newFlowState)
|
||||||
|
@ -15,7 +15,7 @@ public override Task RunFlowTask()
|
|||||||
{
|
{
|
||||||
// TODO : Base prefab from EnvironmentDataSo
|
// TODO : Base prefab from EnvironmentDataSo
|
||||||
|
|
||||||
var props = RestaurantController.Instance.RestaurantState.EnvironmentState.Props;
|
var props = RestaurantState.Instance.EnvironmentState.Props;
|
||||||
foreach (var prop in props)
|
foreach (var prop in props)
|
||||||
{
|
{
|
||||||
// TODO : Instantiate and Initialize
|
// TODO : Instantiate and Initialize
|
||||||
|
@ -20,7 +20,7 @@ public override Task RunFlowTask()
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
var playerPrefab = RestaurantController.Instance.RestaurantData.PlayerData.PlayerPrefab;
|
var playerPrefab = RestaurantData.Instance.PlayerData.PlayerPrefab;
|
||||||
if (playerPrefab == null)
|
if (playerPrefab == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("PlayerPrefab이 설정되지 않았습니다!");
|
Debug.LogError("PlayerPrefab이 설정되지 않았습니다!");
|
||||||
|
@ -10,8 +10,8 @@ public class RestaurantController : Singleton<RestaurantController>, IManager, I
|
|||||||
{
|
{
|
||||||
[SerializeField] private AssetReference _restaurantData;
|
[SerializeField] private AssetReference _restaurantData;
|
||||||
|
|
||||||
public RestaurantData RestaurantData { get; private set; }
|
public RestaurantData GetRestaurantData() => RestaurantData.Instance;
|
||||||
public RestaurantState RestaurantState { get; private set; }
|
public RestaurantState GetRestaurantState() => RestaurantState.Instance;
|
||||||
|
|
||||||
private List<FlowController> _restaurantFlowControllers = new();
|
private List<FlowController> _restaurantFlowControllers = new();
|
||||||
|
|
||||||
@ -27,14 +27,14 @@ public class RestaurantController : Singleton<RestaurantController>, IManager, I
|
|||||||
|
|
||||||
public void PreInit()
|
public void PreInit()
|
||||||
{
|
{
|
||||||
LoadOrCreateRestaurantState();
|
CreateRestaurantState();
|
||||||
RegisterFlowHandler();
|
RegisterFlowHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Init()
|
public async Task Init()
|
||||||
{
|
{
|
||||||
await LoadData();
|
await LoadData();
|
||||||
await RestaurantData.LoadData();
|
await GetRestaurantData().LoadData();
|
||||||
await InitializeAllFlowControllers();
|
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.CreateScriptSingleton();
|
||||||
RestaurantState = ScriptableObject.CreateInstance<RestaurantState>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterFlowHandler()
|
private void RegisterFlowHandler()
|
||||||
@ -73,13 +72,7 @@ private async Task InitializeAllFlowControllers()
|
|||||||
|
|
||||||
private async Task LoadData()
|
private async Task LoadData()
|
||||||
{
|
{
|
||||||
var restaurantDataHandle = _restaurantData.LoadAssetAsync<RestaurantData>();
|
await Task.CompletedTask;
|
||||||
|
|
||||||
await restaurantDataHandle.Task;
|
|
||||||
|
|
||||||
RestaurantData = restaurantDataHandle.Result;
|
|
||||||
|
|
||||||
Debug.Assert(RestaurantData != null, "RestaurantData is null");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OnReadyNewFlow(GameFlowState newFlowState)
|
public async Task OnReadyNewFlow(GameFlowState newFlowState)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
[CreateAssetMenu(fileName = "RestaurantData", menuName = "RestaurantData/RestaurantData", order = 0)]
|
[CreateAssetMenu(fileName = "RestaurantData", menuName = "RestaurantData/RestaurantData", order = 0)]
|
||||||
public class RestaurantData : ScriptableObject
|
public class RestaurantData : ScriptSingleton<RestaurantData>
|
||||||
{
|
{
|
||||||
[SerializeField] private AssetReference _restaurantPlayerData;
|
[SerializeField] private AssetReference _restaurantPlayerData;
|
||||||
[SerializeField] private AssetReference _restaurantManagementData;
|
[SerializeField] private AssetReference _restaurantManagementData;
|
||||||
|
@ -15,7 +15,7 @@ public bool ExecuteInteraction(IInteractor interactor, IInteractable interactabl
|
|||||||
|
|
||||||
private RestaurantManagementState GetManagementState()
|
private RestaurantManagementState GetManagementState()
|
||||||
{
|
{
|
||||||
return RestaurantController.Instance.RestaurantState.ManagementState;
|
return RestaurantState.Instance.ManagementState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanExecuteInteraction(IInteractor interactor = null, IInteractable interactable = null, ScriptableObject payloadSo = null)
|
public bool CanExecuteInteraction(IInteractor interactor = null, IInteractable interactable = null, ScriptableObject payloadSo = null)
|
||||||
|
@ -51,7 +51,7 @@ private async Task InitializeRunRestaurant()
|
|||||||
{
|
{
|
||||||
_iCustomerFactory = new CustomerFactory();
|
_iCustomerFactory = new CustomerFactory();
|
||||||
|
|
||||||
var currentGameLevel = GameController.Instance.GameState.LevelState.Level;
|
var currentGameLevel = GameState.Instance.LevelState.Level;
|
||||||
if (_levelDataSo == null)
|
if (_levelDataSo == null)
|
||||||
{
|
{
|
||||||
_levelDataSo = DataManager.Instance.GetDataSo<LevelDataSo>();
|
_levelDataSo = DataManager.Instance.GetDataSo<LevelDataSo>();
|
||||||
|
@ -86,7 +86,7 @@ public bool IsOpenable()
|
|||||||
|
|
||||||
public RestaurantManagementData GetManagementData()
|
public RestaurantManagementData GetManagementData()
|
||||||
{
|
{
|
||||||
return RestaurantController.Instance.RestaurantData.ManagementData;
|
return RestaurantData.Instance.ManagementData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryAddTodayMenu(ItemViewModel model)
|
public bool TryAddTodayMenu(ItemViewModel model)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public class RestaurantState : ScriptableObject
|
public class RestaurantState : ScriptSingleton<RestaurantState>
|
||||||
{
|
{
|
||||||
public RestaurantManagementState ManagementState { get; private set; }
|
public RestaurantManagementState ManagementState { get; private set; }
|
||||||
public RestaurantRunState RunState { get; private set; }
|
public RestaurantRunState RunState { get; private set; }
|
||||||
|
128
Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs
Normal file
128
Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||||
|
|
||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Addressables를 통해 ScriptableObject 에셋을 로드하여 싱글톤으로 제공하는 베이스 클래스.
|
||||||
|
/// - 첫 접근 시 Addressables에서 타입명(네임스페이스 제외)을 키로 동기 로드합니다.
|
||||||
|
/// - 로드에 실패하면 예외를 발생합니다. (새로 생성하지 않습니다)
|
||||||
|
/// - 이미 로드된 경우 캐시된 인스턴스를 반환합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">구현 타입</typeparam>
|
||||||
|
public abstract class ScriptSingleton<T> : ScriptableObject where T : ScriptSingleton<T>
|
||||||
|
{
|
||||||
|
#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<T>(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
|
||||||
|
/// <summary>
|
||||||
|
/// 새로운 인스턴스를 생성하고 싱글톤으로 등록합니다.
|
||||||
|
/// Addressables에 등록되지 않은 경우 사용합니다.
|
||||||
|
/// </summary>
|
||||||
|
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<T>();
|
||||||
|
_instance = newInstance;
|
||||||
|
_instance.hideFlags = HideFlags.DontUnloadUnusedAsset;
|
||||||
|
_instance.OnInstanceLoaded();
|
||||||
|
|
||||||
|
Debug.Log($"[ScriptSingleton] {typeof(T).Name} 인스턴스를 생성하고 싱글톤으로 등록했습니다.");
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 사용자 정의 초기화 훅. 인스턴스가 로드된 뒤 1회 호출됩니다.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnInstanceLoaded() { }
|
||||||
|
|
||||||
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
|
||||||
|
private static void RegisterQuitHandler()
|
||||||
|
{
|
||||||
|
Application.quitting -= OnApplicationQuitting;
|
||||||
|
Application.quitting += OnApplicationQuitting;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnApplicationQuitting()
|
||||||
|
{
|
||||||
|
_isQuitting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Address Key를 해석합니다. 요구사항에 따라 타입명(네임스페이스 제외) 그대로를 사용합니다.
|
||||||
|
/// </summary>
|
||||||
|
private static string ResolveAddressKey()
|
||||||
|
{
|
||||||
|
return typeof(T).Name;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
2
Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs.meta
Normal file
2
Assets/_DDD/_Scripts/Utilities/ScriptSingleton.cs.meta
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0544b64d4ef0a744dbd9ee6bcf4ecc00
|
Loading…
Reference in New Issue
Block a user