SW 중심대학 OSS GIT 서버 박건태, 이승준, 고기완, 이준호 새로운 배포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
10 KiB

4 years ago
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using Unity.Collections;
  4. using Unity.Collections.LowLevel.Unsafe;
  5. namespace UnityEngine.XR.ARKit
  6. {
  7. /// <summary>
  8. /// Represents the Objective-C type ARCollaborationData.
  9. /// </summary>
  10. /// <remarks>
  11. /// <para>
  12. /// This struct mirrors the Objective-C type ARCollaborationData. Because it
  13. /// represents a native resource, it must be explicitly disposed when no
  14. /// longer needed.
  15. /// </para><para>
  16. /// ARCollaborationData can be constructed from a byte array, or from
  17. /// <see cref="ARKitSessionSubsystem.DequeueCollaborationData"/>.
  18. /// </para><para>
  19. /// This struct is not thread-safe, but it may be constructed and disposed on any thread.
  20. /// </para>
  21. /// </remarks>
  22. public struct ARCollaborationData : IDisposable, IEquatable<ARCollaborationData>
  23. {
  24. /// <summary>
  25. /// Constructs an ARCollaborationData from a byte array.
  26. /// Check <see cref="valid"/> after construction to ensure <paramref name="bytes"/> was successfully deserialized.
  27. /// </summary>
  28. /// <param name="bytes">An array of <c>byte</c>s to convert to <see cref="ARCollaborationData"/>.</param>
  29. /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="bytes"/> is null.</exception>
  30. /// <seealso cref="ToSerialized"/>
  31. public unsafe ARCollaborationData(byte[] bytes)
  32. {
  33. if (bytes == null)
  34. throw new ArgumentNullException(nameof(bytes));
  35. m_NativePtr = ConstructUnchecked(bytes, 0, bytes.Length);
  36. }
  37. /// <summary>
  38. /// Constructs an ARCollaborationData from a byte array.
  39. /// Check <see cref="valid"/> after construction to ensure <paramref name="bytes"/> was successfully deserialized.
  40. /// </summary>
  41. /// <param name="bytes">An array of <c>byte</c>s to convert to <see cref="ARCollaborationData"/>.</param>
  42. /// <param name="offset">The offset into the <paramref name="bytes"/> array from which to start constructing <see cref="ARCollaborationData"/>.</param>
  43. /// <param name="length">The number of bytes in <paramref name="bytes"/> to convert to <see cref="ARCollaborationData"/>.</param>
  44. /// <exception cref="System.ArgumentNullException">Thrown if <paramref name="bytes"/> is null.</exception>
  45. /// <exception cref="System.ArgumentOutOfRangeException">Thrown if <paramref name="offset"/> is outside the range [0..bytes.Length).</exception>
  46. /// <exception cref="System.ArgumentOutOfRangeException">Thrown if <paramref name="length"/> is outside the range [0..(bytes.Length - offset)].</exception>
  47. /// <seealso cref="ToSerialized"/>
  48. public unsafe ARCollaborationData(byte[] bytes, int offset, int length)
  49. {
  50. if (bytes == null)
  51. throw new ArgumentNullException(nameof(bytes));
  52. if (offset < 0)
  53. throw new ArgumentOutOfRangeException(nameof(offset), offset, $"'{nameof(offset)}' must be greater than or equal to zero.");
  54. if (offset >= bytes.Length)
  55. throw new ArgumentOutOfRangeException(nameof(offset), offset, $"'{nameof(offset)}' must be less than the length of the byte array ({bytes.Length}).");
  56. if (length <= 0)
  57. throw new ArgumentOutOfRangeException(nameof(length), length, $"'{nameof(length)}' must be greater than zero.");
  58. if (length > (bytes.Length - offset))
  59. throw new ArgumentOutOfRangeException(nameof(length), length, $"'{nameof(length)}' is greater than the number of available bytes in the buffer ({bytes.Length - offset})");
  60. m_NativePtr = ConstructUnchecked(bytes, offset, length);
  61. }
  62. /// <summary>
  63. /// Constructs an ARCollaborationData from a <c>NativeSlice</c> of <c>byte</c>s.
  64. /// Check <see cref="valid"/> after construction to ensure <paramref name="bytes"/> was successfully deserialized.
  65. /// </summary>
  66. /// <param name="bytes">An array of <c>byte</c>s to convert to <see cref="ARCollaborationData"/>.</param>
  67. /// <exception cref="System.ArgumentException">Thrown if <paramref name="bytes"/> does not refer to valid data.</exception>
  68. /// <seealso cref="ToSerialized"/>
  69. public unsafe ARCollaborationData(NativeSlice<byte> bytes)
  70. {
  71. void* ptr = bytes.GetUnsafePtr();
  72. if ((ptr == null) || (bytes.Length == 0))
  73. throw new ArgumentException("Invalid NativeSlice", nameof(bytes));
  74. m_NativePtr = ConstructUnchecked(ptr, bytes.Length);
  75. }
  76. /// <summary>
  77. /// True if the data is valid. The data may be invalid if this object was constructed
  78. /// with an invalid byte array, or if it has been disposed.
  79. /// </summary>
  80. public bool valid => m_NativePtr != IntPtr.Zero;
  81. /// <summary>
  82. /// Gets the priority of the collaboration data. Use this to determine how
  83. /// you should send the information to peers in a collaborative session,
  84. /// e.g., reliably vs unreliably.
  85. /// </summary>
  86. /// <exception cref="System.InvalidOperationException">Thrown if <see cref="valid"/> is false.</exception>
  87. public ARCollaborationDataPriority priority
  88. {
  89. get
  90. {
  91. ValidateAndThrow();
  92. return UnityARKit_session_getCollaborationDataPriority(m_NativePtr);
  93. }
  94. }
  95. /// <summary>
  96. /// Dispose the native ARCollaborationData. <see cref="valid"/> will be false after disposal.
  97. /// It is safe to dispose an invalid or already disposed ARCollaborationData.
  98. /// </summary>
  99. public void Dispose()
  100. {
  101. UnityARKit_CFRelease(m_NativePtr);
  102. m_NativePtr = IntPtr.Zero;
  103. }
  104. /// <summary>
  105. /// Copies the bytes representing the serialized <see cref="ARCollaborationData"/> to a
  106. /// <see cref="SerializedARCollaborationData"/>.
  107. /// A common use case would be to send these bytes to another device over a network.
  108. /// </summary>
  109. /// <returns>A container representing the serialized bytes of this <see cref="ARCollaborationData"/>.</returns>
  110. /// <exception cref="System.InvalidOperationException">Thrown if <see cref="valid"/> is false.</exception>
  111. public unsafe SerializedARCollaborationData ToSerialized()
  112. {
  113. ValidateAndThrow();
  114. var nsData = new NSData(UnityARKit_session_serializeCollaborationDataToNSData(m_NativePtr));
  115. return new SerializedARCollaborationData(nsData);
  116. }
  117. /// <summary>
  118. /// Generates a hash code suitable for use in <c>HashSet</c> and <c>Dictionary</c>.
  119. /// </summary>
  120. /// <returns>A hash of the <see cref="ARCollaborationData"/>.</returns>
  121. public override int GetHashCode() => m_NativePtr.GetHashCode();
  122. /// <summary>
  123. /// Compares for equality.
  124. /// </summary>
  125. /// <param name="obj">An <c>object</c> to compare against.</param>
  126. /// <returns><c>true</c> if <paramref name="obj"/> is an <see cref="ARCollaborationData"/> and
  127. /// <see cref="Equals(ARCollaborationData)"/> is also <c>true</c>. Otherwise, <c>false</c>.</returns>
  128. public override bool Equals(object obj) => (obj is ARCollaborationData) && Equals((ARCollaborationData)obj);
  129. /// <summary>
  130. /// Compares for equality.
  131. /// </summary>
  132. /// <param name="other">The other <see cref="ARCollaborationData"/> to compare against.</param>
  133. /// <returns><c>true</c> if the <see cref="ARCollaborationData"/> represents the same object.</returns>
  134. public bool Equals(ARCollaborationData other) => m_NativePtr == other.m_NativePtr;
  135. /// <summary>
  136. /// Compares <paramref name="lhs"/> and <paramref name="rhs"/> for equality using <see cref="Equals(ARCollaborationData)"/>.
  137. /// </summary>
  138. /// <param name="lhs">The left-hand-side <see cref="ARCollaborationData"/> of the comparison.</param>
  139. /// <param name="rhs">The right-hand-side <see cref="ARCollaborationData"/> of the comparison.</param>
  140. /// <returns><c>true</c> if <paramref name="lhs"/> compares equal to <paramref name="rhs"/>, <c>false</c> otherwise.</returns>
  141. public static bool operator ==(ARCollaborationData lhs, ARCollaborationData rhs) => lhs.Equals(rhs);
  142. /// <summary>
  143. /// Compares <paramref name="lhs"/> and <paramref name="rhs"/> for inequality using <see cref="Equals(ARCollaborationData)"/>.
  144. /// </summary>
  145. /// <param name="lhs">The left-hand-side <see cref="ARCollaborationData"/> of the comparison.</param>
  146. /// <param name="rhs">The right-hand-side <see cref="ARCollaborationData"/> of the comparison.</param>
  147. /// <returns><c>false</c> if <paramref name="lhs"/> compares equal to <paramref name="rhs"/>, <c>true</c> otherwise.</returns>
  148. public static bool operator !=(ARCollaborationData lhs, ARCollaborationData rhs) => !lhs.Equals(rhs);
  149. internal ARCollaborationData(IntPtr data) => m_NativePtr = data;
  150. internal ARCollaborationData(NSData data) => m_NativePtr = UnityARKit_session_deserializeCollaborationDataFromNSData(data);
  151. void ValidateAndThrow()
  152. {
  153. if (!valid)
  154. throw new InvalidOperationException("ARCollaborationData has already been disposed.");
  155. }
  156. unsafe static IntPtr ConstructUnchecked(void* bytes, int length)
  157. {
  158. using (var nsData = NSData.CreateWithBytesNoCopy(bytes, length))
  159. {
  160. return UnityARKit_session_deserializeCollaborationDataFromNSData(nsData);
  161. }
  162. }
  163. unsafe static IntPtr ConstructUnchecked(byte[] bytes, int offset, int length)
  164. {
  165. fixed(void* ptr = &bytes[offset])
  166. {
  167. return ConstructUnchecked(ptr, length);
  168. }
  169. }
  170. [DllImport("__Internal")]
  171. static extern void UnityARKit_CFRelease(IntPtr ptr);
  172. [DllImport("__Internal")]
  173. static extern IntPtr UnityARKit_session_deserializeCollaborationDataFromNSData(IntPtr nsData);
  174. [DllImport("__Internal")]
  175. static extern IntPtr UnityARKit_session_serializeCollaborationDataToNSData(IntPtr collaborationData);
  176. [DllImport("__Internal")]
  177. static extern ARCollaborationDataPriority UnityARKit_session_getCollaborationDataPriority(IntPtr collaborationData);
  178. internal IntPtr m_NativePtr;
  179. }
  180. }