//------------------------------------------------------------ // 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)); } } }