增加UnLoadAsync, 调整LoadSceneAsync的命名,增加_handlingScene当前正在处理的Scene保护

增加UnLoadAsync, 调整LoadSceneAsync的命名,增加_handlingScene当前正在处理的Scene保护
This commit is contained in:
Alex-Rachel
2025-03-19 09:30:27 +08:00
parent 61b2baeaf7
commit 36db2f3aba
2 changed files with 103 additions and 11 deletions

View File

@@ -20,7 +20,7 @@ namespace TEngine
/// <param name="priority">优先级</param> /// <param name="priority">优先级</param>
/// <param name="gcCollect">加载主场景是否回收垃圾。</param> /// <param name="gcCollect">加载主场景是否回收垃圾。</param>
/// <param name="progressCallBack">加载进度回调。</param> /// <param name="progressCallBack">加载进度回调。</param>
public UniTask<Scene> LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true, public UniTask<Scene> LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true,
Action<float> progressCallBack = null); Action<float> progressCallBack = null);
/// <summary> /// <summary>
@@ -62,13 +62,20 @@ namespace TEngine
/// <returns>是否主场景。</returns> /// <returns>是否主场景。</returns>
public bool IsMainScene(string location); public bool IsMainScene(string location);
/// <summary>
/// 异步卸载子场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <param name="progressCallBack">进度回调。</param>
public UniTask<bool> UnloadAsync(string location, Action<float> progressCallBack = null);
/// <summary> /// <summary>
/// 异步卸载子场景。 /// 异步卸载子场景。
/// </summary> /// </summary>
/// <param name="location">场景资源定位地址。</param> /// <param name="location">场景资源定位地址。</param>
/// <param name="callBack">卸载完成回调。</param> /// <param name="callBack">卸载完成回调。</param>
/// <param name="progressCallBack">进度回调。</param> /// <param name="progressCallBack">进度回调。</param>
public void UnloadAsync(string location, Action callBack = null, Action<float> progressCallBack = null); public void Unload(string location, Action callBack = null, Action<float> progressCallBack = null);
/// <summary> /// <summary>
/// 是否包含场景。 /// 是否包含场景。

View File

@@ -14,6 +14,8 @@ namespace TEngine
private readonly Dictionary<string, SceneHandle> _subScenes = new Dictionary<string, SceneHandle>(); private readonly Dictionary<string, SceneHandle> _subScenes = new Dictionary<string, SceneHandle>();
private readonly HashSet<string> _handlingScene = new HashSet<string>();
/// <summary> /// <summary>
/// 当前主场景名称。 /// 当前主场景名称。
/// </summary> /// </summary>
@@ -39,6 +41,7 @@ namespace TEngine
iter.Dispose(); iter.Dispose();
_subScenes.Clear(); _subScenes.Clear();
_handlingScene.Clear();
_currentMainSceneName = string.Empty; _currentMainSceneName = string.Empty;
} }
@@ -51,8 +54,14 @@ namespace TEngine
/// <param name="priority">优先级</param> /// <param name="priority">优先级</param>
/// <param name="gcCollect">加载主场景是否回收垃圾。</param> /// <param name="gcCollect">加载主场景是否回收垃圾。</param>
/// <param name="progressCallBack">加载进度回调。</param> /// <param name="progressCallBack">加载进度回调。</param>
public async UniTask<Scene> LoadScene(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true, Action<float> progressCallBack = null) public async UniTask<Scene> LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, uint priority = 100, bool gcCollect = true, Action<float> progressCallBack = null)
{ {
if (!_handlingScene.Add(location))
{
Log.Error($"Could not load scene while loading. Scene: {location}");
return default;
}
if (sceneMode == LoadSceneMode.Additive) if (sceneMode == LoadSceneMode.Additive)
{ {
if (_subScenes.TryGetValue(location, out SceneHandle subScene)) if (_subScenes.TryGetValue(location, out SceneHandle subScene))
@@ -62,7 +71,6 @@ namespace TEngine
subScene = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority); subScene = YooAssets.LoadSceneAsync(location, sceneMode, LocalPhysicsMode.None, suspendLoad, priority);
if (progressCallBack != null) if (progressCallBack != null)
{ {
while (!subScene.IsDone && subScene.IsValid) while (!subScene.IsDone && subScene.IsValid)
@@ -78,6 +86,8 @@ namespace TEngine
_subScenes.Add(location, subScene); _subScenes.Add(location, subScene);
_handlingScene.Remove(location);
return subScene.SceneObject; return subScene.SceneObject;
} }
else else
@@ -106,6 +116,8 @@ namespace TEngine
ModuleSystem.GetModule<IResourceModule>().ForceUnloadUnusedAssets(gcCollect); ModuleSystem.GetModule<IResourceModule>().ForceUnloadUnusedAssets(gcCollect);
_handlingScene.Remove(location);
return _currentMainScene.SceneObject; return _currentMainScene.SceneObject;
} }
} }
@@ -124,6 +136,13 @@ namespace TEngine
Action<Scene> callBack = null, Action<Scene> callBack = null,
bool gcCollect = true, Action<float> progressCallBack = null) bool gcCollect = true, Action<float> progressCallBack = null)
{ {
if (!_handlingScene.Add(location))
{
Log.Error($"Could not load scene while loading. Scene: {location}");
return;
}
if (sceneMode == LoadSceneMode.Additive) if (sceneMode == LoadSceneMode.Additive)
{ {
if (_subScenes.TryGetValue(location, out SceneHandle subScene)) if (_subScenes.TryGetValue(location, out SceneHandle subScene))
@@ -136,7 +155,11 @@ namespace TEngine
if (callBack != null) if (callBack != null)
{ {
subScene.Completed += handle => { callBack.Invoke(handle.SceneObject); }; subScene.Completed += handle =>
{
_handlingScene.Remove(location);
callBack.Invoke(handle.SceneObject);
};
} }
if (progressCallBack != null) if (progressCallBack != null)
@@ -160,7 +183,11 @@ namespace TEngine
if (callBack != null) if (callBack != null)
{ {
_currentMainScene.Completed += handle => { callBack.Invoke(handle.SceneObject); }; _currentMainScene.Completed += handle =>
{
_handlingScene.Remove(location);
callBack.Invoke(handle.SceneObject);
};
} }
if (progressCallBack != null) if (progressCallBack != null)
@@ -277,13 +304,61 @@ namespace TEngine
return false; return false;
} }
/// <summary>
/// 异步卸载子场景。
/// </summary>
/// <param name="location">场景资源定位地址。</param>
/// <param name="progressCallBack">进度回调。</param>
public async UniTask<bool> UnloadAsync(string location, Action<float> progressCallBack = null)
{
_subScenes.TryGetValue(location, out SceneHandle subScene);
if (subScene != null)
{
if (subScene.SceneObject == default)
{
Log.Error($"Could not unload Scene while not loaded. Scene: {location}");
return false;
}
if (!_handlingScene.Add(location))
{
Log.Warning($"Could not unload Scene while loading. Scene: {location}");
return false;
}
var unloadOperation = subScene.UnloadAsync();
if (progressCallBack != null)
{
while (!unloadOperation.IsDone && unloadOperation.Status != EOperationStatus.Failed)
{
progressCallBack.Invoke(unloadOperation.Progress);
await UniTask.Yield();
}
}
else
{
await unloadOperation.ToUniTask();
}
_subScenes.Remove(location);
_handlingScene.Remove(location);
return true;
}
Log.Warning($"UnloadAsync invalid location:{location}");
return false;
}
/// <summary> /// <summary>
/// 异步卸载子场景。 /// 异步卸载子场景。
/// </summary> /// </summary>
/// <param name="location">场景资源定位地址。</param> /// <param name="location">场景资源定位地址。</param>
/// <param name="callBack">卸载完成回调。</param> /// <param name="callBack">卸载完成回调。</param>
/// <param name="progressCallBack">进度回调。</param> /// <param name="progressCallBack">进度回调。</param>
public void UnloadAsync(string location, Action callBack = null, Action<float> progressCallBack = null) public void Unload(string location, Action callBack = null, Action<float> progressCallBack = null)
{ {
_subScenes.TryGetValue(location, out SceneHandle subScene); _subScenes.TryGetValue(location, out SceneHandle subScene);
if (subScene != null) if (subScene != null)
@@ -294,11 +369,21 @@ namespace TEngine
return; return;
} }
_subScenes.Remove(location); if (!_handlingScene.Add(location))
{
Log.Warning($"Could not unload Scene while loading. Scene: {location}");
return;
}
subScene.UnloadAsync(); subScene.UnloadAsync();
if (callBack != null) if (callBack != null)
{ {
subScene.UnloadAsync().Completed += @base => { callBack.Invoke(); }; subScene.UnloadAsync().Completed += @base =>
{
_subScenes.Remove(location);
_handlingScene.Remove(location);
callBack.Invoke();
};
} }
if (progressCallBack != null) if (progressCallBack != null)