#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