TodayMenuView viewModel 로직 분리

This commit is contained in:
NTG 2025-08-21 18:15:51 +09:00
parent 4867427b8b
commit 5b0e6fd786
22 changed files with 332 additions and 268 deletions

View File

@ -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:
<UiType>k__BackingField: 3
_enableBlockImage: 0
_uiActionsInputBinding: {fileID: 11400000, guid: 8dd5523e04e1abd4caff017469c49c58, type: 2}

Binary file not shown.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8dd5523e04e1abd4caff017469c49c58
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -16,7 +16,7 @@ public enum SmartVariablesDomain : uint
All = 0xFFFFFFFFu,
}
public enum smartStringKey
public enum SmartStringKey
{
None = 0,
Day,
@ -30,17 +30,21 @@ public enum smartStringKey
public class SmartStringVariables : Singleton<SmartStringVariables>, IManager, IEventHandler<SmartVariablesDirtyEvent>
{
private Dictionary<smartStringKey, string> _smartStringKeys = new()
private Dictionary<SmartStringKey, string> _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()
{
EventBus.Unregister<SmartVariablesDirtyEvent>(this);
@ -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<SmartVariablesDirtyEvent>(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()

View File

@ -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()
{

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2c5267df54c97474fa824451f969b41b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,13 @@
using UnityEngine;
namespace DDD
{
[RequireComponent(typeof(CookViewModel))]
public class CookUi : PopupUi<RestaurantUiActions, CookViewModel>
{
protected override GameObject GetInitialSelected()
{
return null;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fa01b8c8ff13d3241b943d0f12d3b767

View File

@ -0,0 +1,9 @@
using UnityEngine;
namespace DDD
{
public class CookViewModel : SimpleViewModel
{
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7856cd3c67598cf41a31efc38bb512d9

View File

@ -35,30 +35,15 @@ protected override void Awake()
_viewModel = GetComponent<TViewModel>();
}
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())
@ -99,6 +84,11 @@ protected override void TryUnregister()
{
base.TryUnregister();
if (_viewModel != null)
{
_viewModel.PropertyChanged -= OnViewModelPropertyChanged;
}
// 입력 핸들러 해제
foreach (var (action, handler) in _registeredHandlers)
{

View File

@ -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()
};

View File

@ -103,7 +103,7 @@ private void InitializeViews()
_checklistView.Initalize();
_inventoryView.Initialize();
_itemDetailView.Initialize();
_todayMenuView.Initialize();
_todayMenuView.Initialize(_viewModel);
_todayRestaurantStateView.Initialize();
}

View File

@ -1,62 +1,27 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace DDD
{
/// <summary>
/// 레스토랑 관리 UI의 ViewModel
/// 기존 RestaurantManagementUi의 상태 관리와 비즈니스 로직을 담당
/// </summary>
public class RestaurantManagementViewModel : SimpleViewModel, IEventHandler<TodayMenuRemovedEvent>
{
// 홀드 진행 상태 관리
[SerializeField] private float _holdCompleteTime = 1f;
private bool _isHolding;
private List<ItemSlotUi> _foodSlots;
private List<ItemSlotUi> _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<InventoryCategoryType> OnCategoryChanged;
public System.Action<int> OnTabMoved;
public System.Action OnInteractRequested;
public System.Action OnCloseRequested;
public System.Action<InventoryCategoryType> OnMenuCategorySelected;
/// <summary>
/// 홀드 진행률을 0~1 범위로 변환한 값
/// </summary>
public float NormalizedHoldProgress => _holdCompleteTime <= 0f ? 0f : Mathf.Clamp01(_holdProgress / _holdCompleteTime);
// 탭 상태 관리
private SectionButtonType _currentSection = SectionButtonType.Menu;
private InventoryCategoryType _currentCategory = InventoryCategoryType.Food;
/// <summary>
/// 현재 선택된 섹션
/// </summary>
public SectionButtonType CurrentSection
{
get => _currentSection;
set => SetField(ref _currentSection, value);
}
/// <summary>
/// 현재 선택된 카테고리
/// </summary>
public InventoryCategoryType CurrentCategory
{
get => _currentCategory;
set => SetField(ref _currentCategory, value);
}
/// <summary>
/// 배치 완료 가능 여부 (체크리스트 완료 상태)
/// </summary>
public bool CanCompleteBatch => RestaurantState.Instance.ManagementState.GetChecklistStates().All(state => state);
private RestaurantManagementData GetRestaurantManagementData() => RestaurantData.Instance.ManagementData;
private RestaurantManagementState GetRestaurantManagementState() => RestaurantState.Instance.ManagementState;
public override void Initialize()
{
@ -81,14 +46,47 @@ private void UnregisterEvents()
EventBus.Unregister<TodayMenuRemovedEvent>(this);
}
/// <summary>
/// 홀드 진행 업데이트 (View에서 Update마다 호출)
/// </summary>
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();
}
}
/// <summary>
/// 홀드 시작
/// </summary>
public void StartHold()
{
_isHolding = true;
HoldProgress = 0f;
}
/// <summary>
/// 홀드 취소
/// </summary>
public void CancelHold()
{
ResetHoldState();
@ -126,9 +118,7 @@ private void ResetHoldState()
HoldProgress = 0f;
}
/// <summary>
/// 배치 완료 처리
/// </summary>
private void ProcessCompleteBatch()
{
ResetHoldState();
@ -145,9 +135,25 @@ private void ProcessCompleteBatch()
}
}
/// <summary>
/// 섹션 탭 선택 처리
/// </summary>
#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;
@ -164,56 +170,90 @@ public void SetSection(SectionButtonType section)
}
}
/// <summary>
/// 카테고리 탭 선택 처리
/// </summary>
public void SetCategory(InventoryCategoryType category)
{
CurrentCategory = category;
OnCategoryChanged?.Invoke(category);
}
/// <summary>
/// 탭 이동 (이전/다음)
/// </summary>
public void MoveTab(int direction)
{
OnTabMoved?.Invoke(direction);
}
/// <summary>
/// 현재 선택된 UI 요소와 상호작용
/// </summary>
public void InteractWithSelected()
#endregion
#region TodayMenuView
public void CreateFoodSlot(Transform parent)
{
OnInteractRequested?.Invoke();
var foodMaxCount = GetRestaurantManagementData().MaxFoodCount;
_foodSlots = new List<ItemSlotUi>(foodMaxCount);
for (int i = 0; i < foodMaxCount; i++)
{
var instance = Instantiate(GetRestaurantManagementData().ItemSlotUiPrefab, parent);
var slot = instance.GetComponent<ItemSlotUi>();
slot.Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe));
var itemSlotInteractor = instance.GetComponent<ItemSlotInteractor>();
itemSlotInteractor.Initialize(TodayMenuEventType.Remove, new TodayMenuInteractorStrategy());
_foodSlots.Add(slot);
}
}
/// <summary>
/// UI 닫기
/// </summary>
public void CloseUi()
public void CreateDrinkSlot(Transform parent)
{
OnCloseRequested?.Invoke();
var drinkMaxCount = GetRestaurantManagementData().MaxDrinkCount;
_drinkSlots = new List<ItemSlotUi>(drinkMaxCount);
for (int i = 0; i < drinkMaxCount; i++)
{
var instance = Instantiate(GetRestaurantManagementData().ItemSlotUiPrefab, parent);
var slot = instance.GetComponent<ItemSlotUi>();
slot.Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe));
var itemSlotInteractor = instance.GetComponent<ItemSlotInteractor>();
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<InventoryCategoryType> OnCategoryChanged;
public System.Action<int> 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++;
}
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));
}
}
public System.Action<InventoryCategoryType> OnMenuCategorySelected;
#endregion
}
}

View File

@ -1,5 +1,3 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
namespace DDD
@ -9,11 +7,7 @@ public class TodayMenuView : MonoBehaviour, IEventHandler<TodayMenuAddedEvent>,
[SerializeField] private Transform _todayFoodContent;
[SerializeField] private Transform _todayDrinkContent;
private List<ItemSlotUi> _foodSlots;
private List<ItemSlotUi> _drinkSlots;
private RestaurantManagementState restaurantManagementStateSo;
private RestaurantManagementData restaurantManagementDataSo;
private RestaurantManagementViewModel _viewModel;
private void OnDestroy()
{
@ -21,46 +15,15 @@ private void OnDestroy()
EventBus.Unregister<TodayMenuRemovedEvent>(this);
}
public void Initialize()
public void Initialize(RestaurantManagementViewModel viewModel)
{
restaurantManagementStateSo = RestaurantState.Instance.ManagementState;
restaurantManagementDataSo = RestaurantData.Instance.ManagementData;
_viewModel = viewModel;
foreach (Transform child in _todayFoodContent)
{
Destroy(child.gameObject);
}
ClearObject(_todayFoodContent);
ClearObject(_todayDrinkContent);
int maxFoodCount = restaurantManagementStateSo!.MaxFoodCount;
_foodSlots = new List<ItemSlotUi>(maxFoodCount);
for (int i = 0; i < restaurantManagementStateSo.MaxFoodCount; i++)
{
var go = Instantiate(restaurantManagementDataSo.ItemSlotUiPrefab, _todayFoodContent);
var slot = go.GetComponent<ItemSlotUi>();
slot.Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.FoodRecipe));
var itemSlotInteractor = go.GetComponent<ItemSlotInteractor>();
itemSlotInteractor.Initialize(TodayMenuEventType.Remove, new TodayMenuInteractorStrategy());
_foodSlots.Add(slot);
}
foreach (Transform child in _todayDrinkContent)
{
Destroy(child.gameObject);
}
int maxDrinkCount = restaurantManagementStateSo.MaxDrinkCount;
_drinkSlots = new List<ItemSlotUi>(maxDrinkCount);
for (int i = 0; i < restaurantManagementStateSo.MaxDrinkCount; i++)
{
var go = Instantiate(restaurantManagementDataSo.ItemSlotUiPrefab, _todayDrinkContent);
var slot = go.GetComponent<ItemSlotUi>();
slot.Initialize(null, new TodayMenuSlotUiStrategy(RecipeType.DrinkRecipe));
var itemSlotInteractor = go.GetComponent<ItemSlotInteractor>();
itemSlotInteractor.Initialize(TodayMenuEventType.Remove, new TodayMenuInteractorStrategy());
_drinkSlots.Add(slot);
}
_viewModel.CreateFoodSlot(_todayFoodContent);
_viewModel.CreateDrinkSlot(_todayDrinkContent);
UpdateView();
@ -68,6 +31,14 @@ public void Initialize()
EventBus.Register<TodayMenuRemovedEvent>(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();
}
}
}

View File

@ -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<ItemSlotUi>(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<ItemSlotUi>();
@ -50,7 +49,7 @@ public void Initialize()
}
_cookwareSlots = new List<ItemSlotUi>(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<ItemSlotUi>();

View File

@ -6,6 +6,7 @@ namespace DDD
{
public class BaseUiActionsInputBinding<T> : ScriptableObject where T : Enum
{
[ReadOnly]
public InputActionMaps InputActionMaps;
[EnumToggleButtons]

View File

@ -3,5 +3,11 @@
namespace DDD
{
[CreateAssetMenu(fileName = "_UiActionsInputBinding", menuName = "Ui/RestaurantActions_InputBindingSo")]
public class RestaurantActionsInputBinding : BaseUiActionsInputBinding<RestaurantActions> { }
public class RestaurantActionsInputBinding : BaseUiActionsInputBinding<RestaurantActions>
{
private void OnEnable()
{
InputActionMaps = InputActionMaps.Restaurant;
}
}
}

View File

@ -3,5 +3,11 @@
namespace DDD
{
[CreateAssetMenu(fileName = "_UiActionsInputBinding", menuName = "Ui/RestaurantUiActions_InputBindingSo")]
public class RestaurantUiActionsInputBinding : BaseUiActionsInputBinding<RestaurantUiActions> { }
public class RestaurantUiActionsInputBinding : BaseUiActionsInputBinding<RestaurantUiActions>
{
private void OnEnable()
{
InputActionMaps = InputActionMaps.RestaurantUi;
}
}
}

View File

@ -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;

View File

@ -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<string, int> _todayFoodRecipeIds = new();
[ReadOnly, ShowInInspector] private Dictionary<string, int> _todayDrinkRecipeIds = new();
[ReadOnly, ShowInInspector] private List<string> _todayWorkerIds = new();
[ReadOnly, ShowInInspector] private Dictionary<string, HashSet<string>> _cookwareToRecipeIds = new();
private bool _isOpenable;
private Dictionary<string, int> _todayFoodRecipeIds = new();
private Dictionary<string, int> _todayDrinkRecipeIds = new();
private List<string> _todayWorkerIds = new();
private Dictionary<string, HashSet<string>> _cookwareToRecipeIds = new();
public IReadOnlyDictionary<string, int> TodayFoodRecipeIds => _todayFoodRecipeIds;
public IReadOnlyDictionary<string, int> TodayDrinkRecipeIds => _todayDrinkRecipeIds;
@ -37,6 +25,8 @@ public class RestaurantManagementState : ScriptableObject
public int AddedTodayCookwareCount => _cookwareToRecipeIds.Count;
public int MatchedTodayMenuWithCookwareCount => _cookwareToRecipeIds.Values.Count(recipeSet => recipeSet.Count > 0);
private RestaurantManagementData GetRestaurantManagementData() => RestaurantData.Instance.ManagementData;
public void InitializeReadyForRestaurant()
{
// TODO : Load from disk if possible (save data)
@ -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<FoodDataSo>().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<DrinkDataSo>().GetDataById(recipeData.RecipeResult);
var craftableCount = drinkData.GetCraftableCount();
@ -201,7 +191,7 @@ public bool TryAddTodayCookware(ItemViewModel model)
if (model.HasItem == false || DataManager.Instance.GetDataSo<CookwareDataSo>().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<string>();