继续重构调整(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
@@ -1,16 +1,9 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using StarForce;
using StarForce;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace UI
namespace SepCore.UI
{
public class AboutForm : UGuiForm
{
@@ -1,4 +1,4 @@
namespace UI
namespace SepCore.UI
{
public class RoleItemContext : UIContext
{
@@ -1,4 +1,4 @@
namespace UI
namespace SepCore.UI
{
public class RolePropertyAreaContext : UIContext
{
@@ -0,0 +1,45 @@
using SepCore.UI;
namespace SepCore.UI
{
/// <summary>
/// 对话框显示数据。
/// </summary>
public class DialogContext : UIContext
{
/// <summary>
/// 模式,即按钮数量。取值 1、2、3。
/// </summary>
public int Mode { get; set; }
/// <summary>
/// 标题。
/// </summary>
public string Title { get; set; }
/// <summary>
/// 消息内容。
/// </summary>
public string Message { get; set; }
/// <summary>
/// 弹出窗口时是否暂停游戏。
/// </summary>
public bool PauseGame { get; set; }
/// <summary>
/// 确认按钮文本。
/// </summary>
public string ConfirmText { get; set; }
/// <summary>
/// 取消按钮文本。
/// </summary>
public string CancelText { get; set; }
/// <summary>
/// 中立按钮文本。
/// </summary>
public string OtherText { get; set; }
}
}
@@ -1,7 +1,8 @@
fileFormatVersion: 2
guid: e9602a461df53c048af85df015fa8cb7
guid: 8fb06a34d7fb37146a4b9e2f8138a724
timeCreated: 1528026160
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
@@ -0,0 +1,137 @@
using System;
using Cysharp.Threading.Tasks;
using GameFramework;
using GameFramework.Event;
using SepCore.Definition;
using SepCore.Event;
using UnityGameFramework.Runtime;
namespace SepCore.UI
{
public class DialogController : UIControllerBase<DialogContext, DialogForm>
{
private GameFrameworkAction<object> _onClickConfirmGFAction;
private GameFrameworkAction<object> _onClickCancelGFAction;
private GameFrameworkAction<object> _onClickOtherGFAction;
private object _currentUserData;
protected override UIFormType UIFormType => UIFormType.DialogForm;
protected override void RefreshUI(DialogForm form, DialogContext context)
{
form.RefreshUI(context);
}
protected virtual DialogContext BuildContext(DialogRawData rawData)
{
if (rawData == null)
{
return null;
}
return new DialogContext
{
Mode = rawData.Mode,
Title = rawData.Title,
Message = rawData.Message,
PauseGame = rawData.PauseGame,
ConfirmText = rawData.ConfirmText,
CancelText = rawData.CancelText,
OtherText = rawData.OtherText,
};
}
public override async UniTask<int?> OpenUIAsync(object userData = null, float timeout = 30f)
{
if (userData is not DialogRawData rawData)
{
if (userData != null)
{
Log.Warning("DialogController.OpenUIAsync() userData type is invalid.");
}
else
{
Log.Warning("DialogController.OpenUIAsync() rawData is required.");
}
return null;
}
DialogContext context = BuildContext(rawData);
if (context == null)
{
Log.Warning("DialogController.OpenUIAsync() rawData is invalid.");
return null;
}
_onClickConfirmGFAction = rawData.OnClickConfirm;
_onClickCancelGFAction = rawData.OnClickCancel;
_onClickOtherGFAction = rawData.OnClickOther;
_currentUserData = rawData.UserData;
return await OpenFormAsync(context, timeout);
}
public override async UniTask CloseUIAsync(object userData = null, float timeout = 30f)
{
ClearCallbacks();
await CloseFormAsync(userData, timeout);
}
public override void BindUseCase(IUIUseCase useCase)
{
if (useCase != null)
{
Log.Warning("DialogController does not use a use case.");
}
}
protected override void SubscribeCustomEvents()
{
GameEntry.Event.Subscribe(DialogEventArgs.EventId, HandleDialogEventArgs);
}
protected override void UnsubscribeCustomEvents()
{
GameEntry.Event.Unsubscribe(DialogEventArgs.EventId, HandleDialogEventArgs);
}
private void HandleDialogEventArgs(object sender, GameEventArgs e)
{
if (e is not DialogEventArgs args) return;
var callback = args.ButtonId switch
{
1 => _onClickConfirmGFAction,
2 => _onClickCancelGFAction,
3 => _onClickOtherGFAction,
_ => null
};
object userData = _currentUserData;
CloseAndInvokeAsync(callback, userData).Forget();
}
private void ClearCallbacks()
{
_onClickConfirmGFAction = null;
_onClickCancelGFAction = null;
_onClickOtherGFAction = null;
_currentUserData = null;
}
private async UniTaskVoid CloseAndInvokeAsync(GameFrameworkAction<object> callback, object userData)
{
try
{
await CloseUIAsync();
}
catch (Exception exception)
{
Log.Warning("DialogController.CloseUIAsync() failed: {0}", exception.Message);
}
finally
{
callback?.Invoke(userData);
}
}
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: bcea24781fc934c42a5aac696d86f98d
guid: f9a41ea68676c324091e71f3531a9da2
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -0,0 +1,129 @@
using TMPro;
using UnityEngine;
using UnityGameFramework.Runtime;
using SepCore.Event;
namespace SepCore.UI
{
public class DialogForm : UGuiForm
{
[SerializeField] private TMP_Text _titleText = null;
[SerializeField] private TMP_Text _messageText = null;
[SerializeField] private GameObject[] _modeObjects = null;
[SerializeField] private TMP_Text[] _confirmTexts = null;
[SerializeField] private TMP_Text[] _cancelTexts = null;
[SerializeField] private TMP_Text[] _otherTexts = null;
private int _dialogMode = 1;
private bool _pauseGame = false;
public void OnConfirmButtonClick()
{
GameEntry.Event.FireNow(this, DialogEventArgs.Create(1, null));
}
public void OnCancelButtonClick()
{
GameEntry.Event.FireNow(this, DialogEventArgs.Create(2, null));
}
public void OnOtherButtonClick()
{
GameEntry.Event.FireNow(this, DialogEventArgs.Create(3, null));
}
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
if (userData is not DialogContext context)
{
Log.Warning("DialogContext is invalid.");
return;
}
RefreshUI(context);
}
public void RefreshUI(DialogContext context)
{
if (context == null)
{
Log.Warning("DialogContext is invalid.");
return;
}
_dialogMode = context.Mode;
RefreshDialogMode();
_titleText.text = context.Title;
_messageText.text = context.Message;
_pauseGame = context.PauseGame;
RefreshPauseGame();
RefreshConfirmText(context.ConfirmText);
RefreshCancelText(context.CancelText);
RefreshOtherText(context.OtherText);
}
protected override void OnClose(bool isShutdown, object userData)
{
if (_pauseGame)
{
GameEntry.Base.ResumeGame();
}
_dialogMode = 1;
_titleText.text = string.Empty;
_messageText.text = string.Empty;
_pauseGame = false;
RefreshConfirmText(string.Empty);
RefreshCancelText(string.Empty);
RefreshOtherText(string.Empty);
base.OnClose(isShutdown, userData);
}
private void RefreshDialogMode()
{
for (int i = 1; i <= _modeObjects.Length; i++)
{
_modeObjects[i - 1].SetActive(i == _dialogMode);
}
}
private void RefreshPauseGame()
{
if (_pauseGame)
{
GameEntry.Base.PauseGame();
}
}
private void RefreshConfirmText(string confirmText)
{
foreach (var text in _confirmTexts)
{
text.text = confirmText;
}
}
private void RefreshCancelText(string cancelText)
{
foreach (var text in _cancelTexts)
{
text.text = cancelText;
}
}
private void RefreshOtherText(string otherText)
{
foreach (var text in _otherTexts)
{
text.text = otherText;
}
}
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c04f3be6bab0c7748bc236f9023e47f9
guid: e75b6daf7a6651845bdbc6cf9dcaa400
timeCreated: 1528026160
licenseType: Pro
MonoImporter:
@@ -1,232 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using TMPro;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace UI
{
public class DialogForm : UGuiForm
{
[SerializeField] private TMP_Text _titleText = null;
[SerializeField] private TMP_Text _messageText = null;
[SerializeField] private GameObject[] _modeObjects = null;
[SerializeField] private TMP_Text[] _confirmTexts = null;
[SerializeField] private TMP_Text[] _cancelTexts = null;
[SerializeField] private TMP_Text[] _otherTexts = null;
private int _dialogMode = 1;
private bool _pauseGame = false;
private object _userData = null;
private GameFrameworkAction<object> _onClickConfirmGFAction = null;
private GameFrameworkAction<object> _onClickCancelGFAction = null;
private GameFrameworkAction<object> _onClickOtherGFAction = null;
private DialogFormContext _context = null;
public int DialogMode => _dialogMode;
public bool PauseGame => _pauseGame;
public object UserData => _userData;
public void OnConfirmButtonClick()
{
Close();
if (_onClickConfirmGFAction != null)
{
_onClickConfirmGFAction(_userData);
}
}
public void OnCancelButtonClick()
{
Close();
if (_onClickCancelGFAction != null)
{
_onClickCancelGFAction(_userData);
}
}
public void OnOtherButtonClick()
{
Close();
if (_onClickOtherGFAction != null)
{
_onClickOtherGFAction(_userData);
}
}
#if UNITY_2017_3_OR_NEWER
protected override void OnOpen(object userData)
#else
protected internal override void OnOpen(object userData)
#endif
{
base.OnOpen(userData);
if (userData is DialogFormContext context)
{
RefreshUI(context);
return;
}
if (userData is DialogFormRawData dialogParams)
{
RefreshUI(BuildContext(dialogParams));
return;
}
Log.Warning("DialogForm requires DialogFormContext or DialogParams as userData.");
}
#if UNITY_2017_3_OR_NEWER
protected override void OnClose(bool isShutdown, object userData)
#else
protected internal override void OnClose(bool isShutdown, object userData)
#endif
{
if (_pauseGame)
{
GameEntry.Base.ResumeGame();
}
_dialogMode = 1;
_titleText.text = string.Empty;
_messageText.text = string.Empty;
_pauseGame = false;
_userData = null;
_context = null;
RefreshConfirmText(string.Empty);
_onClickConfirmGFAction = null;
RefreshCancelText(string.Empty);
_onClickCancelGFAction = null;
RefreshOtherText(string.Empty);
_onClickOtherGFAction = null;
base.OnClose(isShutdown, userData);
}
public void RefreshUI(DialogFormContext context)
{
if (context == null)
{
Log.Warning("DialogForm context is invalid.");
return;
}
_context = context;
_dialogMode = context.Mode;
RefreshDialogMode();
_titleText.text = context.Title;
_messageText.text = context.Message;
_pauseGame = context.PauseGame;
RefreshPauseGame();
_userData = context.UserData;
RefreshConfirmText(context.ConfirmText);
_onClickConfirmGFAction = context.OnClickConfirm;
RefreshCancelText(context.CancelText);
_onClickCancelGFAction = context.OnClickCancel;
RefreshOtherText(context.OtherText);
_onClickOtherGFAction = context.OnClickOther;
}
private static DialogFormContext BuildContext(DialogFormRawData rawData)
{
if (rawData == null)
{
return null;
}
return new DialogFormContext
{
Mode = rawData.Mode,
Title = rawData.Title,
Message = rawData.Message,
PauseGame = rawData.PauseGame,
ConfirmText = rawData.ConfirmText,
OnClickConfirm = rawData.OnClickConfirm,
CancelText = rawData.CancelText,
OnClickCancel = rawData.OnClickCancel,
OtherText = rawData.OtherText,
OnClickOther = rawData.OnClickOther,
UserData = rawData.UserData
};
}
private void RefreshDialogMode()
{
for (int i = 1; i <= _modeObjects.Length; i++)
{
_modeObjects[i - 1].SetActive(i == _dialogMode);
}
}
private void RefreshPauseGame()
{
if (_pauseGame)
{
GameEntry.Base.PauseGame();
}
}
private void RefreshConfirmText(string confirmText)
{
if (string.IsNullOrEmpty(confirmText))
{
confirmText = GameEntry.Localization.GetString("Dialog.ConfirmButton");
}
for (int i = 0; i < _confirmTexts.Length; i++)
{
_confirmTexts[i].text = confirmText;
}
}
private void RefreshCancelText(string cancelText)
{
if (string.IsNullOrEmpty(cancelText))
{
cancelText = GameEntry.Localization.GetString("Dialog.CancelButton");
}
for (int i = 0; i < _cancelTexts.Length; i++)
{
_cancelTexts[i].text = cancelText;
}
}
private void RefreshOtherText(string otherText)
{
if (string.IsNullOrEmpty(otherText))
{
otherText = GameEntry.Localization.GetString("Dialog.OtherButton");
}
for (int i = 0; i < _otherTexts.Length; i++)
{
_otherTexts[i].text = otherText;
}
}
}
}
@@ -1,19 +0,0 @@
using GameFramework;
namespace UI
{
public class DialogFormContext : UIContext
{
public int Mode;
public string Title;
public string Message;
public bool PauseGame;
public string ConfirmText;
public GameFrameworkAction<object> OnClickConfirm;
public string CancelText;
public GameFrameworkAction<object> OnClickCancel;
public string OtherText;
public GameFrameworkAction<object> OnClickOther;
public object UserData;
}
}
@@ -1,78 +0,0 @@
using SepCore.Definition;
using UnityGameFramework.Runtime;
namespace UI
{
public class DialogFormController : UIFormControllerCommonBase<DialogFormContext, DialogForm>
{
protected override UIFormType UIFormTypeId => UIFormType.DialogForm;
protected override void RefreshUI(DialogForm form, DialogFormContext context)
{
form.RefreshUI(context);
}
protected override void CloseLoadedFormDirect(DialogForm form)
{
GameEntry.UI.CloseUIForm(form);
}
private static DialogFormContext BuildContext(DialogFormRawData rawData)
{
if (rawData == null)
{
return null;
}
return new DialogFormContext
{
Mode = rawData.Mode,
Title = rawData.Title,
Message = rawData.Message,
PauseGame = rawData.PauseGame,
ConfirmText = rawData.ConfirmText,
OnClickConfirm = rawData.OnClickConfirm,
CancelText = rawData.CancelText,
OnClickCancel = rawData.OnClickCancel,
OtherText = rawData.OtherText,
OnClickOther = rawData.OnClickOther,
UserData = rawData.UserData
};
}
public int? OpenUI(DialogFormRawData rawData)
{
DialogFormContext context = BuildContext(rawData);
return OpenUIInternal(context);
}
public override int? OpenUI(object userData = null)
{
if (userData is DialogFormContext context)
{
return OpenUIInternal(context);
}
if (userData is DialogFormRawData rawData)
{
return OpenUI(rawData);
}
if (userData != null)
{
Log.Warning("DialogFormController.OpenUI() userData type is invalid.");
return null;
}
return OpenUIInternal(Context);
}
public override void BindUseCase(IUIUseCase useCase)
{
if (useCase != null)
{
Log.Warning("DialogFormController does not use a use case.");
}
}
}
}
@@ -2,7 +2,7 @@ using SepCore.Definition;
using UnityEngine;
using UnityEngine.UI;
namespace UI
namespace SepCore.UI
{
public class IconArea : MonoBehaviour
{
@@ -2,7 +2,7 @@ using SepCore.Event;
using UnityEngine;
using UnityEngine.UI;
namespace UI
namespace SepCore.UI
{
public class RoleItem : MonoBehaviour
{
@@ -29,12 +29,12 @@ namespace UI
public void UpdateShowRole()
{
int roleId = _context?.RoleId ?? -1;
GameEntry.Event.Fire(this, MenuSelectRoleSelectedEventArgs.Create(roleId));
GameEntry.Event.Fire(this, SelectRoleHoverEventArgs.Create(roleId));
}
public void OnConfirmRoleClick()
{
GameEntry.Event.Fire(this, MenuSelectRoleConfirmEventArgs.Create());
GameEntry.Event.Fire(this, SelectRoleConfirmEventArgs.Create());
}
}
}
@@ -2,7 +2,7 @@ using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace UI
namespace SepCore.UI
{
public class RolePropertyArea : MonoBehaviour
{
@@ -1,7 +1,7 @@
using UnityEngine;
using UnityEngine.UI;
namespace UI
namespace SepCore.UI
{
public class UpdateResourceForm : MonoBehaviour
{