using System.Collections.Generic; using GameFramework.Event; using UnityGameFramework.Runtime; namespace UI { public sealed class AIChatEntryFormController : IFormController { private AIChatEntryFormContext _entryContext; private AIChatEntryForm _entryForm; private int? _entryFormSerialId; private bool _pendingEntryRefresh; private AIChatFormController _chatFormController; private AIChatFormContext _chatContext; public AIChatEntryFormController() { GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess); GameEntry.Event.Subscribe(CloseUIFormCompleteEventArgs.EventId, OnCloseUIFormComplete); } ~AIChatEntryFormController() { GameEntry.Event.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess); GameEntry.Event.Unsubscribe(CloseUIFormCompleteEventArgs.EventId, OnCloseUIFormComplete); } public int? OpenUI(AIChatEntryFormContext context) { if (context == null) { Log.Warning("AIChatEntryFormController open failed. context is null."); return null; } context.Controller = this; _entryContext = context; SyncEntryContextState(); if (_entryForm != null) { _entryForm.RefreshUI(_entryContext); return _entryFormSerialId; } UGuiForm openedForm = GameEntry.UI.GetUIForm(UIFormId.AIChatEntryForm); if (openedForm is AIChatEntryForm existingForm) { _entryForm = existingForm; _entryFormSerialId = existingForm.UIForm.SerialId; _entryForm.RefreshUI(_entryContext); return _entryFormSerialId; } _pendingEntryRefresh = true; _entryFormSerialId = GameEntry.UI.OpenUIForm(UIFormId.AIChatEntryForm, _entryContext); return _entryFormSerialId; } public void CloseUI() { _pendingEntryRefresh = false; if (_entryFormSerialId.HasValue) { GameEntry.UI.CloseUIForm(_entryFormSerialId.Value); return; } if (_entryForm != null) { _entryForm.Close(); } } public void ToggleAIChatForm() { UGuiForm openedChatForm = GameEntry.UI.GetUIForm(UIFormId.AIChatForm); if (openedChatForm != null) { if (_chatFormController != null) { _chatFormController.CloseUI(); } else { GameEntry.UI.CloseUIForm(openedChatForm.UIForm); } RefreshEntryState(); return; } EnsureChatContext(); _chatContext.Controller = _chatFormController; _chatFormController.OpenUI(_chatContext); RefreshEntryState(); } private void EnsureChatContext() { if (_chatFormController == null) { _chatFormController = new AIChatFormController(); } if (_chatContext == null) { _chatContext = new AIChatFormContext { ClearHistoryOnOpen = false, LanguageMode = 0, Messages = new List() }; } _chatContext.Controller = _chatFormController; _chatContext.Messages ??= new List(); } private void SyncEntryContextState() { if (_entryContext == null) { return; } _entryContext.IsChatOpened = GameEntry.UI.GetUIForm(UIFormId.AIChatForm) != null; } private void RefreshEntryState() { SyncEntryContextState(); if (_entryForm == null || _entryContext == null) { return; } _entryForm.SetChatOpened(_entryContext.IsChatOpened); } private void OnOpenUIFormSuccess(object sender, GameEventArgs e) { if (!(e is OpenUIFormSuccessEventArgs args)) { return; } if (_entryFormSerialId.HasValue && args.UIForm != null && args.UIForm.SerialId == _entryFormSerialId.Value && args.UserData == _entryContext) { _entryForm = args.UIForm.Logic as AIChatEntryForm; if (_entryForm == null) { Log.Warning("AIChatEntryFormController open success but form logic is invalid."); } else if (_pendingEntryRefresh) { _entryForm.RefreshUI(_entryContext); _pendingEntryRefresh = false; } } RefreshEntryState(); } private void OnCloseUIFormComplete(object sender, GameEventArgs e) { if (!(e is CloseUIFormCompleteEventArgs args)) { return; } if (args.SerialId == _entryFormSerialId) { _entryForm = null; _entryFormSerialId = null; _pendingEntryRefresh = false; } RefreshEntryState(); } } }