ProjectDDD/Assets/_DDD/_Scripts/GameUi/New/InventoryView.cs
2025-07-28 04:51:11 +09:00

129 lines
4.6 KiB
C#

using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
namespace DDD
{
public class InventoryView : MonoBehaviour, IEventHandler<InventoryChangedEvent>, IEventHandler<TodayMenuAddedEvent>, IEventHandler<TodayMenuRemovedEvent>
{
[SerializeField] private Transform _slotParent;
[SerializeField] private GameObject _slotPrefab;
private RestaurantManagementSo _restaurantManagementSo;
private InventoryCategoryType _currenInventoryCategoryType = InventoryCategoryType.None;
private readonly Dictionary<string, IInventorySlotUi> _slotLookup = new();
private readonly Dictionary<string, ItemViewModel> _modelLookup = new();
private void OnEnable()
{
EventBus.Register<InventoryChangedEvent>(this);
EventBus.Register<TodayMenuAddedEvent>(this);
EventBus.Register<TodayMenuRemovedEvent>(this);
}
private void OnDisable()
{
EventBus.Unregister<InventoryChangedEvent>(this);
EventBus.Unregister<TodayMenuAddedEvent>(this);
EventBus.Unregister<TodayMenuRemovedEvent>(this);
}
public async Task Initialize()
{
_restaurantManagementSo = await AssetManager.LoadAsset<RestaurantManagementSo>(DataConstants.RestaurantManagementSo);
Debug.Assert(_restaurantManagementSo != null, "_todayMenuDataSo != null");
Clear();
var models = ItemViewModelFactory.CreateRestaurantManagementInventoryItem();
_slotLookup.Clear();
_modelLookup.Clear();
foreach (var model in models)
{
var go = Instantiate(_slotPrefab, _slotParent);
var slot = go.GetComponent<IInventorySlotUi>();
slot.Initialize(model);
var interactor = go.GetComponent<TodayMenuInteractor>();
interactor.Initialize(TodayMenuEventType.Add);
_slotLookup[model.Id] = slot;
_modelLookup[model.Id] = model;
}
}
public void UpdateCategoryView(InventoryCategoryType category)
{
_currenInventoryCategoryType = category;
foreach (var kvp in _slotLookup)
{
var id = kvp.Key;
var slot = kvp.Value;
var model = slot.Model;
// 1. 오늘의 메뉴에 등록된 경우 필터링
bool isRegisteredTodayMenu = model.ItemType == ItemType.Recipe && _restaurantManagementSo.IsContainTodayMenu(id);
// 2. 현재 선택된 카테고리에 맞는지 필터링
bool matchCategory = MatchesCategory(model, _currenInventoryCategoryType);
// 3. 조건을 모두 만족할 경우만 활성화
bool shouldShow = !isRegisteredTodayMenu && matchCategory;
slot.SetActive(shouldShow);
}
}
private bool MatchesCategory(ItemViewModel model, InventoryCategoryType category)
{
switch (category)
{
case InventoryCategoryType.Food:
if (model.ItemType != ItemType.Recipe) return false;
return DataManager.Instance.RecipeDataSo.TryGetDataById(model.Id, out var foodRecipe) && foodRecipe.RecipeType == RecipeType.FoodRecipe;
case InventoryCategoryType.Drink:
if (model.ItemType != ItemType.Recipe) return false;
return DataManager.Instance.RecipeDataSo.TryGetDataById(model.Id, out var drinkRecipe) && drinkRecipe.RecipeType == RecipeType.DrinkRecipe;
case InventoryCategoryType.Ingredient:
return model.ItemType == ItemType.Ingredient;
default:
return false;
}
}
public void UpdateView()
{
UpdateCategoryView(_currenInventoryCategoryType);
}
private void Clear()
{
foreach (Transform child in _slotParent)
{
Destroy(child.gameObject);
}
}
public void Invoke(InventoryChangedEvent evt)
{
if (_slotLookup.TryGetValue(evt.ItemId, out var slot))
{
slot.Model.UpdateCount(evt.NewCount);
}
}
public void Invoke(TodayMenuAddedEvent evt)
{
UpdateView();
}
public void Invoke(TodayMenuRemovedEvent evt)
{
UpdateView();
}
}
}