using System; using System.Collections.Generic; using UnityEngine; using UnityEditor.AdaptivePerformance.Editor.Metadata; namespace UnityEditor.AdaptivePerformance.Editor { /// Interface for specifying package initialization information public interface AdaptivePerformancePackageInitializationBase { /// Package name property /// The name of the package string PackageName { get; } /// The loader full type name for this package /// Loader full type name string LoaderFullTypeName { get; } /// The loader type name for this package /// Loader type name string LoaderTypeName { get; } /// The settings full type name for this package /// Settings full type name string SettingsFullTypeName { get; } /// The settings type name for this package /// Settings type name string SettingsTypeName { get; } /// Package initialization key /// The init key for the package string PackageInitKey { get; } /// Initialize package settings /// The scriptable object instance to initialize /// True if successful, false if not. bool PopulateSettingsOnInitialization(ScriptableObject obj); } [InitializeOnLoad] class AdaptivePerformancePackageInitializationBootstrap { static AdaptivePerformancePackageInitializationBootstrap() { if (!EditorApplication.isPlayingOrWillChangePlaymode) { EditorApplication.update += BeginPackageInitialization; } EditorApplication.playModeStateChanged += PlayModeStateChanged; } private static void PlayModeStateChanged(PlayModeStateChange state) { switch (state) { case PlayModeStateChange.EnteredPlayMode: BeginPackageInitialization(); break; case PlayModeStateChange.EnteredEditMode: BeginPackageInitialization(); break; } } internal static void BeginPackageInitialization() { EditorApplication.update -= BeginPackageInitialization; foreach (var t in TypeLoaderExtensions.GetAllTypesWithInterface()) { if (t.IsInterface || t.FullName.Contains("UnityEditor.AdaptivePerformance.TestPackage") || t.FullName.Contains("UnityEditor.AdaptivePerformance.Editor.Metadata.AdaptivePerformanceKnownPackages")) continue; IAdaptivePerformancePackage package = Activator.CreateInstance(t) as IAdaptivePerformancePackage; if (package == null) { Debug.LogError($"Unable to find an implementation for expected package type {t.FullName}."); continue; } InitPackage(package); } foreach (var t in TypeLoaderExtensions.GetAllTypesWithInterface()) { if (t.IsInterface) continue; AdaptivePerformancePackageInitializationBase packageInit = Activator.CreateInstance(t) as AdaptivePerformancePackageInitializationBase; if (packageInit == null) { Debug.LogError($"Unable to find an implementation for expected package type {t.FullName}."); continue; } InitPackage(packageInit); } if (AdaptivePerformanceSettingsManager.Instance != null) AdaptivePerformanceSettingsManager.Instance.ResetUi = true; } internal static void InitPackage(IAdaptivePerformancePackage package) { var packageMetadata = package.metadata; if (packageMetadata == null) { Debug.LogError($"Package {package.GetType().Name} has a package definition but has no metadata. Skipping initialization."); return; } AdaptivePerformancePackageMetadataStore.AddPluginPackage(package); if (!InitializePackageFromMetadata(package, packageMetadata)) { Debug.LogWarning( String.Format("{0} package Initialization not completed. You will need to create any instances of the loaders and settings manually before you can use the intended Adaptive Performance Provider Package.", packageMetadata.packageName)); } } static bool InitializePackageFromMetadata(IAdaptivePerformancePackage package, IAdaptivePerformancePackageMetadata packageMetadata) { bool ret = true; ret = ret && InitializeLoaderFromMetadata(packageMetadata.packageName, packageMetadata.loaderMetadata); ret = ret && InitializeSettingsFromMetadata(package, packageMetadata.packageName, packageMetadata.settingsType, packageMetadata.licenseURL); return ret; } static bool InitializeLoaderFromMetadata(string packageName, List loaderMetadatas) { if (String.IsNullOrEmpty(packageName)) return false; if (loaderMetadatas == null || loaderMetadatas.Count == 0) { Debug.LogWarning($"Package {packageName} has no loader metadata. Skipping loader initialization."); return true; } bool ret = true; foreach (var loader in loaderMetadatas) { bool hasInstance = EditorUtilities.AssetDatabaseHasInstanceOfType(loader.loaderType); if (!hasInstance) { var obj = EditorUtilities.CreateScriptableObjectInstance(loader.loaderType, EditorUtilities.GetAssetPathForComponents(EditorUtilities.s_DefaultLoaderPath)); hasInstance = (obj != null); if (!hasInstance) { Debug.LogError($"Error creating instance of loader {loader.loaderName} for package {packageName}"); } } ret |= hasInstance; } return ret; } static bool InitializeSettingsFromMetadata(IAdaptivePerformancePackage package, string packageName, string settingsType, string licenseURL) { if (String.IsNullOrEmpty(packageName)) return false; if (settingsType == null) { Debug.LogWarning($"Package {packageName} has no settings metadata. Skipping settings initialization."); return true; } bool ret = EditorUtilities.AssetDatabaseHasInstanceOfType(settingsType); if (!ret) { var obj = EditorUtilities.CreateScriptableObjectInstance(settingsType, EditorUtilities.GetAssetPathForComponents(EditorUtilities.s_DefaultSettingsPath)); ret = package.PopulateNewSettingsInstance(obj); } return ret; } static void InitPackage(AdaptivePerformancePackageInitializationBase packageInit) { if (!InitializeLoaderInstance(packageInit)) { Debug.LogWarning( String.Format("{0} Loader Initialization not completed. You will need to create an instance of the loader manually before you can use the intended Adaptive Performance Provider Package.", packageInit.PackageName)); } if (!InitializeSettingsInstance(packageInit)) { Debug.LogWarning( String.Format("{0} Settings Initialization not completed. You will need to create an instance of settings to customize options specific to this package.", packageInit.PackageName)); } } static bool InitializeLoaderInstance(AdaptivePerformancePackageInitializationBase packageInit) { bool ret = EditorUtilities.AssetDatabaseHasInstanceOfType(packageInit.LoaderTypeName); if (!ret) { var obj = EditorUtilities.CreateScriptableObjectInstance(packageInit.LoaderFullTypeName, EditorUtilities.GetAssetPathForComponents(EditorUtilities.s_DefaultLoaderPath)); ret = (obj != null); } return ret; } static bool InitializeSettingsInstance(AdaptivePerformancePackageInitializationBase packageInit) { bool ret = EditorUtilities.AssetDatabaseHasInstanceOfType(packageInit.SettingsTypeName); if (!ret) { var obj = EditorUtilities.CreateScriptableObjectInstance(packageInit.SettingsFullTypeName, EditorUtilities.GetAssetPathForComponents(EditorUtilities.s_DefaultSettingsPath)); ret = packageInit.PopulateSettingsOnInitialization(obj); } return ret; } } }