From 5b0e6fd786f7799f004ce8c15741d6868bba7457 Mon Sep 17 00:00:00 2001 From: NTG Date: Thu, 21 Aug 2025 18:15:51 +0900 Subject: [PATCH] =?UTF-8?q?TodayMenuView=20viewModel=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Prefabs/Uis/GameUi/PopupUis/CookUi.prefab | 40 ++- .../RestaurantManagementData.asset | 4 +- .../CookUi_UiActionsInputBinding.asset | 3 + .../CookUi_UiActionsInputBinding.asset.meta | 8 + .../Localization/SmartStringVariables.cs | 58 ++-- .../GameUi/BaseUi/PopupUis/BasePopupUi.cs | 2 +- .../GameUi/BaseUi/PopupUis/CookUi.meta | 8 + .../GameUi/BaseUi/PopupUis/CookUi/CookUi.cs | 13 + .../BaseUi/PopupUis/CookUi/CookUi.cs.meta | 2 + .../BaseUi/PopupUis/CookUi/CookViewModel.cs | 9 + .../PopupUis/CookUi/CookViewModel.cs.meta | 2 + .../GameUi/BaseUi/PopupUis/PopupUi.cs | 26 +- .../RestaurantManagementUi/ItemDetailView.cs | 2 +- .../RestaurantManagementUi.cs | 2 +- .../RestaurantManagementViewModel.cs | 252 ++++++++++-------- .../TodayMenuUi/TodayMenuView.cs | 99 ++----- .../TodayRestaurantStateView.cs | 7 +- .../InputSystem/BaseUiActionsInputBinding.cs | 1 + .../RestaurantActionsInputBinding.cs | 8 +- .../RestaurantUiActionsInputBinding.cs | 8 +- .../DataObjects/RestaurantManagementData.cs | 16 +- .../FlowStates/RestaurantManagementState.cs | 30 +-- 22 files changed, 332 insertions(+), 268 deletions(-) create mode 100644 Assets/_DDD/_Addressables/So/UiActionInputBinding/CookUi_UiActionsInputBinding.asset create mode 100644 Assets/_DDD/_Addressables/So/UiActionInputBinding/CookUi_UiActionsInputBinding.asset.meta create mode 100644 Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi.meta create mode 100644 Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookUi.cs create mode 100644 Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookUi.cs.meta create mode 100644 Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookViewModel.cs create mode 100644 Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookViewModel.cs.meta diff --git a/Assets/_DDD/_Addressables/Prefabs/Uis/GameUi/PopupUis/CookUi.prefab b/Assets/_DDD/_Addressables/Prefabs/Uis/GameUi/PopupUis/CookUi.prefab index fc1f008e9..9c485db06 100644 --- a/Assets/_DDD/_Addressables/Prefabs/Uis/GameUi/PopupUis/CookUi.prefab +++ b/Assets/_DDD/_Addressables/Prefabs/Uis/GameUi/PopupUis/CookUi.prefab @@ -173,10 +173,48 @@ PrefabInstance: - targetCorrespondingSourceObject: {fileID: 8967231042952671610, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3} insertIndex: -1 addedObject: {fileID: 5701939276505918991} - m_AddedComponents: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 6952779389930089995, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3} + insertIndex: -1 + addedObject: {fileID: 3558726899806659957} + - targetCorrespondingSourceObject: {fileID: 6952779389930089995, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3} + insertIndex: -1 + addedObject: {fileID: 7215137460101227451} m_SourcePrefab: {fileID: 100100000, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3} --- !u!224 &7368736952364656095 stripped RectTransform: m_CorrespondingSourceObject: {fileID: 8967231042952671610, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3} m_PrefabInstance: {fileID: 1887292089917625509} m_PrefabAsset: {fileID: 0} +--- !u!1 &8812486931779779246 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 6952779389930089995, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3} + m_PrefabInstance: {fileID: 1887292089917625509} + m_PrefabAsset: {fileID: 0} +--- !u!114 &3558726899806659957 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8812486931779779246} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7856cd3c67598cf41a31efc38bb512d9, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &7215137460101227451 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8812486931779779246} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fa01b8c8ff13d3241b943d0f12d3b767, type: 3} + m_Name: + m_EditorClassIdentifier: + k__BackingField: 3 + _enableBlockImage: 0 + _uiActionsInputBinding: {fileID: 11400000, guid: 8dd5523e04e1abd4caff017469c49c58, type: 2} diff --git a/Assets/_DDD/_Addressables/So/RestaurantData/RestaurantManagementData.asset b/Assets/_DDD/_Addressables/So/RestaurantData/RestaurantManagementData.asset index e3b105226..5a47d8b0f 100644 --- a/Assets/_DDD/_Addressables/So/RestaurantData/RestaurantManagementData.asset +++ b/Assets/_DDD/_Addressables/So/RestaurantData/RestaurantManagementData.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8995b564fc56bef77202c03a2b1244f5ad12c848bc8d03682df227b505d2a2a8 -size 1003 +oid sha256:25a0d77c306ae49a158ee0149a8ca2fb9bbdc8ee932881ee887b4c4f47853c4e +size 1182 diff --git a/Assets/_DDD/_Addressables/So/UiActionInputBinding/CookUi_UiActionsInputBinding.asset b/Assets/_DDD/_Addressables/So/UiActionInputBinding/CookUi_UiActionsInputBinding.asset new file mode 100644 index 000000000..721f48e12 --- /dev/null +++ b/Assets/_DDD/_Addressables/So/UiActionInputBinding/CookUi_UiActionsInputBinding.asset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e2071ac5981e4d62e2738f900fe73d1b4018109cfab917382ca6cf3da33e3b5 +size 459 diff --git a/Assets/_DDD/_Addressables/So/UiActionInputBinding/CookUi_UiActionsInputBinding.asset.meta b/Assets/_DDD/_Addressables/So/UiActionInputBinding/CookUi_UiActionsInputBinding.asset.meta new file mode 100644 index 000000000..6b7fffb09 --- /dev/null +++ b/Assets/_DDD/_Addressables/So/UiActionInputBinding/CookUi_UiActionsInputBinding.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8dd5523e04e1abd4caff017469c49c58 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_DDD/_Scripts/GameFramework/Localization/SmartStringVariables.cs b/Assets/_DDD/_Scripts/GameFramework/Localization/SmartStringVariables.cs index 2ee3199b6..0dbf0df71 100644 --- a/Assets/_DDD/_Scripts/GameFramework/Localization/SmartStringVariables.cs +++ b/Assets/_DDD/_Scripts/GameFramework/Localization/SmartStringVariables.cs @@ -16,7 +16,7 @@ public enum SmartVariablesDomain : uint All = 0xFFFFFFFFu, } - public enum smartStringKey + public enum SmartStringKey { None = 0, Day, @@ -30,16 +30,20 @@ public enum smartStringKey public class SmartStringVariables : Singleton, IManager, IEventHandler { - private Dictionary _smartStringKeys = new() + private Dictionary _smartStringKeys = new() { - {smartStringKey.Day, "day"}, - {smartStringKey.AddedTodayFoodCount, "addedTodayFoodCount"}, - {smartStringKey.AddedTodayCookwareCount, "addedTodayCookwareCount"}, - {smartStringKey.MatchedTodayMenuWithCookwareCount, "matchedTodayMenuWithCookwareCount"}, - {smartStringKey.ChecklistFoodCount, "checklistFoodCount"}, - {smartStringKey.ChecklistCookwareCount, "checklistCookwareCount"}, - {smartStringKey.ChecklistMatchedMenuWithCookwareCount, "checklistMatchedMenuWithCookwareCount"}, + {SmartStringKey.Day, "day"}, + {SmartStringKey.AddedTodayFoodCount, "addedTodayFoodCount"}, + {SmartStringKey.AddedTodayCookwareCount, "addedTodayCookwareCount"}, + {SmartStringKey.MatchedTodayMenuWithCookwareCount, "matchedTodayMenuWithCookwareCount"}, + {SmartStringKey.ChecklistFoodCount, "checklistFoodCount"}, + {SmartStringKey.ChecklistCookwareCount, "checklistCookwareCount"}, + {SmartStringKey.ChecklistMatchedMenuWithCookwareCount, "checklistMatchedMenuWithCookwareCount"}, }; + + private GameLevelState GetGameLevelState() => GameState.Instance.LevelState; + private RestaurantManagementData GetRestaurantManagementData() => RestaurantData.Instance.ManagementData; + private RestaurantManagementState GetRestaurantManagementState() => RestaurantState.Instance.ManagementState; private void OnDestroy() { @@ -50,17 +54,13 @@ public void PreInit() { } public async Task Init() { - var gameLevelStateSo = GameState.Instance.LevelState; - var restaurantStateSo = RestaurantState.Instance.ManagementState; - - // 예시: day 초기 세팅 (없으면 생성, 타입 다르면 교체) - Set(_smartStringKeys[smartStringKey.Day], gameLevelStateSo.Level); - Set(_smartStringKeys[smartStringKey.AddedTodayFoodCount], restaurantStateSo.AddedTodayFoodCount); - Set(_smartStringKeys[smartStringKey.AddedTodayCookwareCount], restaurantStateSo.AddedTodayCookwareCount); - Set(_smartStringKeys[smartStringKey.MatchedTodayMenuWithCookwareCount], restaurantStateSo.MatchedTodayMenuWithCookwareCount); - Set(_smartStringKeys[smartStringKey.ChecklistFoodCount], restaurantStateSo.ChecklistFoodCount); - Set(_smartStringKeys[smartStringKey.ChecklistCookwareCount], restaurantStateSo.ChecklistCookwareCount); - Set(_smartStringKeys[smartStringKey.ChecklistMatchedMenuWithCookwareCount], restaurantStateSo.ChecklistMatchedMenuWithCookwareCount); + Set(_smartStringKeys[SmartStringKey.Day], GetGameLevelState().Level); + Set(_smartStringKeys[SmartStringKey.ChecklistFoodCount], GetRestaurantManagementData().ChecklistFoodCount); + Set(_smartStringKeys[SmartStringKey.ChecklistCookwareCount], GetRestaurantManagementData().ChecklistCookwareCount); + Set(_smartStringKeys[SmartStringKey.ChecklistMatchedMenuWithCookwareCount], GetRestaurantManagementData().ChecklistMatchedMenuWithCookwareCount); + Set(_smartStringKeys[SmartStringKey.AddedTodayFoodCount], GetRestaurantManagementState().AddedTodayFoodCount); + Set(_smartStringKeys[SmartStringKey.AddedTodayCookwareCount], GetRestaurantManagementState().AddedTodayCookwareCount); + Set(_smartStringKeys[SmartStringKey.MatchedTodayMenuWithCookwareCount], GetRestaurantManagementState().MatchedTodayMenuWithCookwareCount); await Task.CompletedTask; } @@ -71,8 +71,6 @@ public void PostInit() EventBus.Register(this); } - private RestaurantManagementState GetRestaurantState() => RestaurantState.Instance.ManagementState; - public void Invoke(SmartVariablesDirtyEvent evt) { var flags = evt.DomainFlags; @@ -97,24 +95,22 @@ public void Invoke(SmartVariablesDirtyEvent evt) public void RefreshTodayMenuCounts() { - var state = GetRestaurantState(); - Set(_smartStringKeys[smartStringKey.AddedTodayFoodCount], state.AddedTodayFoodCount); - Set(_smartStringKeys[smartStringKey.AddedTodayCookwareCount], state.AddedTodayCookwareCount); - Set(_smartStringKeys[smartStringKey.MatchedTodayMenuWithCookwareCount], state.MatchedTodayMenuWithCookwareCount); + Set(_smartStringKeys[SmartStringKey.AddedTodayFoodCount], GetRestaurantManagementState().AddedTodayFoodCount); + Set(_smartStringKeys[SmartStringKey.AddedTodayCookwareCount], GetRestaurantManagementState().AddedTodayCookwareCount); + Set(_smartStringKeys[SmartStringKey.MatchedTodayMenuWithCookwareCount], GetRestaurantManagementState().MatchedTodayMenuWithCookwareCount); } public void RefreshChecklistTargets() { - var state = GetRestaurantState(); - Set(_smartStringKeys[smartStringKey.ChecklistFoodCount], state.ChecklistFoodCount); - Set(_smartStringKeys[smartStringKey.ChecklistCookwareCount], state.ChecklistCookwareCount); - Set(_smartStringKeys[smartStringKey.ChecklistMatchedMenuWithCookwareCount], state.ChecklistMatchedMenuWithCookwareCount); + Set(_smartStringKeys[SmartStringKey.ChecklistFoodCount], GetRestaurantManagementData().ChecklistFoodCount); + Set(_smartStringKeys[SmartStringKey.ChecklistCookwareCount], GetRestaurantManagementData().ChecklistCookwareCount); + Set(_smartStringKeys[SmartStringKey.ChecklistMatchedMenuWithCookwareCount], GetRestaurantManagementData().ChecklistMatchedMenuWithCookwareCount); } public void RefreshDay() { var gameLevelStateSo = GameState.Instance.LevelState; - Set(_smartStringKeys[smartStringKey.Day], gameLevelStateSo.Level); + Set(_smartStringKeys[SmartStringKey.Day], gameLevelStateSo.Level); } public void RefreshAll() diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/BasePopupUi.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/BasePopupUi.cs index 43b1303af..74a905e75 100644 --- a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/BasePopupUi.cs +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/BasePopupUi.cs @@ -6,7 +6,7 @@ namespace DDD public abstract class BasePopupUi : BaseUi { public bool IsTopPopup => UiManager.Instance.UiState.IsTopPopup(this); - public InputActionMaps InputActionMaps; + public InputActionMaps InputActionMaps { get; protected set; } protected override void Awake() { diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi.meta b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi.meta new file mode 100644 index 000000000..c4f1fbe5b --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2c5267df54c97474fa824451f969b41b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookUi.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookUi.cs new file mode 100644 index 000000000..aa18279ba --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookUi.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +namespace DDD +{ + [RequireComponent(typeof(CookViewModel))] + public class CookUi : PopupUi + { + protected override GameObject GetInitialSelected() + { + return null; + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookUi.cs.meta b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookUi.cs.meta new file mode 100644 index 000000000..e5fffcb81 --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookUi.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fa01b8c8ff13d3241b943d0f12d3b767 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookViewModel.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookViewModel.cs new file mode 100644 index 000000000..d224e5100 --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookViewModel.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace DDD +{ + public class CookViewModel : SimpleViewModel + { + + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookViewModel.cs.meta b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookViewModel.cs.meta new file mode 100644 index 000000000..6667db216 --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/CookUi/CookViewModel.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7856cd3c67598cf41a31efc38bb512d9 diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/PopupUi.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/PopupUi.cs index 38be27a27..947567de3 100644 --- a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/PopupUi.cs +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/PopupUi.cs @@ -34,31 +34,16 @@ protected override void Awake() _viewModel = GetComponent(); } - - protected override void OnEnable() + + protected override void TryRegister() { - base.OnEnable(); + base.TryRegister(); if (_viewModel && _bindingContext != null) { _bindingContext.SetDataContext(_viewModel); _viewModel.PropertyChanged += OnViewModelPropertyChanged; } - } - - protected override void OnDisable() - { - base.OnDisable(); - - if (_viewModel != null) - { - _viewModel.PropertyChanged -= OnViewModelPropertyChanged; - } - } - - protected override void TryRegister() - { - base.TryRegister(); // PopupUi의 입력 바인딩 등록 foreach (var actionEnum in _uiActionsInputBinding.BindingActions.GetFlags()) @@ -98,6 +83,11 @@ protected override void TryRegister() protected override void TryUnregister() { base.TryUnregister(); + + if (_viewModel != null) + { + _viewModel.PropertyChanged -= OnViewModelPropertyChanged; + } // 입력 핸들러 해제 foreach (var (action, handler) in _registeredHandlers) diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/ItemDetailView.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/ItemDetailView.cs index 5cd0a253a..48c554123 100644 --- a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/ItemDetailView.cs +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/ItemDetailView.cs @@ -92,7 +92,7 @@ private void UpdateTasteHashTags(ItemViewModel model) var backgroundMaterial = model.RecipeType switch { RecipeType.FoodRecipe => restaurantManagementDataSo.FoodTasteMaterial, - RecipeType.DrinkRecipe => restaurantManagementDataSo.DrinkTasteMateria, + RecipeType.DrinkRecipe => restaurantManagementDataSo.DrinkTasteMaterial, _ => throw new ArgumentOutOfRangeException() }; diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/RestaurantManagementUi.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/RestaurantManagementUi.cs index cca7ea97b..a4d092d3a 100644 --- a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/RestaurantManagementUi.cs +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/RestaurantManagementUi.cs @@ -103,7 +103,7 @@ private void InitializeViews() _checklistView.Initalize(); _inventoryView.Initialize(); _itemDetailView.Initialize(); - _todayMenuView.Initialize(); + _todayMenuView.Initialize(_viewModel); _todayRestaurantStateView.Initialize(); } diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/RestaurantManagementViewModel.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/RestaurantManagementViewModel.cs index fb8825c30..d86f6a3e9 100644 --- a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/RestaurantManagementViewModel.cs +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/RestaurantManagementViewModel.cs @@ -1,63 +1,28 @@ +using System.Collections.Generic; using System.Linq; using UnityEngine; namespace DDD { - /// - /// 레스토랑 관리 UI의 ViewModel - /// 기존 RestaurantManagementUi의 상태 관리와 비즈니스 로직을 담당 - /// public class RestaurantManagementViewModel : SimpleViewModel, IEventHandler { - // 홀드 진행 상태 관리 - [SerializeField] private float _holdCompleteTime = 1f; - private bool _isHolding; + private List _foodSlots; + private List _drinkSlots; - private float _holdProgress; - public float HoldProgress - { - get => _holdProgress; - private set - { - if (SetField(ref _holdProgress, value)) - { - OnPropertyChanged(nameof(NormalizedHoldProgress)); - } - } - } + // View에서 구독할 이벤트들 + public System.Action OnBatchCompleted; + public System.Action OnChecklistFailed; + public System.Action OnMenuSectionSelected; + public System.Action OnCookwareSectionSelected; + public System.Action OnCategoryChanged; + public System.Action OnTabMoved; + public System.Action OnInteractRequested; + public System.Action OnCloseRequested; + public System.Action OnMenuCategorySelected; - /// - /// 홀드 진행률을 0~1 범위로 변환한 값 - /// - public float NormalizedHoldProgress => _holdCompleteTime <= 0f ? 0f : Mathf.Clamp01(_holdProgress / _holdCompleteTime); + private RestaurantManagementData GetRestaurantManagementData() => RestaurantData.Instance.ManagementData; + private RestaurantManagementState GetRestaurantManagementState() => RestaurantState.Instance.ManagementState; - // 탭 상태 관리 - private SectionButtonType _currentSection = SectionButtonType.Menu; - private InventoryCategoryType _currentCategory = InventoryCategoryType.Food; - - /// - /// 현재 선택된 섹션 - /// - public SectionButtonType CurrentSection - { - get => _currentSection; - set => SetField(ref _currentSection, value); - } - - /// - /// 현재 선택된 카테고리 - /// - public InventoryCategoryType CurrentCategory - { - get => _currentCategory; - set => SetField(ref _currentCategory, value); - } - - /// - /// 배치 완료 가능 여부 (체크리스트 완료 상태) - /// - public bool CanCompleteBatch => RestaurantState.Instance.ManagementState.GetChecklistStates().All(state => state); - public override void Initialize() { base.Initialize(); @@ -80,15 +45,48 @@ private void UnregisterEvents() { EventBus.Unregister(this); } - - /// - /// 홀드 진행 업데이트 (View에서 Update마다 호출) - /// + + public void InteractWithSelected() + { + OnInteractRequested?.Invoke(); + } + + public void CloseUi() + { + OnCloseRequested?.Invoke(); + } + + public void Invoke(TodayMenuRemovedEvent evt) + { + SetCategory(evt.InventoryCategoryType); + OnMenuCategorySelected?.Invoke(evt.InventoryCategoryType); + } + + #region RestaurantManagementView + + private bool _isHolding; + + private float _holdProgress; + public float HoldProgress + { + get => _holdProgress; + private set + { + if (SetField(ref _holdProgress, value)) + { + OnPropertyChanged(nameof(NormalizedHoldProgress)); + } + } + } + + public float NormalizedHoldProgress => GetRestaurantManagementData().HoldCompleteTime <= 0f ? 0f : Mathf.Clamp01(_holdProgress / GetRestaurantManagementData().HoldCompleteTime); + public bool CanCompleteBatch => GetRestaurantManagementState().GetChecklistStates().All(state => state); + public void UpdateHoldProgress() { if (_isHolding == false) return; - if (_holdCompleteTime <= 0f) + if (GetRestaurantManagementData().HoldCompleteTime <= 0f) { ProcessCompleteBatch(); return; @@ -97,24 +95,18 @@ public void UpdateHoldProgress() var deltaTime = Time.deltaTime; HoldProgress += deltaTime; - if (HoldProgress >= _holdCompleteTime) + if (HoldProgress >= GetRestaurantManagementData().HoldCompleteTime) { ProcessCompleteBatch(); } } - - /// - /// 홀드 시작 - /// + public void StartHold() { _isHolding = true; HoldProgress = 0f; } - /// - /// 홀드 취소 - /// public void CancelHold() { ResetHoldState(); @@ -125,10 +117,8 @@ private void ResetHoldState() _isHolding = false; HoldProgress = 0f; } - - /// - /// 배치 완료 처리 - /// + + private void ProcessCompleteBatch() { ResetHoldState(); @@ -144,10 +134,26 @@ private void ProcessCompleteBatch() OnChecklistFailed?.Invoke(); } } - - /// - /// 섹션 탭 선택 처리 - /// + + #endregion + + #region TabGroup + + // 탭 상태 관리 + private SectionButtonType _currentSection = SectionButtonType.Menu; + public SectionButtonType CurrentSection + { + get => _currentSection; + set => SetField(ref _currentSection, value); + } + + private InventoryCategoryType _currentCategory = InventoryCategoryType.Food; + public InventoryCategoryType CurrentCategory + { + get => _currentCategory; + set => SetField(ref _currentCategory, value); + } + public void SetSection(SectionButtonType section) { CurrentSection = section; @@ -163,57 +169,91 @@ public void SetSection(SectionButtonType section) break; } } - - /// - /// 카테고리 탭 선택 처리 - /// + public void SetCategory(InventoryCategoryType category) { CurrentCategory = category; OnCategoryChanged?.Invoke(category); } - - /// - /// 탭 이동 (이전/다음) - /// + public void MoveTab(int direction) { OnTabMoved?.Invoke(direction); } - - /// - /// 현재 선택된 UI 요소와 상호작용 - /// - public void InteractWithSelected() + + #endregion + + #region TodayMenuView + + public void CreateFoodSlot(Transform parent) { - OnInteractRequested?.Invoke(); + var foodMaxCount = GetRestaurantManagementData().MaxFoodCount; + _foodSlots = new List(foodMaxCount); + for (int i = 0; i < foodMaxCount; i++) + { + var instance = Instantiate(GetRestaurantManagementData().ItemSlotUiPrefab, parent); + var slot = instance.GetComponent(); + slot.Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe)); + var itemSlotInteractor = instance.GetComponent(); + itemSlotInteractor.Initialize(TodayMenuEventType.Remove, new TodayMenuInteractorStrategy()); + + _foodSlots.Add(slot); + } } - /// - /// UI 닫기 - /// - public void CloseUi() + public void CreateDrinkSlot(Transform parent) { - OnCloseRequested?.Invoke(); + var drinkMaxCount = GetRestaurantManagementData().MaxDrinkCount; + _drinkSlots = new List(drinkMaxCount); + for (int i = 0; i < drinkMaxCount; i++) + { + var instance = Instantiate(GetRestaurantManagementData().ItemSlotUiPrefab, parent); + var slot = instance.GetComponent(); + slot.Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe)); + var itemSlotInteractor = instance.GetComponent(); + itemSlotInteractor.Initialize(TodayMenuEventType.Remove, new TodayMenuInteractorStrategy()); + + _drinkSlots.Add(slot); + } } - // View에서 구독할 이벤트들 - public System.Action OnBatchCompleted; - public System.Action OnChecklistFailed; - public System.Action OnMenuSectionSelected; - public System.Action OnCookwareSectionSelected; - public System.Action OnCategoryChanged; - public System.Action OnTabMoved; - public System.Action OnInteractRequested; - public System.Action OnCloseRequested; - - // 이벤트 핸들러 - public void Invoke(TodayMenuRemovedEvent evt) + public void UpdateTodayMenuItems() { - SetCategory(evt.InventoryCategoryType); - OnMenuCategorySelected?.Invoke(evt.InventoryCategoryType); - } + int foodIndex = 0; + foreach (var foodRecipeIdCountPair in GetRestaurantManagementState().TodayFoodRecipeIds) + { + if (foodIndex >= _foodSlots.Count) break; + + var model = ItemViewModelFactory.CreateByItemId(foodRecipeIdCountPair.Key); + var foodSlot = _foodSlots[foodIndex]; + foodSlot.Initialize(model, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe)); + foodSlot.Model.SetCount(foodRecipeIdCountPair.Value); + foodIndex++; + } - public System.Action OnMenuCategorySelected; + for (int i = foodIndex; i < _foodSlots.Count; i++) + { + _foodSlots[i].Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe)); + } + + int drinkIndex = 0; + foreach (var drinkRecipeIdCountPair in GetRestaurantManagementState().TodayDrinkRecipeIds) + { + if (drinkIndex >= _drinkSlots.Count) break; + + var model = ItemViewModelFactory.CreateByItemId(drinkRecipeIdCountPair.Key); + var drinkSlot = _drinkSlots[drinkIndex]; + drinkSlot.Initialize(model, new TodayMenuSlotUiStrategy(RecipeType.DrinkRecipe)); + drinkSlot.Model.SetCount(drinkRecipeIdCountPair.Value); + drinkIndex++; + } + + for (int i = drinkIndex; i < _drinkSlots.Count; i++) + { + _drinkSlots[i].Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.DrinkRecipe)); + } + } + + #endregion } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/TodayMenuUi/TodayMenuView.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/TodayMenuUi/TodayMenuView.cs index 977cf8ba2..ddb149174 100644 --- a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/TodayMenuUi/TodayMenuView.cs +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/TodayMenuUi/TodayMenuView.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using System.Threading.Tasks; using UnityEngine; namespace DDD @@ -8,12 +6,8 @@ public class TodayMenuView : MonoBehaviour, IEventHandler, { [SerializeField] private Transform _todayFoodContent; [SerializeField] private Transform _todayDrinkContent; - - private List _foodSlots; - private List _drinkSlots; - - private RestaurantManagementState restaurantManagementStateSo; - private RestaurantManagementData restaurantManagementDataSo; + + private RestaurantManagementViewModel _viewModel; private void OnDestroy() { @@ -21,53 +15,30 @@ private void OnDestroy() EventBus.Unregister(this); } - public void Initialize() + public void Initialize(RestaurantManagementViewModel viewModel) { - restaurantManagementStateSo = RestaurantState.Instance.ManagementState; - restaurantManagementDataSo = RestaurantData.Instance.ManagementData; + _viewModel = viewModel; + + ClearObject(_todayFoodContent); + ClearObject(_todayDrinkContent); + + _viewModel.CreateFoodSlot(_todayFoodContent); + _viewModel.CreateDrinkSlot(_todayDrinkContent); - foreach (Transform child in _todayFoodContent) - { - Destroy(child.gameObject); - } - - int maxFoodCount = restaurantManagementStateSo!.MaxFoodCount; - _foodSlots = new List(maxFoodCount); - for (int i = 0; i < restaurantManagementStateSo.MaxFoodCount; i++) - { - var go = Instantiate(restaurantManagementDataSo.ItemSlotUiPrefab, _todayFoodContent); - var slot = go.GetComponent(); - slot.Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe)); - var itemSlotInteractor = go.GetComponent(); - itemSlotInteractor.Initialize(TodayMenuEventType.Remove, new TodayMenuInteractorStrategy()); - - _foodSlots.Add(slot); - } - - foreach (Transform child in _todayDrinkContent) - { - Destroy(child.gameObject); - } - - int maxDrinkCount = restaurantManagementStateSo.MaxDrinkCount; - _drinkSlots = new List(maxDrinkCount); - for (int i = 0; i < restaurantManagementStateSo.MaxDrinkCount; i++) - { - var go = Instantiate(restaurantManagementDataSo.ItemSlotUiPrefab, _todayDrinkContent); - var slot = go.GetComponent(); - slot.Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.DrinkRecipe)); - var itemSlotInteractor = go.GetComponent(); - itemSlotInteractor.Initialize(TodayMenuEventType.Remove, new TodayMenuInteractorStrategy()); - - _drinkSlots.Add(slot); - } - UpdateView(); EventBus.Register(this); EventBus.Register(this); } + private void ClearObject(Transform root) + { + foreach (Transform child in root) + { + Destroy(child.gameObject); + } + } + public void Invoke(TodayMenuAddedEvent evt) { UpdateView(); @@ -80,39 +51,7 @@ public void Invoke(TodayMenuRemovedEvent evt) private void UpdateView() { - int foodIndex = 0; - foreach (var foodRecipeIdCountPair in restaurantManagementStateSo.TodayFoodRecipeIds) - { - if (foodIndex >= _foodSlots.Count) break; - - var model = ItemViewModelFactory.CreateByItemId(foodRecipeIdCountPair.Key); - var foodSlot = _foodSlots[foodIndex]; - foodSlot.Initialize(model, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe)); - foodSlot.Model.SetCount(foodRecipeIdCountPair.Value); - foodIndex++; - } - - for (int i = foodIndex; i < _foodSlots.Count; i++) - { - _foodSlots[i].Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe)); - } - - int drinkIndex = 0; - foreach (var drinkRecipeIdCountPair in restaurantManagementStateSo.TodayDrinkRecipeIds) - { - if (drinkIndex >= _drinkSlots.Count) break; - - var model = ItemViewModelFactory.CreateByItemId(drinkRecipeIdCountPair.Key); - var drinkSlot = _drinkSlots[drinkIndex]; - drinkSlot.Initialize(model, new TodayMenuSlotUiStrategy(RecipeType.DrinkRecipe)); - drinkSlot.Model.SetCount(drinkRecipeIdCountPair.Value); - drinkIndex++; - } - - for (int i = drinkIndex; i < _drinkSlots.Count; i++) - { - _drinkSlots[i].Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.DrinkRecipe)); - } + _viewModel.UpdateTodayMenuItems(); } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs index 55ec2df61..8d9257c3b 100644 --- a/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi/PopupUis/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Threading.Tasks; using UnityEngine; namespace DDD @@ -31,9 +30,9 @@ public void Initialize() Destroy(child.gameObject); } - int maxCookwareCount = restaurantManagementStateSo!.MaxCookwareCount; + int maxCookwareCount = restaurantManagementDataSo!.MaxCookwareCount; _workerSlots = new List(maxCookwareCount); - for (int i = 0; i < restaurantManagementStateSo.MaxCookwareCount; i++) + for (int i = 0; i < restaurantManagementDataSo.MaxCookwareCount; i++) { var go = Instantiate(restaurantManagementDataSo.ItemSlotUiPrefab, _todayWorkerContent); var slot = go.GetComponent(); @@ -50,7 +49,7 @@ public void Initialize() } _cookwareSlots = new List(maxCookwareCount); - for (int i = 0; i < restaurantManagementStateSo.MaxCookwareCount; i++) + for (int i = 0; i < restaurantManagementDataSo.MaxCookwareCount; i++) { var go = Instantiate(restaurantManagementDataSo.ItemSlotUiPrefab, _todayCookwareContent); var slot = go.GetComponent(); diff --git a/Assets/_DDD/_Scripts/InputSystem/BaseUiActionsInputBinding.cs b/Assets/_DDD/_Scripts/InputSystem/BaseUiActionsInputBinding.cs index 617aa841b..8df340828 100644 --- a/Assets/_DDD/_Scripts/InputSystem/BaseUiActionsInputBinding.cs +++ b/Assets/_DDD/_Scripts/InputSystem/BaseUiActionsInputBinding.cs @@ -6,6 +6,7 @@ namespace DDD { public class BaseUiActionsInputBinding : ScriptableObject where T : Enum { + [ReadOnly] public InputActionMaps InputActionMaps; [EnumToggleButtons] diff --git a/Assets/_DDD/_Scripts/InputSystem/RestaurantActionsInputBinding.cs b/Assets/_DDD/_Scripts/InputSystem/RestaurantActionsInputBinding.cs index 0b02feb28..4e627e7b4 100644 --- a/Assets/_DDD/_Scripts/InputSystem/RestaurantActionsInputBinding.cs +++ b/Assets/_DDD/_Scripts/InputSystem/RestaurantActionsInputBinding.cs @@ -3,5 +3,11 @@ namespace DDD { [CreateAssetMenu(fileName = "_UiActionsInputBinding", menuName = "Ui/RestaurantActions_InputBindingSo")] - public class RestaurantActionsInputBinding : BaseUiActionsInputBinding { } + public class RestaurantActionsInputBinding : BaseUiActionsInputBinding + { + private void OnEnable() + { + InputActionMaps = InputActionMaps.Restaurant; + } + } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/InputSystem/RestaurantUiActionsInputBinding.cs b/Assets/_DDD/_Scripts/InputSystem/RestaurantUiActionsInputBinding.cs index 6674e29ee..88049f47c 100644 --- a/Assets/_DDD/_Scripts/InputSystem/RestaurantUiActionsInputBinding.cs +++ b/Assets/_DDD/_Scripts/InputSystem/RestaurantUiActionsInputBinding.cs @@ -3,5 +3,11 @@ namespace DDD { [CreateAssetMenu(fileName = "_UiActionsInputBinding", menuName = "Ui/RestaurantUiActions_InputBindingSo")] - public class RestaurantUiActionsInputBinding : BaseUiActionsInputBinding { } + public class RestaurantUiActionsInputBinding : BaseUiActionsInputBinding + { + private void OnEnable() + { + InputActionMaps = InputActionMaps.RestaurantUi; + } + } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantData/DataObjects/RestaurantManagementData.cs b/Assets/_DDD/_Scripts/RestaurantData/DataObjects/RestaurantManagementData.cs index e760073a7..bf69b4f67 100644 --- a/Assets/_DDD/_Scripts/RestaurantData/DataObjects/RestaurantManagementData.cs +++ b/Assets/_DDD/_Scripts/RestaurantData/DataObjects/RestaurantManagementData.cs @@ -1,3 +1,4 @@ +using Sirenix.OdinInspector; using UnityEngine; namespace DDD @@ -5,11 +6,24 @@ namespace DDD [CreateAssetMenu(fileName = "RestaurantManagementData", menuName = "RestaurantData/RestaurantManagementData")] public class RestaurantManagementData : ScriptableObject { + public float HoldCompleteTime = 1f; + + [Title("오늘의 레스토랑 상태")] + public int MaxFoodCount = 8; + public int MaxDrinkCount = 6; + public int MaxCookwareCount = 6; + + [Title("체크리스트 조건")] + public int ChecklistFoodCount = 1; + public int ChecklistCookwareCount = 1; + public int ChecklistMatchedMenuWithCookwareCount = 1; + + [Title("컴포넌트")] public ItemSlotUi ItemSlotUiPrefab; public TasteHashTagSlotUi TasteHashTagSlotUiPrefab; public Material FoodTasteMaterial; - public Material DrinkTasteMateria; + public Material DrinkTasteMaterial; public RuntimeAnimatorController TodayMenuSlotUiAnimatorController; public RuntimeAnimatorController InventorySlotUiAnimatorController; diff --git a/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantManagementState.cs b/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantManagementState.cs index 1ad52ed1b..16a2b1138 100644 --- a/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantManagementState.cs +++ b/Assets/_DDD/_Scripts/RestaurantState/FlowStates/RestaurantManagementState.cs @@ -7,23 +7,11 @@ namespace DDD { public class RestaurantManagementState : ScriptableObject { - // TODO : 데이터에서 초기화하고, 동적으로 변경 - [Title("오늘의 레스토랑 상태")] - public int MaxFoodCount = 8; - public int MaxDrinkCount = 6; - public int MaxCookwareCount = 6; - - [Title("체크리스트 조건")] - public int ChecklistFoodCount = 1; - public int ChecklistCookwareCount = 1; - public int ChecklistMatchedMenuWithCookwareCount = 1; - - [Title("실시간 데이터")] - [ReadOnly, SerializeField] private bool _isOpenable; - [ReadOnly, ShowInInspector] private Dictionary _todayFoodRecipeIds = new(); - [ReadOnly, ShowInInspector] private Dictionary _todayDrinkRecipeIds = new(); - [ReadOnly, ShowInInspector] private List _todayWorkerIds = new(); - [ReadOnly, ShowInInspector] private Dictionary> _cookwareToRecipeIds = new(); + private bool _isOpenable; + private Dictionary _todayFoodRecipeIds = new(); + private Dictionary _todayDrinkRecipeIds = new(); + private List _todayWorkerIds = new(); + private Dictionary> _cookwareToRecipeIds = new(); public IReadOnlyDictionary TodayFoodRecipeIds => _todayFoodRecipeIds; public IReadOnlyDictionary TodayDrinkRecipeIds => _todayDrinkRecipeIds; @@ -36,6 +24,8 @@ public class RestaurantManagementState : ScriptableObject public int AddedTodayWorkerCount => _todayWorkerIds.Count; public int AddedTodayCookwareCount => _cookwareToRecipeIds.Count; public int MatchedTodayMenuWithCookwareCount => _cookwareToRecipeIds.Values.Count(recipeSet => recipeSet.Count > 0); + + private RestaurantManagementData GetRestaurantManagementData() => RestaurantData.Instance.ManagementData; public void InitializeReadyForRestaurant() { @@ -101,7 +91,7 @@ public bool TryAddTodayMenu(ItemViewModel model) if (recipeData.RecipeType == RecipeType.FoodRecipe) { - if (_todayFoodRecipeIds.Count >= MaxFoodCount || _todayFoodRecipeIds.ContainsKey(recipeId)) return false; + if (_todayFoodRecipeIds.Count >= GetRestaurantManagementData().MaxFoodCount || _todayFoodRecipeIds.ContainsKey(recipeId)) return false; var foodData = DataManager.Instance.GetDataSo().GetDataById(recipeData.RecipeResult); var craftableCount = foodData.GetCraftableCount(); @@ -112,7 +102,7 @@ public bool TryAddTodayMenu(ItemViewModel model) } else if (recipeData.RecipeType == RecipeType.DrinkRecipe) { - if (_todayDrinkRecipeIds.Count >= MaxDrinkCount || _todayDrinkRecipeIds.ContainsKey(recipeId)) return false; + if (_todayDrinkRecipeIds.Count >= GetRestaurantManagementData().MaxDrinkCount || _todayDrinkRecipeIds.ContainsKey(recipeId)) return false; var drinkData = DataManager.Instance.GetDataSo().GetDataById(recipeData.RecipeResult); var craftableCount = drinkData.GetCraftableCount(); @@ -201,7 +191,7 @@ public bool TryAddTodayCookware(ItemViewModel model) if (model.HasItem == false || DataManager.Instance.GetDataSo().ContainsData(cookwareId) == false) return false; - if (_cookwareToRecipeIds.Count >= MaxCookwareCount || _cookwareToRecipeIds.ContainsKey(cookwareId)) return false; + if (_cookwareToRecipeIds.Count >= GetRestaurantManagementData().MaxCookwareCount || _cookwareToRecipeIds.ContainsKey(cookwareId)) return false; _cookwareToRecipeIds[cookwareId] = new HashSet();