//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 loyalsoft. All rights reserved.
// Homepage: http://www.game7000.com/
// Feedback: http://www.game7000.com/
//------------------------------------------------------------
using GameFramework.Resource;
using System;
using System.Collections.Generic;
namespace GameFramework.Scene
{
///
/// 场景管理器。
///
internal sealed class SceneManager : GameFrameworkModule, ISceneManager
{
private readonly List m_LoadedSceneAssetNames;
private readonly List m_LoadingSceneAssetNames;
private readonly List m_UnloadingSceneAssetNames;
private readonly LoadSceneCallbacks m_LoadSceneCallbacks;
private readonly UnloadSceneCallbacks m_UnloadSceneCallbacks;
private IResourceManager m_ResourceManager;
private EventHandler m_LoadSceneSuccessEventHandler;
private EventHandler m_LoadSceneFailureEventHandler;
private EventHandler m_LoadSceneUpdateEventHandler;
private EventHandler m_LoadSceneDependencyAssetEventHandler;
private EventHandler m_UnloadSceneSuccessEventHandler;
private EventHandler m_UnloadSceneFailureEventHandler;
///
/// 初始化场景管理器的新实例。
///
public SceneManager()
{
m_LoadedSceneAssetNames = new List();
m_LoadingSceneAssetNames = new List();
m_UnloadingSceneAssetNames = new List();
m_LoadSceneCallbacks = new LoadSceneCallbacks(LoadSceneSuccessCallback, LoadSceneFailureCallback, LoadSceneUpdateCallback, LoadSceneDependencyAssetCallback);
m_UnloadSceneCallbacks = new UnloadSceneCallbacks(UnloadSceneSuccessCallback, UnloadSceneFailureCallback);
m_ResourceManager = null;
m_LoadSceneSuccessEventHandler = null;
m_LoadSceneFailureEventHandler = null;
m_LoadSceneUpdateEventHandler = null;
m_LoadSceneDependencyAssetEventHandler = null;
m_UnloadSceneSuccessEventHandler = null;
m_UnloadSceneFailureEventHandler = null;
}
///
/// 获取游戏框架模块优先级。
///
/// 优先级较高的模块会优先轮询,并且关闭操作会后进行。
internal override int Priority
{
get
{
return 2;
}
}
///
/// 加载场景成功事件。
///
public event EventHandler LoadSceneSuccess
{
add
{
m_LoadSceneSuccessEventHandler += value;
}
remove
{
m_LoadSceneSuccessEventHandler -= value;
}
}
///
/// 加载场景失败事件。
///
public event EventHandler LoadSceneFailure
{
add
{
m_LoadSceneFailureEventHandler += value;
}
remove
{
m_LoadSceneFailureEventHandler -= value;
}
}
///
/// 加载场景更新事件。
///
public event EventHandler LoadSceneUpdate
{
add
{
m_LoadSceneUpdateEventHandler += value;
}
remove
{
m_LoadSceneUpdateEventHandler -= value;
}
}
///
/// 加载场景时加载依赖资源事件。
///
public event EventHandler LoadSceneDependencyAsset
{
add
{
m_LoadSceneDependencyAssetEventHandler += value;
}
remove
{
m_LoadSceneDependencyAssetEventHandler -= value;
}
}
///
/// 卸载场景成功事件。
///
public event EventHandler UnloadSceneSuccess
{
add
{
m_UnloadSceneSuccessEventHandler += value;
}
remove
{
m_UnloadSceneSuccessEventHandler -= value;
}
}
///
/// 卸载场景失败事件。
///
public event EventHandler UnloadSceneFailure
{
add
{
m_UnloadSceneFailureEventHandler += value;
}
remove
{
m_UnloadSceneFailureEventHandler -= value;
}
}
///
/// 场景管理器轮询。
///
/// 逻辑流逝时间,以秒为单位。
/// 真实流逝时间,以秒为单位。
internal override void Update(float elapseSeconds, float realElapseSeconds)
{
}
///
/// 关闭并清理场景管理器。
///
internal override void Shutdown()
{
string[] loadedSceneAssetNames = m_LoadedSceneAssetNames.ToArray();
foreach (string loadedSceneAssetName in loadedSceneAssetNames)
{
if (SceneIsUnloading(loadedSceneAssetName))
{
continue;
}
UnloadScene(loadedSceneAssetName);
}
m_LoadedSceneAssetNames.Clear();
m_LoadingSceneAssetNames.Clear();
m_UnloadingSceneAssetNames.Clear();
}
///
/// 设置资源管理器。
///
/// 资源管理器。
public void SetResourceManager(IResourceManager resourceManager)
{
if (resourceManager == null)
{
throw new GameFrameworkException("Resource manager is invalid.");
}
m_ResourceManager = resourceManager;
}
///
/// 获取场景是否已加载。
///
/// 场景资源名称。
/// 场景是否已加载。
public bool SceneIsLoaded(string sceneAssetName)
{
if (string.IsNullOrEmpty(sceneAssetName))
{
throw new GameFrameworkException("Scene asset name is invalid.");
}
return m_LoadedSceneAssetNames.Contains(sceneAssetName);
}
///
/// 获取已加载场景的资源名称。
///
/// 已加载场景的资源名称。
public string[] GetLoadedSceneAssetNames()
{
return m_LoadedSceneAssetNames.ToArray();
}
///
/// 获取已加载场景的资源名称。
///
/// 已加载场景的资源名称。
public void GetLoadedSceneAssetNames(List results)
{
if (results == null)
{
throw new GameFrameworkException("Results is invalid.");
}
results.Clear();
results.AddRange(m_LoadedSceneAssetNames);
}
///
/// 获取场景是否正在加载。
///
/// 场景资源名称。
/// 场景是否正在加载。
public bool SceneIsLoading(string sceneAssetName)
{
if (string.IsNullOrEmpty(sceneAssetName))
{
throw new GameFrameworkException("Scene asset name is invalid.");
}
return m_LoadingSceneAssetNames.Contains(sceneAssetName);
}
///
/// 获取正在加载场景的资源名称。
///
/// 正在加载场景的资源名称。
public string[] GetLoadingSceneAssetNames()
{
return m_LoadingSceneAssetNames.ToArray();
}
///
/// 获取正在加载场景的资源名称。
///
/// 正在加载场景的资源名称。
public void GetLoadingSceneAssetNames(List results)
{
if (results == null)
{
throw new GameFrameworkException("Results is invalid.");
}
results.Clear();
results.AddRange(m_LoadingSceneAssetNames);
}
///
/// 获取场景是否正在卸载。
///
/// 场景资源名称。
/// 场景是否正在卸载。
public bool SceneIsUnloading(string sceneAssetName)
{
if (string.IsNullOrEmpty(sceneAssetName))
{
throw new GameFrameworkException("Scene asset name is invalid.");
}
return m_UnloadingSceneAssetNames.Contains(sceneAssetName);
}
///
/// 获取正在卸载场景的资源名称。
///
/// 正在卸载场景的资源名称。
public string[] GetUnloadingSceneAssetNames()
{
return m_UnloadingSceneAssetNames.ToArray();
}
///
/// 获取正在卸载场景的资源名称。
///
/// 正在卸载场景的资源名称。
public void GetUnloadingSceneAssetNames(List results)
{
if (results == null)
{
throw new GameFrameworkException("Results is invalid.");
}
results.Clear();
results.AddRange(m_UnloadingSceneAssetNames);
}
///
/// 检查场景资源是否存在。
///
/// 要检查场景资源的名称。
/// 场景资源是否存在。
public bool HasScene(string sceneAssetName)
{
return m_ResourceManager.HasAsset(sceneAssetName) != HasAssetResult.NotExist;
}
///
/// 加载场景。
///
/// 场景资源名称。
public void LoadScene(string sceneAssetName)
{
LoadScene(sceneAssetName, Constant.DefaultPriority, null);
}
///
/// 加载场景。
///
/// 场景资源名称。
/// 加载场景资源的优先级。
public void LoadScene(string sceneAssetName, int priority)
{
LoadScene(sceneAssetName, priority, null);
}
///
/// 加载场景。
///
/// 场景资源名称。
/// 用户自定义数据。
public void LoadScene(string sceneAssetName, object userData)
{
LoadScene(sceneAssetName, Constant.DefaultPriority, userData);
}
///
/// 加载场景。
///
/// 场景资源名称。
/// 加载场景资源的优先级。
/// 用户自定义数据。
public void LoadScene(string sceneAssetName, int priority, object userData)
{
if (string.IsNullOrEmpty(sceneAssetName))
{
throw new GameFrameworkException("Scene asset name is invalid.");
}
if (m_ResourceManager == null)
{
throw new GameFrameworkException("You must set resource manager first.");
}
if (SceneIsUnloading(sceneAssetName))
{
throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is being unloaded.", sceneAssetName));
}
if (SceneIsLoading(sceneAssetName))
{
throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is being loaded.", sceneAssetName));
}
if (SceneIsLoaded(sceneAssetName))
{
throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is already loaded.", sceneAssetName));
}
m_LoadingSceneAssetNames.Add(sceneAssetName);
m_ResourceManager.LoadScene(sceneAssetName, priority, m_LoadSceneCallbacks, userData);
}
///
/// 卸载场景。
///
/// 场景资源名称。
public void UnloadScene(string sceneAssetName)
{
UnloadScene(sceneAssetName, null);
}
///
/// 卸载场景。
///
/// 场景资源名称。
/// 用户自定义数据。
public void UnloadScene(string sceneAssetName, object userData)
{
if (string.IsNullOrEmpty(sceneAssetName))
{
throw new GameFrameworkException("Scene asset name is invalid.");
}
if (m_ResourceManager == null)
{
throw new GameFrameworkException("You must set resource manager first.");
}
if (SceneIsUnloading(sceneAssetName))
{
throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is being unloaded.", sceneAssetName));
}
if (SceneIsLoading(sceneAssetName))
{
throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is being loaded.", sceneAssetName));
}
if (!SceneIsLoaded(sceneAssetName))
{
throw new GameFrameworkException(Utility.Text.Format("Scene asset '{0}' is not loaded yet.", sceneAssetName));
}
m_UnloadingSceneAssetNames.Add(sceneAssetName);
m_ResourceManager.UnloadScene(sceneAssetName, m_UnloadSceneCallbacks, userData);
}
private void LoadSceneSuccessCallback(string sceneAssetName, float duration, object userData)
{
m_LoadingSceneAssetNames.Remove(sceneAssetName);
m_LoadedSceneAssetNames.Add(sceneAssetName);
if (m_LoadSceneSuccessEventHandler != null)
{
LoadSceneSuccessEventArgs loadSceneSuccessEventArgs = LoadSceneSuccessEventArgs.Create(sceneAssetName, duration, userData);
m_LoadSceneSuccessEventHandler(this, loadSceneSuccessEventArgs);
ReferencePool.Release(loadSceneSuccessEventArgs);
}
}
private void LoadSceneFailureCallback(string sceneAssetName, LoadResourceStatus status, string errorMessage, object userData)
{
m_LoadingSceneAssetNames.Remove(sceneAssetName);
string appendErrorMessage = Utility.Text.Format("Load scene failure, scene asset name '{0}', status '{1}', error message '{2}'.", sceneAssetName, status, errorMessage);
if (m_LoadSceneFailureEventHandler != null)
{
LoadSceneFailureEventArgs loadSceneFailureEventArgs = LoadSceneFailureEventArgs.Create(sceneAssetName, appendErrorMessage, userData);
m_LoadSceneFailureEventHandler(this, loadSceneFailureEventArgs);
ReferencePool.Release(loadSceneFailureEventArgs);
return;
}
throw new GameFrameworkException(appendErrorMessage);
}
private void LoadSceneUpdateCallback(string sceneAssetName, float progress, object userData)
{
if (m_LoadSceneUpdateEventHandler != null)
{
LoadSceneUpdateEventArgs loadSceneUpdateEventArgs = LoadSceneUpdateEventArgs.Create(sceneAssetName, progress, userData);
m_LoadSceneUpdateEventHandler(this, loadSceneUpdateEventArgs);
ReferencePool.Release(loadSceneUpdateEventArgs);
}
}
private void LoadSceneDependencyAssetCallback(string sceneAssetName, string dependencyAssetName, int loadedCount, int totalCount, object userData)
{
if (m_LoadSceneDependencyAssetEventHandler != null)
{
LoadSceneDependencyAssetEventArgs loadSceneDependencyAssetEventArgs = LoadSceneDependencyAssetEventArgs.Create(sceneAssetName, dependencyAssetName, loadedCount, totalCount, userData);
m_LoadSceneDependencyAssetEventHandler(this, loadSceneDependencyAssetEventArgs);
ReferencePool.Release(loadSceneDependencyAssetEventArgs);
}
}
private void UnloadSceneSuccessCallback(string sceneAssetName, object userData)
{
m_UnloadingSceneAssetNames.Remove(sceneAssetName);
m_LoadedSceneAssetNames.Remove(sceneAssetName);
if (m_UnloadSceneSuccessEventHandler != null)
{
UnloadSceneSuccessEventArgs unloadSceneSuccessEventArgs = UnloadSceneSuccessEventArgs.Create(sceneAssetName, userData);
m_UnloadSceneSuccessEventHandler(this, unloadSceneSuccessEventArgs);
ReferencePool.Release(unloadSceneSuccessEventArgs);
}
}
private void UnloadSceneFailureCallback(string sceneAssetName, object userData)
{
m_UnloadingSceneAssetNames.Remove(sceneAssetName);
if (m_UnloadSceneFailureEventHandler != null)
{
UnloadSceneFailureEventArgs unloadSceneFailureEventArgs = UnloadSceneFailureEventArgs.Create(sceneAssetName, userData);
m_UnloadSceneFailureEventHandler(this, unloadSceneFailureEventArgs);
ReferencePool.Release(unloadSceneFailureEventArgs);
return;
}
throw new GameFrameworkException(Utility.Text.Format("Unload scene failure, scene asset name '{0}'.", sceneAssetName));
}
}
}