using System;
using System.Runtime.InteropServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
namespace UnityEngine.XR.ARKit
{
///
/// Represents the Objective-C type ARCollaborationData.
///
///
///
/// This struct mirrors the Objective-C type ARCollaborationData. Because it
/// represents a native resource, it must be explicitly disposed when no
/// longer needed.
///
/// ARCollaborationData can be constructed from a byte array, or from
/// .
///
/// This struct is not thread-safe, but it may be constructed and disposed on any thread.
///
///
public struct ARCollaborationData : IDisposable, IEquatable
{
///
/// Constructs an ARCollaborationData from a byte array.
/// Check after construction to ensure was successfully deserialized.
///
/// An array of bytes to convert to .
/// Thrown if is null.
///
public unsafe ARCollaborationData(byte[] bytes)
{
if (bytes == null)
throw new ArgumentNullException(nameof(bytes));
m_NativePtr = ConstructUnchecked(bytes, 0, bytes.Length);
}
///
/// Constructs an ARCollaborationData from a byte array.
/// Check after construction to ensure was successfully deserialized.
///
/// An array of bytes to convert to .
/// The offset into the array from which to start constructing .
/// The number of bytes in to convert to .
/// Thrown if is null.
/// Thrown if is outside the range [0..bytes.Length).
/// Thrown if is outside the range [0..(bytes.Length - offset)].
///
public unsafe ARCollaborationData(byte[] bytes, int offset, int length)
{
if (bytes == null)
throw new ArgumentNullException(nameof(bytes));
if (offset < 0)
throw new ArgumentOutOfRangeException(nameof(offset), offset, $"'{nameof(offset)}' must be greater than or equal to zero.");
if (offset >= bytes.Length)
throw new ArgumentOutOfRangeException(nameof(offset), offset, $"'{nameof(offset)}' must be less than the length of the byte array ({bytes.Length}).");
if (length <= 0)
throw new ArgumentOutOfRangeException(nameof(length), length, $"'{nameof(length)}' must be greater than zero.");
if (length > (bytes.Length - offset))
throw new ArgumentOutOfRangeException(nameof(length), length, $"'{nameof(length)}' is greater than the number of available bytes in the buffer ({bytes.Length - offset})");
m_NativePtr = ConstructUnchecked(bytes, offset, length);
}
///
/// Constructs an ARCollaborationData from a NativeSlice of bytes.
/// Check after construction to ensure was successfully deserialized.
///
/// An array of bytes to convert to .
/// Thrown if does not refer to valid data.
///
public unsafe ARCollaborationData(NativeSlice bytes)
{
void* ptr = bytes.GetUnsafePtr();
if ((ptr == null) || (bytes.Length == 0))
throw new ArgumentException("Invalid NativeSlice", nameof(bytes));
m_NativePtr = ConstructUnchecked(ptr, bytes.Length);
}
///
/// True if the data is valid. The data may be invalid if this object was constructed
/// with an invalid byte array, or if it has been disposed.
///
public bool valid => m_NativePtr != IntPtr.Zero;
///
/// Gets the priority of the collaboration data. Use this to determine how
/// you should send the information to peers in a collaborative session,
/// e.g., reliably vs unreliably.
///
/// Thrown if is false.
public ARCollaborationDataPriority priority
{
get
{
ValidateAndThrow();
return UnityARKit_session_getCollaborationDataPriority(m_NativePtr);
}
}
///
/// Dispose the native ARCollaborationData. will be false after disposal.
/// It is safe to dispose an invalid or already disposed ARCollaborationData.
///
public void Dispose()
{
UnityARKit_CFRelease(m_NativePtr);
m_NativePtr = IntPtr.Zero;
}
///
/// Copies the bytes representing the serialized to a
/// .
/// A common use case would be to send these bytes to another device over a network.
///
/// A container representing the serialized bytes of this .
/// Thrown if is false.
public unsafe SerializedARCollaborationData ToSerialized()
{
ValidateAndThrow();
var nsData = new NSData(UnityARKit_session_serializeCollaborationDataToNSData(m_NativePtr));
return new SerializedARCollaborationData(nsData);
}
///
/// Generates a hash code suitable for use in HashSet and Dictionary.
///
/// A hash of the .
public override int GetHashCode() => m_NativePtr.GetHashCode();
///
/// Compares for equality.
///
/// An object to compare against.
/// true if is an and
/// is also true. Otherwise, false.
public override bool Equals(object obj) => (obj is ARCollaborationData) && Equals((ARCollaborationData)obj);
///
/// Compares for equality.
///
/// The other to compare against.
/// true if the represents the same object.
public bool Equals(ARCollaborationData other) => m_NativePtr == other.m_NativePtr;
///
/// Compares and for equality using .
///
/// The left-hand-side of the comparison.
/// The right-hand-side of the comparison.
/// true if compares equal to , false otherwise.
public static bool operator ==(ARCollaborationData lhs, ARCollaborationData rhs) => lhs.Equals(rhs);
///
/// Compares and for inequality using .
///
/// The left-hand-side of the comparison.
/// The right-hand-side of the comparison.
/// false if compares equal to , true otherwise.
public static bool operator !=(ARCollaborationData lhs, ARCollaborationData rhs) => !lhs.Equals(rhs);
internal ARCollaborationData(IntPtr data) => m_NativePtr = data;
internal ARCollaborationData(NSData data) => m_NativePtr = UnityARKit_session_deserializeCollaborationDataFromNSData(data);
void ValidateAndThrow()
{
if (!valid)
throw new InvalidOperationException("ARCollaborationData has already been disposed.");
}
unsafe static IntPtr ConstructUnchecked(void* bytes, int length)
{
using (var nsData = NSData.CreateWithBytesNoCopy(bytes, length))
{
return UnityARKit_session_deserializeCollaborationDataFromNSData(nsData);
}
}
unsafe static IntPtr ConstructUnchecked(byte[] bytes, int offset, int length)
{
fixed(void* ptr = &bytes[offset])
{
return ConstructUnchecked(ptr, length);
}
}
[DllImport("__Internal")]
static extern void UnityARKit_CFRelease(IntPtr ptr);
[DllImport("__Internal")]
static extern IntPtr UnityARKit_session_deserializeCollaborationDataFromNSData(IntPtr nsData);
[DllImport("__Internal")]
static extern IntPtr UnityARKit_session_serializeCollaborationDataToNSData(IntPtr collaborationData);
[DllImport("__Internal")]
static extern ARCollaborationDataPriority UnityARKit_session_getCollaborationDataPriority(IntPtr collaborationData);
internal IntPtr m_NativePtr;
}
}