继续重构调整(UI)

- 引入 UniTask 和异步版本的 UIModule
- 调整 Runtime/UIBase 和 Presentation 下的脚本命名空间到 SepCore.UI
- 将原来的 5 层 UI 迁移到异步实现
- 规范各层的 UI 脚本命名
This commit is contained in:
SepComet
2026-06-03 09:58:37 +08:00
parent 6b8a6a8789
commit 7bba8bbb80
552 changed files with 83648 additions and 2726 deletions
@@ -0,0 +1,9 @@
namespace SepCore.UI
{
public class SelectRoleContext : UIContext
{
public RoleItemContext[] RoleItemContexts;
public RolePropertyAreaContext RolePropertyAreaContext;
public int[] RoleIds;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6c34d5aa87925ee41b70887958e7611c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,207 @@
using Cysharp.Threading.Tasks;
using SepCore.Event;
using SepCore.Definition;
using GameFramework.Event;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace SepCore.UI
{
public class SelectRoleController : UIControllerBase<SelectRoleContext, SelectRoleForm>
{
private SelectRoleUseCase _useCase;
protected override UIFormType UIFormType => UIFormType.SelectRoleForm;
protected override void RefreshUI(SelectRoleForm form, SelectRoleContext context)
{
form.RefreshUI(context);
}
protected override void SubscribeCustomEvents()
{
GameEntry.Event.Subscribe(MenuSelectRoleReturnEventArgs.EventId, OnSelectRoleReturn);
GameEntry.Event.Subscribe(SelectRoleHoverEventArgs.EventId, OnSelectRoleHover);
GameEntry.Event.Subscribe(SelectRoleConfirmEventArgs.EventId, OnMenuSelectRoleConfirm);
}
protected override void UnsubscribeCustomEvents()
{
GameEntry.Event.Unsubscribe(MenuSelectRoleReturnEventArgs.EventId, OnSelectRoleReturn);
GameEntry.Event.Unsubscribe(SelectRoleHoverEventArgs.EventId, OnSelectRoleHover);
GameEntry.Event.Unsubscribe(SelectRoleConfirmEventArgs.EventId, OnMenuSelectRoleConfirm);
}
private static SelectRoleContext BuildContext(SelectRoleRawData rawData)
{
if (rawData == null)
{
Log.Error("SelectRoleFormController.BuildContext() rawData is null.");
return null;
}
int count = rawData.RoleIds?.Length ?? 0;
RoleItemContext[] roleItems = new RoleItemContext[count];
for (int i = 0; i < count; i++)
{
string iconName = rawData.RoleIconNames != null && i < rawData.RoleIconNames.Length
? rawData.RoleIconNames[i]
: null;
roleItems[i] = new RoleItemContext
{
RoleId = rawData.RoleIds[i],
IconName = iconName
};
}
RolePropertyAreaContext propertyContext = null;
if (rawData.SelectedRoleId >= 0)
{
propertyContext = new RolePropertyAreaContext
{
RoleName = rawData.SelectedRoleName,
InitialPropertyText = rawData.SelectedRoleInitialPropertyText
};
}
return new SelectRoleContext
{
RoleItemContexts = roleItems,
RolePropertyAreaContext = propertyContext,
RoleIds = rawData.RoleIds
};
}
public override async UniTask<int?> OpenUIAsync(object userData = null, float timeout = 30f)
{
if (userData is SelectRoleRawData rawData)
{
return await OpenUIAsync(rawData, timeout);
}
if (userData != null)
{
Log.Warning("SelectRoleController.OpenUIAsync() userData type is invalid.");
return null;
}
if (_useCase == null)
{
Log.Error("SelectRoleController.OpenUIAsync() useCase is null.");
return null;
}
SelectRoleRawData initialRawData = _useCase.CreateModel();
return await OpenUIAsync(initialRawData, timeout);
}
public async UniTask<int?> OpenUIAsync(SelectRoleRawData rawData, float timeout = 30f)
{
SelectRoleContext context = BuildContext(rawData);
return await OpenFormAsync(context, timeout);
}
public override void BindUseCase(IUIUseCase useCase)
{
if (useCase is not SelectRoleUseCase selectRoleUseCase)
{
Log.Error("SelectRoleUseCase.BindUseCase() useCase is invalid.");
return;
}
_useCase = selectRoleUseCase;
}
public void UpdateShowRole(RolePropertyAreaContext rolePropertyAreaContext)
{
if (Context == null)
{
Log.Error("SelectRoleFormController.UpdateShowRole() Context is null.");
return;
}
Context.RolePropertyAreaContext = rolePropertyAreaContext;
Form?.UpdateShowRole(rolePropertyAreaContext);
}
private bool IsCurrentFormEventSender(object sender)
{
if (sender is SelectRoleForm selectRoleForm)
{
return selectRoleForm == Form;
}
if (sender is Component component && Form != null)
{
return component.transform.IsChildOf(Form.transform);
}
return false;
}
private void OnSelectRoleReturn(object sender, GameEventArgs e)
{
if (sender is not SelectRoleForm selectRoleForm || selectRoleForm != Form)
{
return;
}
if (e is not MenuSelectRoleReturnEventArgs)
{
return;
}
CloseUIAsync().Forget();
}
private void OnSelectRoleHover(object sender, GameEventArgs e)
{
if (e is not SelectRoleHoverEventArgs args)
{
return;
}
if (!IsCurrentFormEventSender(sender))
{
return;
}
OnSelectRoleHoverAsync(args).Forget();
}
private async UniTaskVoid OnSelectRoleHoverAsync(SelectRoleHoverEventArgs args)
{
if (_useCase == null)
{
Log.Error("SelectRoleFormController.OnMenuSelectRoleSelected() useCase is null.");
return;
}
SelectRoleRawData rawData = _useCase.SelectRole(args.RoleId);
await OpenUIAsync(rawData);
}
private void OnMenuSelectRoleConfirm(object sender, GameEventArgs e)
{
if (e is not SelectRoleConfirmEventArgs)
{
return;
}
if (!IsCurrentFormEventSender(sender))
{
return;
}
if (_useCase == null)
{
Log.Error("SelectRoleFormController.OnMenuSelectRoleConfirm() useCase is null.");
return;
}
_useCase.ConfirmSelectedRole();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ff46cd6b508b0304a801223cbae79419
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,100 @@
using System;
using SepCore.Event;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace SepCore.UI
{
public class SelectRoleForm : UGuiForm
{
[SerializeField] private GameObject _randomRoleCard = null;
[SerializeField] private GameObject _roleCard = null;
[SerializeField] private RolePropertyArea _propertyArea = null;
private SelectRoleContext _context = null;
private RoleItem[] _roleItems = null;
public void RefreshUI(SelectRoleContext context)
{
_context = context;
int itemIndex = 1, roleIndex = 0;
while (itemIndex < _roleItems.Length)
{
if (roleIndex < _context.RoleItemContexts.Length)
{
_roleItems[itemIndex].OnInit(_context.RoleItemContexts[roleIndex]);
_roleItems[itemIndex].gameObject.SetActive(true);
}
else
{
_roleItems[itemIndex].gameObject.SetActive(false);
_roleItems[itemIndex].OnReset();
}
itemIndex++;
roleIndex++;
}
UpdateShowRole(_context.RolePropertyAreaContext);
}
#region FSM
protected override void OnInit(object userData)
{
base.OnInit(userData);
_roleItems = this.transform.GetComponentsInChildren<RoleItem>();
}
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
if (userData is SelectRoleContext context)
{
RefreshUI(context);
return;
}
Log.Warning("SelectRoleForm requires SelectRoleFormContext as userData.");
}
protected override void OnClose(bool isShutdown, object userData)
{
base.OnClose(isShutdown, userData);
_context = null;
foreach (var item in _roleItems)
{
item.OnReset();
}
}
#endregion
public void UpdateShowRole(RolePropertyAreaContext propertyAreaContext)
{
if (propertyAreaContext == null)
{
_randomRoleCard.SetActive(true);
_roleCard.SetActive(false);
_propertyArea.OnReset();
}
else
{
_randomRoleCard.SetActive(false);
_propertyArea.OnInit(propertyAreaContext);
_roleCard.SetActive(true);
}
}
public void OnReturnButtonClick()
{
GameEntry.Event.Fire(this, MenuSelectRoleReturnEventArgs.Create());
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 665710bc9ed5c5547a40f0cc2d92ba2e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: