197 lines
7.4 KiB
C#
197 lines
7.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.Localization.SmartFormat.PersistentVariables;
|
|
|
|
namespace DDD
|
|
{
|
|
[Flags]
|
|
public enum SmartVariablesDomain : uint
|
|
{
|
|
None = 0u,
|
|
RestaurantToday = 1u << 0,
|
|
ChecklistTargets = 1u << 1,
|
|
PlayerLevel = 1u << 2,
|
|
All = 0xFFFFFFFFu,
|
|
}
|
|
|
|
public enum smartStringKey
|
|
{
|
|
None = 0,
|
|
Day,
|
|
AddedTodayFoodCount,
|
|
AddedTodayCookwareCount,
|
|
MatchedTodayMenuWithCookwareCount,
|
|
ChecklistFoodCount,
|
|
ChecklistCookwareCount,
|
|
ChecklistMatchedMenuWithCookwareCount,
|
|
}
|
|
|
|
public class SmartStringVariables : Singleton<SmartStringVariables>, IManager, IEventHandler<SmartVariablesDirtyEvent>
|
|
{
|
|
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"},
|
|
};
|
|
|
|
private void OnDestroy()
|
|
{
|
|
EventBus.Unregister<SmartVariablesDirtyEvent>(this);
|
|
}
|
|
|
|
public void PreInit() { }
|
|
|
|
public async Task Init()
|
|
{
|
|
var gameLevelStateSo = GameStateSo.instance.GameLevelStateSo;
|
|
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);
|
|
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
public void PostInit()
|
|
{
|
|
// 도메인 단위 더티 이벤트를 구독하여 필요한 key만 갱신
|
|
EventBus.Register<SmartVariablesDirtyEvent>(this);
|
|
}
|
|
|
|
private RestaurantManagementStateSo GetRestaurantState() => RestaurantState.instance.ManagementState;
|
|
|
|
public void Invoke(SmartVariablesDirtyEvent evt)
|
|
{
|
|
var flags = evt.DomainFlags;
|
|
if (flags == SmartVariablesDomain.All)
|
|
{
|
|
RefreshAll();
|
|
return;
|
|
}
|
|
if ((flags & SmartVariablesDomain.RestaurantToday) != 0)
|
|
{
|
|
RefreshTodayMenuCounts();
|
|
}
|
|
if ((flags & SmartVariablesDomain.ChecklistTargets) != 0)
|
|
{
|
|
RefreshChecklistTargets();
|
|
}
|
|
if ((flags & SmartVariablesDomain.PlayerLevel) != 0)
|
|
{
|
|
RefreshDay();
|
|
}
|
|
}
|
|
|
|
public void RefreshTodayMenuCounts()
|
|
{
|
|
var state = GetRestaurantState();
|
|
Set(_smartStringKeys[smartStringKey.AddedTodayFoodCount], state.AddedTodayFoodCount);
|
|
Set(_smartStringKeys[smartStringKey.AddedTodayCookwareCount], state.AddedTodayCookwareCount);
|
|
Set(_smartStringKeys[smartStringKey.MatchedTodayMenuWithCookwareCount], state.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);
|
|
}
|
|
|
|
public void RefreshDay()
|
|
{
|
|
var gameLevelStateSo = GameStateSo.instance.GameLevelStateSo;
|
|
Set(_smartStringKeys[smartStringKey.Day], gameLevelStateSo.Level);
|
|
}
|
|
|
|
public void RefreshAll()
|
|
{
|
|
RefreshDay();
|
|
RefreshTodayMenuCounts();
|
|
RefreshChecklistTargets();
|
|
}
|
|
|
|
// ---------- 공용 Set API (가비지 최소화) ----------
|
|
|
|
/// <summary>int 변수 세팅. {key} 로 접근.</summary>
|
|
public void Set(string key, int value)
|
|
{
|
|
var v = Ensure<IntVariable>(key);
|
|
if (v.Value != value) v.Value = value;
|
|
}
|
|
|
|
/// <summary>float 변수 세팅. {key} 로 접근.</summary>
|
|
public void Set(string key, float value)
|
|
{
|
|
var v = Ensure<FloatVariable>(key);
|
|
if (Mathf.Approximately(v.Value, value) == false) v.Value = value;
|
|
}
|
|
|
|
/// <summary>bool 변수 세팅. {key} 로 접근.</summary>
|
|
public void Set(string key, bool value)
|
|
{
|
|
var v = Ensure<BoolVariable>(key);
|
|
if (v.Value != value) v.Value = value;
|
|
}
|
|
|
|
/// <summary>string 변수 세팅. {key} 로 접근.</summary>
|
|
public void Set(string key, string value)
|
|
{
|
|
var v = Ensure<StringVariable>(key);
|
|
if (string.Equals(v.Value, value) == false) v.Value = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// enum은 보통 현지화 포맷에서 문자열로 취급하는 편이 직관적입니다.
|
|
/// 필요시 IntVariable로 바꾸고 (int)(object)value 저장하는 버전도 추가 가능.
|
|
/// </summary>
|
|
public void SetEnum<TEnum>(string key, TEnum value) where TEnum : struct
|
|
{
|
|
var v = Ensure<StringVariable>(key);
|
|
string s = value.ToString();
|
|
if (string.Equals(v.Value, s) == false) v.Value = s;
|
|
}
|
|
|
|
// ---------- 유틸 ----------
|
|
|
|
/// <summary>
|
|
/// key에 해당하는 변수가 있고 타입이 일치하면 캐시 반환.
|
|
/// 없거나 타입이 다르면 교체(Add/Remove)하여 보장.
|
|
/// </summary>
|
|
private T Ensure<T>(string key) where T : class, IVariable, new()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(key))
|
|
{
|
|
Debug.LogError("SmartStringVariables.Ensure: key is null or empty.");
|
|
return null;
|
|
}
|
|
|
|
var smartStringVariableGroup = GameDataSo.instance.GameLocalizationData.SmartStringVariableGroup;
|
|
|
|
if (smartStringVariableGroup.TryGetValue(key, out var existing))
|
|
{
|
|
if (existing is T hasType) return hasType;
|
|
|
|
smartStringVariableGroup.Remove(key); // 타입 다르면 제거 후 교체
|
|
}
|
|
|
|
var created = new T();
|
|
smartStringVariableGroup.Add(key, created);
|
|
return (T)created;
|
|
}
|
|
}
|
|
}
|