- SelectRoleForm 五层归位:UseCase 改为构造注入 IProcedureMenu(新增 Runtime/ProcedureInterface),RawData 暴露原始 StatModifier[] 而非展示串,Controller 复用 ItemDescUtility 拼装属性文本,并修复 OpenUIAsync(object) 合法 RawData 分支缺少 return 的误报路径 - StatModifier 去展示职责:删除 _statTypeNames / ToString,富文本格式化下沉到 Presentation 层的 ItemDescUtility.Describe(StatModifier),CreatePropDescription 改用统一入口 - 事件目录按 UIForm 归档:Base/Event/UI/Menu/* 拆解到 SelectRoleForm/ MenuForm/ DialogForm/ DisplayItemInfoForm/ Combat/ 等各自子目录,MenuSelectRoleReturnEventArgs 改名 SelectRoleReturnEventArgs,语义归属本 UI 模块 - IUIFormController → IUIController 改名,联动 UIControllerBase / UIRouterComponent / Editor - 同步更新 docs/UI-5层架构设计规范.md 中相关示例与 MenuForm.prefab、ProcedureMenu 引用
113 lines
3.1 KiB
C#
113 lines
3.1 KiB
C#
using Cysharp.Threading.Tasks;
|
|
using SepCore.Definition;
|
|
using UnityGameFramework.Runtime;
|
|
using SepCore.AsyncTask;
|
|
|
|
namespace SepCore.UI
|
|
{
|
|
public abstract class UIControllerBase<TContext, TForm> : IUIController
|
|
where TContext : UIContext
|
|
where TForm : UGuiForm
|
|
{
|
|
private TContext _context;
|
|
private TForm _form;
|
|
private int? _formSerialId;
|
|
|
|
protected TContext Context => _context;
|
|
|
|
protected TForm Form => _form;
|
|
|
|
protected abstract UIFormType UIFormType { get; }
|
|
|
|
protected abstract void RefreshUI(TForm form, TContext context);
|
|
|
|
protected virtual void SubscribeCustomEvents()
|
|
{
|
|
}
|
|
|
|
protected virtual void UnsubscribeCustomEvents()
|
|
{
|
|
}
|
|
|
|
protected virtual void CloseLoadedFormDirect(TForm form)
|
|
{
|
|
form.Close();
|
|
}
|
|
|
|
protected async UniTask<int?> OpenFormAsync(TContext context, float timeout = 30f)
|
|
{
|
|
if (context == null)
|
|
{
|
|
Log.Warning("{0}.OpenFormAsync() context is null.", GetType().Name);
|
|
return null;
|
|
}
|
|
|
|
if (_form != null)
|
|
{
|
|
_context = context;
|
|
RefreshUI(_form, _context);
|
|
return _formSerialId;
|
|
}
|
|
|
|
_context = context;
|
|
|
|
UIForm uiForm = await GameEntry.UI.OpenUIFormAsync(UIFormType, _context, timeout);
|
|
if (uiForm == null)
|
|
{
|
|
Log.Warning("{0}.OpenFormAsync() failed to open form '{1}'.", GetType().Name, UIFormType.ToString());
|
|
return null;
|
|
}
|
|
|
|
_formSerialId = uiForm.SerialId;
|
|
_form = uiForm.Logic as TForm;
|
|
if (_form == null)
|
|
{
|
|
Log.Warning("{0} open success but form logic is invalid.", GetType().Name);
|
|
_context = null;
|
|
_formSerialId = null;
|
|
return null;
|
|
}
|
|
|
|
SubscribeCustomEvents();
|
|
RefreshUI(_form, _context);
|
|
return _formSerialId;
|
|
}
|
|
|
|
protected virtual async UniTask CloseFormAsync(object userData = null, float timeout = 30f)
|
|
{
|
|
UnsubscribeCustomEvents();
|
|
|
|
int? serialId = _formSerialId;
|
|
TForm form = _form;
|
|
|
|
_context = null;
|
|
_form = null;
|
|
_formSerialId = null;
|
|
|
|
if (serialId.HasValue)
|
|
{
|
|
if (GameEntry.UI.HasUIForm(serialId.Value))
|
|
{
|
|
await GameEntry.UI.CloseUIFormAsync(serialId.Value, userData, timeout);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (form != null)
|
|
{
|
|
CloseLoadedFormDirect(form);
|
|
}
|
|
}
|
|
|
|
public abstract UniTask OpenUIAsync(object userData = null, float timeout = 30f);
|
|
|
|
public virtual UniTask CloseUIAsync(object userData = null, float timeout = 30f)
|
|
{
|
|
return CloseFormAsync(userData, timeout);
|
|
}
|
|
|
|
public abstract void BindUseCase(IUIUseCase useCase);
|
|
}
|
|
}
|