2025-08-20 02:24:48 +08:00

401 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 文件位置: Assets/Scripts/TH1_UI/Controller/Base/ViewController.cs
// (请确保命名空间和你的项目一致)
using System;
using System.Collections.Generic;
using TH1_UI;
using TH1_UI.Core;
using TH1_UI.View.Base;
using UnityEngine;
// 这是你原有的代码,为了完整性我把它折叠起来了,无需修改
#region Unchanged Interfaces and Usings
namespace TH1_UI.Controller.Base
{
public interface IViewControllerInterface
{
ViewDestroyDomain Domain { get; }
ViewLevelValue ViewLevel { get; }
ViewDepthProperty DepthProperty { get; }
ViewOpenProperty OpenProperty { get; }
ViewCloseProperty CloseProperty { get; }
ViewLoadProperty LoadProperty { get; }
string Name { get; }
int Depth { get; set; }
void Start(string subFolderPath, string resourceName, ViewDestroyDomain domain);
bool Open();
bool IsShow();
bool OpenWithParam(string param);
bool Close();
void Destroy();
}
#endregion
public class ViewController<T> : IViewControllerInterface where T : View.Base.View
{
// ... (这里到 _TryOpen 之前的所有代码都保持原样,无需改动) ...
public ViewDestroyDomain Domain => _domain;
public ViewDepthProperty DepthProperty => _depthProperty;
public ViewCloseProperty CloseProperty { get; } = new ViewCloseProperty();
public ViewOpenProperty OpenProperty { get; } = new ViewOpenProperty();
public ViewLoadProperty LoadProperty => _loadProperty;
protected ViewHierarchyProperty HierarchyProperty { get; } = new ViewHierarchyProperty();
protected ViewCameraProperty CameraProperty { get; } = new ViewCameraProperty();
protected ViewMaskProperty MaskProperty { get; } = new ViewMaskProperty();
public ViewLevelValue ViewLevel => HierarchyProperty.ViewLevel;
public string Name => _loadProperty.ControllerName;
public int Depth
{
get => _depthProperty.Depth;
set
{
if (IsShow())
{
_script.SetSortingOrder(value);
}
}
}
public T WindowScript => _script;
public GameObject WindowObj => _windowObj;
protected void AddLoadAtlas(string name)
{
UIResourceController.Instance.AddAtlasHolder(name, LoadProperty.ControllerName);
if (!_atlasLoadList.Contains(name))
{
_atlasLoadList.Add(name);
}
}
public virtual void Start(string subFolderPath, string resourceName, ViewDestroyDomain domain)
{
_domain = domain;
LoadProperty.SubFolderPath = subFolderPath;
LoadProperty.ResourceName = resourceName;
LoadProperty.ControllerName = this.GetType().Name;
DepthProperty.Start(this);
HierarchyProperty.Start(this);
CameraProperty.ThisController = this;
}
public virtual bool Open()
{
_atlasPreloadingValue.Clear();
if (EnableOpen())
{
_TryOpen();
return true;
}
else
{
return false;
}
}
public virtual bool OpenWithParam(string param)
{
return Open();
}
protected virtual bool EnableOpen()
{
return true;
}
bool _TryOpen()
{
if (IsShow())
{
UpdateView();
return false;
}
bool preLoadWait = _PreLoad();
if (preLoadWait)
{
_atlasPreloadingValue.Add("PreLoad", 30, true);
}
if (WindowObj == null)
{
// ✅ 核心修改 #1: 使用新的 GetWindow 方法签名
// 现在的 GetWindow 只负责查找Key 使用 ResourceName
GameObject window = UIResourceController.Instance.GetWindow(LoadProperty.ResourceName);
if (window == null)
{
// 如果找不到,就启动我们改造后的 ViewLoadProperty 去加载
if (LoadProperty.LoadState == LoadWindowState.NONE)
{
LoadProperty.Attach(_loadViewCallback, _OnViewLoadedCallback);
LoadProperty.Start();
}
}
else
{
// 如果找到了,说明是之前加载过的,直接开始后续流程
LoadProperty.Invoke();
_OnWindowLoadNotify(window);
_OnViewStart();
}
}
else
{
_OnViewStart();
}
return true;
}
protected virtual bool _PreLoad()
{
_PreLoadSubViewController();
return UIResourceController.Instance.LoadAtlasList(_atlasLoadList, _OnCompletePreLoad);
}
void _OnCompletePreLoad()
{
if (_atlasPreloadingValue.Has("PreLoad"))
{
_atlasPreloadingValue.Del("PreLoad");
_OnViewStart();
}
}
void _OnViewLoadedCallback(UInt32 eveID)
{
// ✅ 核心修改 #2: 在异步(现在是同步)回调中,同样使用新的 GetWindow 方法
GameObject window = UIResourceController.Instance.GetWindow(LoadProperty.ResourceName);
_OnWindowLoadNotify(window);
_OnViewStart();
}
void _OnWindowLoadNotify(System.Object obj)
{
_windowObj = obj as GameObject;
if (_windowObj == null)
{
// 为了兼容性暂时注释掉需要ViDebuger的代码
// ViDebuger.Error("Window GameObject is NULL! [res: " + LoadProperty.ResourceName + "]");
Debug.LogError("Window GameObject is NULL! [res: " + LoadProperty.ResourceName + "]");
return;
}
UIWindowProperty propertyScript = _windowObj?.GetComponentInChildren<UIWindowProperty>();
if (propertyScript == null)
{
// ViDebuger.Error(WindowObj.name + " Script is null, Then Initializtion error!");
Debug.LogError(WindowObj.name + " Script is null, Then Initializtion error!");
}
_script = _windowObj?.GetComponent<T>();
if (_script == null)
{
_script = _windowObj?.AddComponent<T>();
}
_script?.Initialize(propertyScript);
OnLoaded();
_LoadSubViewController(_windowObj);
}
void _OnViewStart()
{
if (WindowObj != null && WindowScript != null && !_atlasPreloadingValue.Value)
{
_OnOpenWindowNotify(WindowObj);
}
}
void _OnOpenWindowNotify(System.Object obj)
{
_TrueOpen();
}
void _TrueOpen()
{
if (_script != null)
{
_script.SetEnableClick(MaskProperty.EnableClick);
_script.Show();
}
DepthProperty.Open();
RegisterEventCallback();
OpenProperty.Execute();
HierarchyProperty.Open();
CameraProperty.Open();
OnOpen();
_OpenSubViewController();
OnOpenSub();
}
public virtual bool Close()
{
_loadViewCallback.End();
_atlasPreloadingValue.Clear();
if (IsShow())
{
_ReleasePreLoad();
_TrueClose();
return true;
}
else
{
_atlasLoadList.Clear();
if (LoadProperty.LoadState == LoadWindowState.LOADING)
{
_loadViewCallback.End();
LoadProperty.LoadState = LoadWindowState.NONE;
}
else if (LoadProperty.LoadState == LoadWindowState.LOADED)
{
_loadViewCallback.End();
}
return true;
}
}
void _TrueClose()
{
UnregisterEventCallback();
OnClose();
_CloseSubViewController();
DepthProperty.Close();
CameraProperty.Close();
if (_script != null)
{
_script.Hide();
}
HierarchyProperty.Close();
CloseProperty.Execute();
}
protected bool _ReleasePreLoad()
{
for (int iter = 0; iter < _atlasLoadList.Count; ++iter)
{
string iterAtlas = _atlasLoadList[iter];
if (UIResourceController.Instance.DelAtlasHolder(iterAtlas, LoadProperty.ControllerName))
{
UIResourceController.Instance.ReleaseAtlas(iterAtlas);
}
}
_atlasLoadList.Clear();
return true;
}
public virtual void Destroy()
{
Close();
_ReleasePreLoad();
_DestroySubViewController();
// ✅ 核心修改 #3: 删除窗口时使用的key必须和获取/添加窗口时一致,即 ResourceName
UIResourceController.Instance.DelWindow(LoadProperty.ResourceName);
if (_windowObj != null)
{
// GameObject.Destroy() 已经是 UIResourceController.DelWindow 的一部分了
// 所以这里不需要再 Destroy只需要将引用置空
_windowObj = null;
}
_script = null;
LoadProperty.End();
}
public virtual bool IsShow()
{
if (_script == null)
{
return false;
}
return _script.IsShow();
}
// ... (这里往后的代码,包括子界面管理等,都保持原样,无需改动) ...
protected virtual void OnLoaded() { }
protected virtual void OnOpen() { }
protected virtual void OnOpenSub() { }
protected virtual void RegisterEventCallback() { }
protected virtual void UnregisterEventCallback() { }
protected virtual void OnClose() { }
protected virtual void UpdateView() { }
T _script;
ViewDestroyDomain _domain;
GameObject _windowObj;
ViAsynCallback _loadViewCallback = new ViAsynCallback(); // 这是一个未知类型,但我们无需修改
ViewDepthProperty _depthProperty = new ViewDepthProperty();
ViewLoadProperty _loadProperty = new ViewLoadProperty();
ViPriorityValue<bool> _atlasPreloadingValue = new ViPriorityValue<bool>(false); // 这是一个未知类型,但我们无需修改
List<string> _atlasLoadList = new List<string>();
Dictionary<string, ViewControllerSubInterface> _subViewDict = new Dictionary<string, ViewControllerSubInterface>();
protected T1 AddSubViewController<T1>(string childPath, string ex = null) where T1 : ViewControllerSubInterface, new()
{
var sub = new T1();
sub.Start(childPath, this);
_subViewDict.Add(typeof(T1).Name + ex, sub);
return sub;
}
public T1 GetSubViewController<T1>(string ex = null) where T1 : ViewControllerSubInterface, new()
{
_subViewDict.TryGetValue(typeof(T1).Name + ex, out var subViewController);
return (T1) subViewController;
}
void _PreLoadSubViewController()
{
foreach (var kv in _subViewDict)
{
var subViewController = kv.Value;
subViewController.PreLoad();
var loadAtlas = subViewController.GetLoadAtlas();
foreach (var atlas in loadAtlas)
{
AddLoadAtlas(atlas);
}
}
}
void _LoadSubViewController(GameObject windowObj)
{
foreach (var kv in _subViewDict)
{
kv.Value.OnWindowLoadNotify(windowObj);
}
}
void _OpenSubViewController()
{
foreach (var kv in _subViewDict)
{
if (kv.Value.DefaultOpen)
{
kv.Value.Open();
}
}
}
void _CloseSubViewController()
{
foreach (var kv in _subViewDict)
{
kv.Value.Close();
}
}
void _DestroySubViewController()
{
foreach (var kv in _subViewDict)
{
kv.Value.Destroy();
}
}
protected void CloseAllSubView()
{
foreach (var kv in _subViewDict)
{
kv.Value.Close();
}
}
}
}