Files
vampire-like/Assets/GameMain/Scripts/Runtime/UIBase/Base/UIControllerBase.cs
T
SepComet d2ce741a37 按 UI 五层规范重构 SelectRoleForm 并整理事件目录
- 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 引用
2026-06-16 17:09:20 +08:00

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