// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; using System.Collections.Generic; using UnityEngine; namespace Microsoft.MixedReality.OpenXR { internal delegate void OpenXRContextEvent(IOpenXRContext sender, EventArgs args); internal delegate void OpenXRContextEvent(IOpenXRContext sender, TEventArgs args) where TEventArgs : EventArgs; internal interface IOpenXRContext { ulong Instance { get; } ulong SystemId { get; } ulong Session { get; } bool IsSessionRunning { get; } XrSessionState SessionState { get; } ulong SceneOriginSpace { get; } event OpenXRContextEvent InstanceCreated; // after instance is created event OpenXRContextEvent InstanceDestroying; // before instance is destroyed event OpenXRContextEvent SessionCreated; // after session is created event OpenXRContextEvent SessionDestroying; // before session is destroyed event OpenXRContextEvent SessionBegun; // after session is begun event OpenXRContextEvent SessionEnding; // before session is ended } internal interface ISubsystemPlugin { void CreateSubsystem(List descriptors, string id) where TDescriptor : ISubsystemDescriptor where TSubsystem : ISubsystem; void StartSubsystem() where T : class, ISubsystem; void StopSubsystem() where T : class, ISubsystem; void DestroySubsystem() where T : class, ISubsystem; } internal abstract class SubsystemController { protected readonly IOpenXRContext Context; public SubsystemController(IOpenXRContext context) { Context = context; } public virtual void OnSubsystemCreate(ISubsystemPlugin plugin) { } public virtual void OnSubsystemStart(ISubsystemPlugin plugin) { } public virtual void OnSubsystemStop(ISubsystemPlugin plugin) { } public virtual void OnSubsystemDestroy(ISubsystemPlugin plugin) { } internal static SubsystemController CreateFromInternalType(string fullName, IOpenXRContext context) { Type type = FindInternalPackageType(fullName); if (type != null) { // Throw exceptions if the type is not configured correctly var ctor = type.GetConstructor(new Type[] { typeof(IOpenXRContext) }); if (ctor == null) { throw new Exception($"Type {type.FullName} does not have a constructor that takes an IOpenXRContext"); } return (SubsystemController)ctor.Invoke(new object[] { context }); } return null; } private static Type FindInternalPackageType(string fullName) { Type subsystemControllerType = typeof(T); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (assembly.FullName.StartsWith("Microsoft.MixedReality.OpenXR.Internal")) { foreach (var type in assembly.GetTypes()) { if (subsystemControllerType.IsAssignableFrom(type) && type.FullName == fullName) { return type; } } } } return null; } } }