using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Localization.SmartFormat.PersistentVariables;
namespace DDD
{
///
/// Smart String 변수 전담 매니저.
/// - VariablesGroupAsset 안의 변수들을 생성/재사용하고 값만 갱신(무가비지).
/// - {day}, {playerName}, {money} 등 공용 Set API 제공.
///
public class SmartStringVariables : Singleton, IManager
{
private VariablesGroupAsset _vars;
private GameStateSo _gameStateSo;
private const string VariablesGroupAssetKey = "SmartStringGroup";
private const string Daykey = "day";
public void PreInit() { }
public async Task Init()
{
_vars = await AssetManager.LoadAsset(VariablesGroupAssetKey);
Debug.Assert(_vars != null, "_variablesGroupAsset is null");
_gameStateSo = await AssetManager.LoadAsset(DataConstants.GameStateSo);
Debug.Assert(_gameStateSo != null, "_gameStateSo is null");
// 예시: day 초기 세팅 (없으면 생성, 타입 다르면 교체)
Set(Daykey, _gameStateSo.GetCurrentLevel());
}
public void PostInit() { }
public VariablesGroupAsset GetVariablesGroupAsset() => _vars;
// ---------- 공용 Set API (가비지 최소화) ----------
/// int 변수 세팅. {key} 로 접근.
public void Set(string key, int value)
{
var v = Ensure(key);
if (v.Value != value) v.Value = value;
}
/// float 변수 세팅. {key} 로 접근.
public void Set(string key, float value)
{
var v = Ensure(key);
if (!Mathf.Approximately(v.Value, value)) v.Value = value;
}
/// bool 변수 세팅. {key} 로 접근.
public void Set(string key, bool value)
{
var v = Ensure(key);
if (v.Value != value) v.Value = value;
}
/// string 변수 세팅. {key} 로 접근.
public void Set(string key, string value)
{
var v = Ensure(key);
if (!string.Equals(v.Value, value)) v.Value = value;
}
///
/// enum은 보통 현지화 포맷에서 문자열로 취급하는 편이 직관적입니다.
/// 필요시 IntVariable로 바꾸고 (int)(object)value 저장하는 버전도 추가 가능.
///
public void SetEnum(string key, TEnum value) where TEnum : struct
{
var v = Ensure(key);
string s = value.ToString();
if (!string.Equals(v.Value, s)) v.Value = s;
}
// ---------- 유틸 ----------
///
/// key에 해당하는 변수가 있고 타입이 일치하면 캐시 반환.
/// 없거나 타입이 다르면 교체(Add/Remove)하여 보장.
///
private T Ensure(string key) where T : class, IVariable, new()
{
Debug.Assert(!string.IsNullOrEmpty(key), "SmartStringVariables.Ensure: key is null or empty.");
Debug.Assert(_vars != null, "SmartStringVariables.Ensure: _vars is null (Init 순서 확인).");
if (_vars.TryGetValue(key, out var existing))
{
if (existing is T ok) return ok;
_vars.Remove(key); // 타입 다르면 제거 후 교체
}
var created = new T();
_vars.Add(key, created);
return (T)created;
}
/// 변수 존재 여부.
public bool Has(string key) => _vars != null && _vars.ContainsKey(key);
/// 변수 제거.
public bool Remove(string key) => _vars != null && _vars.Remove(key);
}
}