Nenhuma descrição
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

AdaptivePerformanceManagerSettings.cs 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Runtime.CompilerServices;
  6. using UnityEditor;
  7. using UnityEngine;
  8. using UnityEngine.Rendering;
  9. using UnityEngine.UIElements;
  10. using UnityEngine.Serialization;
  11. [assembly: InternalsVisibleTo("Unity.AdaptivePerformance.Tests")]
  12. namespace UnityEngine.AdaptivePerformance
  13. {
  14. /// <summary>
  15. /// Class to handle active loader and subsystem management for Adaptive Performance. This class is to be added as a
  16. /// ScriptableObject asset in your project and should only be referenced by an <see cref="AdaptivePerformanceGeneralSettings"/>
  17. /// instance for its use.
  18. ///
  19. /// Given a list of loaders, it will attempt to load each loader in the given order. Unity will use the first
  20. /// loader that is successful and ignore all remaining loaders. The successful loader
  21. /// is accessible through the <see cref="activeLoader"/> property on the manager.
  22. ///
  23. /// Depending on configuration, the <see cref="AdaptivePerformanceGeneralSettings"/> instance will automatically manage the active loader
  24. /// at the correct points in the application lifecycle. You can override certain points in the active loader lifecycle
  25. /// and manually manage them by toggling the <see cref="AdaptivePerformanceManagerSettings.automaticLoading"/> and <see cref="AdaptivePerformanceManagerSettings.automaticRunning"/>
  26. /// properties. Disabling <see cref="AdaptivePerformanceManagerSettings.automaticLoading"/> implies that you are responsible for the full lifecycle
  27. /// of the Adaptive Performance session normally handled by the <see cref="AdaptivePerformanceGeneralSettings"/> instance. Setting this to false also sets
  28. /// <see cref="AdaptivePerformanceManagerSettings.automaticRunning"/> to false.
  29. ///
  30. /// Disabling <see cref="AdaptivePerformanceManagerSettings.automaticRunning"/> only implies that you are responsible for starting and stopping
  31. /// the <see cref="activeLoader"/> through the <see cref="StartSubsystems"/> and <see cref="StopSubsystems"/> APIs.
  32. ///
  33. /// Unity executes atomatic lifecycle management as follows:
  34. ///
  35. /// * OnEnable calls <see cref="InitializeLoader"/> internally. The loader list will be iterated over and the first successful loader will be set as the active loader.
  36. /// * Start calls <see cref="StartSubsystems"/> internally. Ask the active loader to start all subsystems.
  37. /// * OnDisable calls <see cref="StopSubsystems"/> internally. Ask the active loader to stop all subsystems.
  38. /// * OnDestroy calls <see cref="DeinitializeLoader"/> internally. Deinitialize and remove the active loader.
  39. /// </summary>
  40. public sealed class AdaptivePerformanceManagerSettings : ScriptableObject
  41. {
  42. [HideInInspector]
  43. bool m_InitializationComplete = false;
  44. [SerializeField]
  45. [Tooltip("Determines if the Adaptive Performance Manager instance is responsible for creating and destroying the appropriate loader instance.")]
  46. bool m_AutomaticLoading = false;
  47. /// <summary>
  48. /// Get and set Automatic Loading state for this manager. When this is true, the manager will automatically call
  49. /// <see cref="InitializeLoader"/> and <see cref="DeinitializeLoader"/> for you. When false, <see cref="automaticRunning"/>
  50. /// is also set to false and remains that way. This means that disabling automatic loading disables all automatic behavior
  51. /// for the manager.
  52. /// </summary>
  53. public bool automaticLoading
  54. {
  55. get { return m_AutomaticLoading; }
  56. set { m_AutomaticLoading = value; }
  57. }
  58. [SerializeField]
  59. [Tooltip("Determines if the Adaptive Performance Manager instance is responsible for starting and stopping subsystems for the active loader instance.")]
  60. bool m_AutomaticRunning = false;
  61. /// <summary>
  62. /// Get and set the automatic running state for this manager. When this is true, the manager will call <see cref="StartSubsystems"/>
  63. /// and <see cref="StopSubsystems"/> APIs at appropriate times. When false, or when <see cref="automaticLoading"/> is false,
  64. /// it is up to the user of the manager to handle that same functionality.
  65. /// </summary>
  66. public bool automaticRunning
  67. {
  68. get { return m_AutomaticRunning; }
  69. set { m_AutomaticRunning = value; }
  70. }
  71. [SerializeField]
  72. [Tooltip("List of Adaptive Performance Loader instances arranged in desired load order.")]
  73. List<AdaptivePerformanceLoader> m_Loaders = new List<AdaptivePerformanceLoader>();
  74. /// <summary>
  75. /// List of loaders currently managed by this Adaptive Performance Manager instance.
  76. /// </summary>
  77. public List<AdaptivePerformanceLoader> loaders
  78. {
  79. get { return m_Loaders; }
  80. #if UNITY_EDITOR
  81. set { m_Loaders = value; }
  82. #endif
  83. }
  84. /// <summary>
  85. /// Read-only boolean that is true if initialization is completed and false otherwise. Because initialization is
  86. /// handled as a Coroutine, applications that use the auto-lifecycle management of AdaptivePerformanceManager
  87. /// will need to wait for init to complete before checking for an ActiveLoader and calling StartSubsystems.
  88. /// </summary>
  89. public bool isInitializationComplete
  90. {
  91. get { return m_InitializationComplete; }
  92. }
  93. [HideInInspector]
  94. static AdaptivePerformanceLoader s_ActiveLoader = null;
  95. ///<summary>
  96. /// Returns the current singleton active loader instance.
  97. ///</summary>
  98. [HideInInspector]
  99. public AdaptivePerformanceLoader activeLoader { get { return s_ActiveLoader; } private set { s_ActiveLoader = value; } }
  100. /// <summary>
  101. /// Returns the current active loader, cast to the requested type. Useful shortcut when you need
  102. /// to get the active loader as something less generic than AdaptivePerformanceLoader.
  103. /// </summary>
  104. /// <typeparam name="T">Requested type of the loader.</typeparam>
  105. /// <returns>The active loader as requested type, or null if no active loader currently exists.</returns>
  106. public T ActiveLoaderAs<T>() where T : AdaptivePerformanceLoader
  107. {
  108. return activeLoader as T;
  109. }
  110. /// <summary>
  111. /// Iterate over the configured list of loaders and attempt to initialize each one. The first one
  112. /// that succeeds is set as the active loader and initialization immediately terminates.
  113. ///
  114. /// When this completes, <see cref="isInitializationComplete"/> will be set to true. This will mark that it is safe to
  115. /// call other parts of the API, but does not guarantee that init successfully created a loader. To check that init successfully created a loader,
  116. /// you need to check that ActiveLoader is not null.
  117. ///
  118. /// **Note**: There can only be one active loader. Any attempt to initialize a new active loader with one
  119. /// already set will cause a warning to be logged and immediate exit of this function.
  120. ///
  121. /// This method is synchronous and on return all state should be immediately checkable.
  122. /// </summary>
  123. public void InitializeLoaderSync()
  124. {
  125. if (isInitializationComplete && activeLoader != null)
  126. {
  127. Debug.LogWarning(
  128. "Adaptive Performance Management has already initialized an active loader in this scene." +
  129. "Please make sure to stop all subsystems and deinitialize the active loader before initializing a new one.");
  130. return;
  131. }
  132. foreach (var loader in loaders)
  133. {
  134. if (loader != null)
  135. {
  136. if (loader.Initialize())
  137. {
  138. activeLoader = loader;
  139. m_InitializationComplete = true;
  140. return;
  141. }
  142. }
  143. }
  144. activeLoader = null;
  145. }
  146. /// <summary>
  147. /// Iterate over the configured list of loaders and attempt to initialize each one. The first one
  148. /// that succeeds is set as the active loader and initialization immediately terminates.
  149. ///
  150. /// When complete, <see cref="isInitializationComplete"/> will be set to true. This will mark that it is safe to
  151. /// call other parts of the API, but does not guarantee that init successfully created a loader. To check that init successfully created a loader,
  152. /// you need to check that ActiveLoader is not null.
  153. ///
  154. /// **Note:** There can only be one active loader. Any attempt to initialize a new active loader with one
  155. /// already set will cause a warning to be logged and this function wil immeditely exit.
  156. ///
  157. /// Iteration is done asynchronously. You must call this method within the context of a Coroutine.
  158. /// </summary>
  159. ///
  160. /// <returns>Enumerator marking the next spot to continue execution at.</returns>
  161. public IEnumerator InitializeLoader()
  162. {
  163. if (isInitializationComplete && activeLoader != null)
  164. {
  165. Debug.LogWarning(
  166. "Adaptive Performance Management has already initialized an active loader in this scene." +
  167. "Please make sure to stop all subsystems and deinitialize the active loader before initializing a new one.");
  168. yield break;
  169. }
  170. foreach (var loader in loaders)
  171. {
  172. if (loader != null)
  173. {
  174. if (loader.Initialize())
  175. {
  176. activeLoader = loader;
  177. m_InitializationComplete = true;
  178. yield break;
  179. }
  180. }
  181. yield return null;
  182. }
  183. activeLoader = null;
  184. }
  185. /// <summary>
  186. /// If there is an active loader, this will request the loader to start all the subsystems that it
  187. /// is managing.
  188. ///
  189. /// You must wait for <see cref="isInitializationComplete"/> to be set to true before calling this API.
  190. /// </summary>
  191. public void StartSubsystems()
  192. {
  193. if (!m_InitializationComplete)
  194. {
  195. Debug.LogWarning(
  196. "Call to StartSubsystems without an initialized manager." +
  197. "Please make sure to wait for initialization to complete before calling this API.");
  198. return;
  199. }
  200. if (activeLoader != null)
  201. {
  202. activeLoader.Start();
  203. }
  204. }
  205. /// <summary>
  206. /// If there is an active loader, this will request the loader to stop all the subsystems that it
  207. /// is managing.
  208. ///
  209. /// You must wait for <see cref="isInitializationComplete"/> to be set to true before calling this API.
  210. /// </summary>
  211. public void StopSubsystems()
  212. {
  213. if (!m_InitializationComplete)
  214. {
  215. Debug.LogWarning(
  216. "Call to StopSubsystems without an initialized manager." +
  217. "Please make sure to wait for initialization to complete before calling this API.");
  218. return;
  219. }
  220. if (activeLoader != null)
  221. {
  222. activeLoader.Stop();
  223. }
  224. }
  225. /// <summary>
  226. /// If there is an active loader, this function will deinitialize it and remove the active loader instance from
  227. /// management. Unity will automatically call <see cref="StopSubsystems"/> before deinitialization to make sure
  228. /// that things are cleaned up appropriately.
  229. ///
  230. /// You must wait for <see cref="isInitializationComplete"/> to be set to true before calling this API.
  231. ///
  232. /// On return, <see cref="isInitializationComplete"/> will be set to false.
  233. /// </summary>
  234. public void DeinitializeLoader()
  235. {
  236. if (!m_InitializationComplete)
  237. {
  238. Debug.LogWarning(
  239. "Call to DeinitializeLoader without an initialized manager." +
  240. "Please make sure to wait for initialization to complete before calling this API.");
  241. return;
  242. }
  243. StopSubsystems();
  244. if (activeLoader != null)
  245. {
  246. activeLoader.Deinitialize();
  247. activeLoader = null;
  248. }
  249. m_InitializationComplete = false;
  250. }
  251. // Use this for initialization
  252. void Start()
  253. {
  254. if (automaticLoading && automaticRunning)
  255. {
  256. StartSubsystems();
  257. }
  258. }
  259. void OnDisable()
  260. {
  261. if (automaticLoading && automaticRunning)
  262. {
  263. StopSubsystems();
  264. }
  265. }
  266. void OnDestroy()
  267. {
  268. if (automaticLoading)
  269. {
  270. DeinitializeLoader();
  271. }
  272. }
  273. }
  274. }