// // /*=============================================================================== // // Copyright (C) 2025 PhantomsXR Ltd. All Rights Reserved. // // // // This file is part of the Phantom.XRMOD.QuestModule.Runtime. // // // // The XR-MOD cannot be copied, distributed, or made available to // // third-parties for commercial purposes without written permission of PhantomsXR Ltd. // // // // Contact nswell@phantomsxr.com for licensing requests. // // ===============================================================================*/ using System; using Phantom.XRMOD.ActionNotification.Runtime; using Phantom.XRMOD.Core.Runtime; namespace Phantom.XRMOD.QuestModule.Runtime { /// /// Manages the lifecycle of XR algorithms on the Quest platform. /// /// Listens for notifications and controls the state (Start, Pause, Stop) /// of various algorithms such as Meshing and Passthrough. /// /// public class BuildXRAlgorithmLifeControllerCommand : ICommand, IReleaseCommand { /// /// Initializes a new instance of the class and immediately executes it. /// public BuildXRAlgorithmLifeControllerCommand() { Execute(); } /// /// Subscribes to the algorithm lifecycle control notification. /// public void Execute() { ActionNotificationCenter.DefaultCenter.AddObserver(XRAlgorithmLifeController, nameof(ActionParameterDataType.ARAlgorithmLifeCTRL)); } /// /// Unsubscribes from the algorithm lifecycle control notification. /// /// Optional project name context. public void Release(string _projectName = default) { ActionNotificationCenter.DefaultCenter.RemoveObserver(nameof(ActionParameterDataType.ARAlgorithmLifeCTRL)); } /// /// Callback handler for algorithm lifecycle notifications. /// /// Dispatches control commands to specific feature decorators based on the algorithm type in . /// /// /// Notification data containing . private void XRAlgorithmLifeController(BaseNotificationData _data) { if (_data is ARAlgorithmArgs tmp_Args) { switch (tmp_Args.ARAlgorithmType) { case ARAlgorithmType.ImageTracker: // Not support for Quest platform break; case ARAlgorithmType.Immersal: break; case ARAlgorithmType.Anchor: break; case ARAlgorithmType.Meshing: ExecuteOrCreateFeature(typeof(MetaQuestMeshingDecorator), tmp_Args); break; case ARAlgorithmType.PassThrough: ExecuteOrCreateFeature(typeof(MetaQuestMRFeatureDecorator), tmp_Args); break; default: throw new ArgumentOutOfRangeException(); } tmp_Args.NotificationAct?.Invoke(); } } /// /// Executes or controls a feature based on whether it already exists. /// /// The type of the command to build the feature if it doesn't exist. /// The type of the feature decorator. /// Arguments specifying the operation (Start, Pause, Stop). private void ExecuteOrCreateFeature(Type tmp_AlgorithmType, ARAlgorithmArgs tmp_Args) where T : class, ICommand { IFeatureDecorator tmp_Decorator; if (FeatureHasBeenAlready(tmp_AlgorithmType, out tmp_Decorator)) { switch (tmp_Args.ARAlgorithmOperator) { case ARAlgorithmOperator.StartAlgorithm: tmp_Decorator.StartAlgorithm(); break; case ARAlgorithmOperator.PauseAlgorithm: tmp_Decorator.PauseAlgorithm(); break; case ARAlgorithmOperator.StopAlgorithm: tmp_Decorator.StopAlgorithm(); break; default: throw new ArgumentOutOfRangeException(); } } else { IocContainer.GetIoc.Resolve().Execute(); } } /// /// Checks if a feature decorator has already been registered in the FeatureManager. /// /// The type of the feature decorator. /// The retrieved feature decorator instance. /// True if the feature exists, false otherwise. private bool FeatureHasBeenAlready(Type _algorithmType, out IFeatureDecorator _featureDecorator) { return FeatureManager.TryGetValue(_algorithmType!, out _featureDecorator); } } }