#if UNITY_OPENXR_1_9_0_OR_NEWER using System; using System.Collections.Generic; namespace UnityEngine.XR.OpenXR.Features.MagicLeapSupport { public partial class MagicLeapPixelSensorFeature { /// /// A class that represents any asynchronous operation that the pixel sensor performs /// internal abstract class PixelSensorAsyncOperation { internal readonly List ProcessedStreams = new(); protected ulong Future; internal PixelSensorNativeFunctions NativeFunctions; internal MagicLeapPixelSensorFeature PixelSensorFeature; internal PixelSensor Sensor; public PixelSensorAsyncOperationResult OperationResult { get; } = new(); protected abstract PixelSensorStatus OperationStartStatus { get; } protected abstract PixelSensorStatus OperationFinishStatus { get; } protected virtual PixelSensorStatus OperationFailedStatus => PixelSensorStatus.Undefined; protected abstract HashSet IncomingValidStatus { get; } public bool DidOperationFinish => OperationResult.DidOperationFinish || OperationResult.DidOperationFail; public void Start(IEnumerable streams) { if (!IncomingValidStatus.Contains(Sensor.Status) && Sensor.Status != OperationFinishStatus) { throw new InvalidOperationException($"{Sensor.SensorType}'s streams does not have the right status (Expected Status: [{string.Join(',',IncomingValidStatus)}]"); } ProcessedStreams.Clear(); ProcessedStreams.AddRange(streams); if (StartOperation()) { Sensor.Status = OperationStartStatus; OperationResult.StartOperation(Sensor.SensorType, OperationStartStatus, ProcessedStreams); } else { Sensor.Status = OperationFailedStatus; OperationResult.OperationFailed(Sensor.SensorType, OperationFailedStatus, ProcessedStreams); } } protected abstract bool StartOperation(); protected abstract bool OperationCompleted(); private void FinishOperation(bool success) { if (success) { OnOperationSucceeded(); OperationResult.FinishOperation(Sensor.SensorType, OperationFinishStatus, ProcessedStreams); } else { OperationResult.OperationFailed(Sensor.SensorType, OperationFailedStatus, ProcessedStreams); } } public void PollOperation() { if (!NativeFunctions.PollFuture(in Future, out var futureState)) { Debug.LogError("Unable to poll future!"); FinishOperation(false); return; } if (futureState != XrFutureState.Ready) { return; } var operationSuccessful = OperationCompleted(); var targetStatus = operationSuccessful ? OperationFinishStatus : OperationFailedStatus; Sensor.Status = targetStatus; Sensor.StreamStatus.SetStatusForStreams(targetStatus, ProcessedStreams); FinishOperation(operationSuccessful); } protected virtual void OnOperationSucceeded() { } } } } #endif