using Cysharp.Threading.Tasks; using SepCore.Definition; using UnityGameFramework.Runtime; using SepCore.AsyncTask; namespace SepCore.UI { public abstract class UIControllerBase : IUIFormController 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 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); } }