vampire-like/Assets/GameMain/Scripts/Presentation/Common/Dialog/DialogController.cs

138 lines
4.2 KiB
C#

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