177 lines
5.8 KiB
C#
177 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Cysharp.Threading.Tasks;
|
|
using SepCore.Definition;
|
|
using SepCore.UI;
|
|
using UnityEngine;
|
|
using UnityGameFramework.Runtime;
|
|
|
|
namespace SepCore.CustomComponent
|
|
{
|
|
public class UIRouterComponent : GameFrameworkComponent
|
|
{
|
|
[Serializable]
|
|
public class ControllerBinding
|
|
{
|
|
[SerializeField] private UIFormType _uiFormType = UIFormType.Undefined;
|
|
[SerializeField] private string _controllerTypeName;
|
|
|
|
public UIFormType UIFormType => _uiFormType;
|
|
|
|
public string ControllerTypeName => _controllerTypeName;
|
|
}
|
|
|
|
[SerializeField] private List<ControllerBinding> _controllerBindings = new();
|
|
|
|
private readonly Dictionary<UIFormType, IUIFormController> _routeControllers = new();
|
|
private readonly Dictionary<UIFormType, Func<IUIFormController>> _controllerFactories = new();
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
RegisterSerializedBindings();
|
|
}
|
|
|
|
public void RegisterController(UIFormType uiFormType, Func<IUIFormController> controllerFactory)
|
|
{
|
|
if (controllerFactory == null)
|
|
{
|
|
Log.Error("UIRouterComponent.RegisterController() controllerFactory is invalid.");
|
|
return;
|
|
}
|
|
|
|
if (_routeControllers.TryGetValue(uiFormType, out IUIFormController controller))
|
|
{
|
|
controller.CloseUIAsync().Forget();
|
|
_routeControllers.Remove(uiFormType);
|
|
}
|
|
|
|
_controllerFactories[uiFormType] = controllerFactory;
|
|
}
|
|
|
|
public void RegisterController<TController>(UIFormType uiFormType)
|
|
where TController : IUIFormController, new()
|
|
{
|
|
RegisterController(uiFormType, () => new TController());
|
|
}
|
|
|
|
public void BindUIUseCase(UIFormType uiFormType, IUIUseCase useCase)
|
|
{
|
|
IUIFormController controller = GetOrCreateController(uiFormType);
|
|
if (controller == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
controller.BindUseCase(useCase);
|
|
}
|
|
|
|
public UniTask<int?> OpenUIAsync(UIFormType uiFormType, object userData = null, float timeout = 30f)
|
|
{
|
|
IUIFormController controller = GetOrCreateController(uiFormType);
|
|
if (controller == null)
|
|
{
|
|
return UniTask.FromResult<int?>(null);
|
|
}
|
|
|
|
return controller.OpenUIAsync(userData, timeout);
|
|
}
|
|
|
|
public UniTask CloseUIAsync(UIFormType uiFormType, object userData = null, float timeout = 30f)
|
|
{
|
|
IUIFormController controller = GetOrCreateController(uiFormType);
|
|
if (controller == null)
|
|
{
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
return controller.CloseUIAsync(userData, timeout);
|
|
}
|
|
|
|
private IUIFormController GetOrCreateController(UIFormType uiFormType)
|
|
{
|
|
if (_routeControllers.TryGetValue(uiFormType, out IUIFormController controller))
|
|
{
|
|
return controller;
|
|
}
|
|
|
|
if (!_controllerFactories.TryGetValue(uiFormType, out Func<IUIFormController> controllerFactory))
|
|
{
|
|
Log.Error("UIRouterComponent requires a controller binding for '{0}'.", uiFormType.ToString());
|
|
return null;
|
|
}
|
|
|
|
controller = controllerFactory();
|
|
if (controller == null)
|
|
{
|
|
Log.Error("UIRouterComponent controller factory for '{0}' returned null.", uiFormType.ToString());
|
|
return null;
|
|
}
|
|
|
|
_routeControllers.Add(uiFormType, controller);
|
|
return controller;
|
|
}
|
|
|
|
private void RegisterSerializedBindings()
|
|
{
|
|
if (_controllerBindings == null || _controllerBindings.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
HashSet<UIFormType> seen = new();
|
|
foreach (ControllerBinding binding in _controllerBindings)
|
|
{
|
|
if (binding == null || binding.UIFormType == UIFormType.Undefined ||
|
|
string.IsNullOrWhiteSpace(binding.ControllerTypeName))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!seen.Add(binding.UIFormType))
|
|
{
|
|
Log.Warning("UIRouter duplicate binding for '{0}', later one overrides earlier one.",
|
|
binding.UIFormType.ToString());
|
|
}
|
|
|
|
Type controllerType = Type.GetType(binding.ControllerTypeName);
|
|
if (controllerType == null)
|
|
{
|
|
Log.Warning("UIRouter binding type not found: {0}", binding.ControllerTypeName);
|
|
continue;
|
|
}
|
|
|
|
if (!typeof(IUIFormController).IsAssignableFrom(controllerType))
|
|
{
|
|
Log.Warning("UIRouter binding type '{0}' does not implement IUIFormController.",
|
|
binding.ControllerTypeName);
|
|
continue;
|
|
}
|
|
|
|
RegisterController(binding.UIFormType, () => CreateController(controllerType));
|
|
}
|
|
}
|
|
|
|
private static IUIFormController CreateController(Type controllerType)
|
|
{
|
|
object instance = Activator.CreateInstance(controllerType);
|
|
if (instance is IUIFormController controller)
|
|
{
|
|
return controller;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
foreach (KeyValuePair<UIFormType, IUIFormController> pair in _routeControllers)
|
|
{
|
|
pair.Value.CloseUIAsync().Forget();
|
|
}
|
|
|
|
_routeControllers.Clear();
|
|
}
|
|
}
|
|
}
|