using System;
using AlicizaX.ObjectPool;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace AlicizaX.Runtime
{
///
/// 基础组件。
///
[DisallowMultipleComponent]
[UnityEngine.Scripting.Preserve]
public sealed class RootModule : MonoBehaviour
{
private static RootModule _instance = null;
public static RootModule Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType();
}
return _instance;
}
}
private const int DEFAULT_DPI = 96;
private float _gameSpeedBeforePause = 1f;
[SerializeField] private int frameRate = 120;
[SerializeField] private float gameSpeed = 1f;
[SerializeField] private bool runInBackground = true;
[SerializeField] private bool neverSleep = true;
///
/// 获取或设置游戏帧率。
///
public int FrameRate
{
get => frameRate;
set => Application.targetFrameRate = frameRate = value;
}
///
/// 获取或设置游戏速度。
///
public float GameSpeed
{
get => gameSpeed;
set => Time.timeScale = gameSpeed = value >= 0f ? value : 0f;
}
///
/// 获取游戏是否暂停。
///
public bool IsGamePaused => gameSpeed <= 0f;
///
/// 获取是否正常游戏速度。
///
public bool IsNormalGameSpeed => Math.Abs(gameSpeed - 1f) < 0.01f;
///
/// 获取或设置是否允许后台运行。
///
public bool RunInBackground
{
get => runInBackground;
set => Application.runInBackground = runInBackground = value;
}
///
/// 获取或设置是否禁止休眠。
///
public bool NeverSleep
{
get => neverSleep;
set
{
neverSleep = value;
Screen.sleepTimeout = value ? SleepTimeout.NeverSleep : SleepTimeout.SystemSetting;
}
}
///
/// 暂停游戏。
///
public void PauseGame()
{
if (IsGamePaused)
{
return;
}
_gameSpeedBeforePause = GameSpeed;
GameSpeed = 0f;
}
///
/// 恢复游戏。
///
public void ResumeGame()
{
if (!IsGamePaused)
{
return;
}
GameSpeed = _gameSpeedBeforePause;
}
///
/// 重置为正常游戏速度。
///
public void ResetNormalGameSpeed()
{
if (IsNormalGameSpeed)
{
return;
}
GameSpeed = 1f;
}
///
/// 游戏框架组件初始化。
///
private void Awake()
{
_instance = this;
DontDestroyOnLoad(this);
Utility.Unity.MakeEntity(transform);
Log.Info("Game Version: {0}, Unity Version: {1}", AppVersion.GameVersion, Application.unityVersion);
Utility.Converter.ScreenDpi = Screen.dpi;
if (Utility.Converter.ScreenDpi <= 0)
{
Utility.Converter.ScreenDpi = DEFAULT_DPI;
}
Application.targetFrameRate = frameRate;
Time.timeScale = gameSpeed;
Application.runInBackground = runInBackground;
Screen.sleepTimeout = neverSleep ? SleepTimeout.NeverSleep : SleepTimeout.SystemSetting;
Application.lowMemory += OnLowMemory;
}
private void OnApplicationQuit()
{
Application.lowMemory -= OnLowMemory;
StopAllCoroutines();
Shutdown();
}
internal void Shutdown()
{
Destroy(gameObject);
Utility.Unity.Shutdown();
MemoryPool.ClearAll();
Utility.Marshal.FreeCachedHGlobal();
}
private void Update()
{
ModuleSystem.UpdateExecuteList(Time.deltaTime, Time.unscaledDeltaTime);
}
private void LateUpdate()
{
ModuleSystem.UpdateLateExecuteList();
}
private void FixedUpdate()
{
ModuleSystem.UpdateFixedExecuteList();
}
private void OnDrawGizmos()
{
ModuleSystem.UpdateGizmosExecuteList();
}
private void OnGUI()
{
ModuleSystem.UpdateGUIExecuteList();
}
private async void OnDestroy()
{
await UniTask.Yield();
ModuleSystem.Dispose();
}
private void OnLowMemory()
{
Log.Warning("Low memory reported...");
IObjectPoolModule objectPoolModule = ModuleSystem.GetModule();
if (objectPoolModule != null)
{
objectPoolModule.ReleaseAllUnused();
}
}
}
}