using System; using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; namespace Unity.Services.Core { /// /// Utility to initialize all Unity services from a single endpoint. /// class UnityServicesInternal : IUnityServices { /// /// Initialization state. /// public ServicesInitializationState State { get; internal set; } public InitializationOptions Options { get; internal set; } internal bool CanInitialize; internal AsyncOperation Initialization; /// /// Single entry point to initialize all used services. /// /// /// The options to customize services initialization. /// /// /// Return a handle to the initialization operation. /// public Task Initialize(InitializationOptions options) { if (!HasRequestedInitialization() || HasInitializationFailed()) { Options = options; CreateInitialization(); } if (!CanInitialize || State != ServicesInitializationState.Uninitialized) { return Initialization.AsTask(); } StartInitialization(); return Initialization.AsTask(); } bool HasRequestedInitialization() { return !(Initialization is null); } bool HasInitializationFailed() { return Initialization.Status == AsyncOperationStatus.Failed; } void CreateInitialization() { Initialization = new AsyncOperation(); Initialization.SetInProgress(); Initialization.Completed += OnInitializationCompleted; } void StartInitialization() { State = ServicesInitializationState.Initializing; var registry = CoreRegistry.Instance; var sortedPackageTypeHashes = new List(registry.Tree.PackageTypeHashToInstance.Count); try { var sorter = new DependencyTreeInitializeOrderSorter(registry.Tree, sortedPackageTypeHashes); sorter.SortRegisteredPackagesIntoTarget(); } catch (Exception reason) { Initialization.Fail(reason); return; } try { var initializer = new CoreRegistryInitializer(registry, Initialization, sortedPackageTypeHashes); initializer.InitializeRegistry(); } catch (Exception reason) { Initialization.Fail(reason); } } void OnInitializationCompleted(IAsyncOperation initialization) { switch (initialization.Status) { case AsyncOperationStatus.Succeeded: { State = ServicesInitializationState.Initialized; CoreRegistry.Instance.LockComponentRegistration(); break; } default: { State = ServicesInitializationState.Uninitialized; break; } } } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] internal static void EnableInitialization() { var instance = (UnityServicesInternal)UnityServices.Instance; instance.CanInitialize = true; CoreRegistry.Instance.LockPackageRegistration(); if (instance.HasRequestedInitialization()) { instance.StartInitialization(); } } } }