Assignment for RMIT Mixed Reality in 2020
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.

172 lines
4.5 KiB

  1. namespace Oculus.Platform
  2. {
  3. using UnityEngine;
  4. using System;
  5. using System.Collections.Generic;
  6. public static class Callback
  7. {
  8. #region Notification Callbacks: Exposed through Oculus.Platform.Platform
  9. internal static void SetNotificationCallback<T>(Message.MessageType type, Message<T>.Callback callback)
  10. {
  11. if (callback == null) {
  12. throw new Exception ("Cannot provide a null notification callback.");
  13. }
  14. notificationCallbacks[type] = new RequestCallback<T>(callback);
  15. if (type == Message.MessageType.Notification_Room_InviteAccepted)
  16. {
  17. FlushRoomInviteNotificationQueue();
  18. }
  19. }
  20. internal static void SetNotificationCallback(Message.MessageType type, Message.Callback callback)
  21. {
  22. if (callback == null) {
  23. throw new Exception ("Cannot provide a null notification callback.");
  24. }
  25. notificationCallbacks[type] = new RequestCallback(callback);
  26. }
  27. #endregion
  28. #region Adding and running request handlers
  29. internal static void AddRequest(Request request)
  30. {
  31. if (request.RequestID == 0)
  32. {
  33. // An early out error happened in the C SDK. Do not add it to the mapping of callbacks
  34. Debug.LogError("An unknown error occurred. Request failed.");
  35. return;
  36. }
  37. requestIDsToRequests[request.RequestID] = request;
  38. }
  39. internal static void RunCallbacks()
  40. {
  41. while (true)
  42. {
  43. var msg = Platform.Message.PopMessage();
  44. if (msg == null)
  45. {
  46. break;
  47. }
  48. HandleMessage(msg);
  49. }
  50. }
  51. internal static void RunLimitedCallbacks(uint limit)
  52. {
  53. for (var i = 0; i < limit; ++i)
  54. {
  55. var msg = Platform.Message.PopMessage();
  56. if (msg == null)
  57. {
  58. break;
  59. }
  60. HandleMessage(msg);
  61. }
  62. }
  63. internal static void OnApplicationQuit()
  64. {
  65. // Clear out all outstanding callbacks
  66. requestIDsToRequests.Clear();
  67. notificationCallbacks.Clear();
  68. }
  69. #endregion
  70. #region Callback Internals
  71. private static Dictionary<ulong, Request> requestIDsToRequests = new Dictionary<ulong, Request>();
  72. private static Dictionary<Message.MessageType, RequestCallback> notificationCallbacks = new Dictionary<Message.MessageType, RequestCallback>();
  73. private static bool hasRegisteredRoomInviteNotificationHandler = false;
  74. private static List<Message> pendingRoomInviteNotifications = new List<Message>();
  75. private static void FlushRoomInviteNotificationQueue() {
  76. hasRegisteredRoomInviteNotificationHandler = true;
  77. foreach (Message msg in pendingRoomInviteNotifications) {
  78. HandleMessage(msg);
  79. }
  80. pendingRoomInviteNotifications.Clear();
  81. }
  82. private class RequestCallback
  83. {
  84. private Message.Callback messageCallback;
  85. public RequestCallback() { }
  86. public RequestCallback(Message.Callback callback)
  87. {
  88. this.messageCallback = callback;
  89. }
  90. public virtual void HandleMessage(Message msg)
  91. {
  92. if (messageCallback != null)
  93. {
  94. messageCallback(msg);
  95. }
  96. }
  97. }
  98. private sealed class RequestCallback<T> : RequestCallback
  99. {
  100. private Message<T>.Callback callback;
  101. public RequestCallback(Message<T>.Callback callback)
  102. {
  103. this.callback = callback;
  104. }
  105. public override void HandleMessage(Message msg)
  106. {
  107. if (callback != null)
  108. {
  109. // We need to queue up GameInvites because the callback runner will be called before a handler has beeen set.
  110. if (!hasRegisteredRoomInviteNotificationHandler && msg.Type == Message.MessageType.Notification_Room_InviteAccepted)
  111. {
  112. pendingRoomInviteNotifications.Add(msg);
  113. return;
  114. }
  115. if (msg is Message<T>)
  116. {
  117. callback((Message<T>)msg);
  118. }
  119. else
  120. {
  121. Debug.LogError("Unable to handle message: " + msg.GetType());
  122. }
  123. }
  124. }
  125. }
  126. internal static void HandleMessage(Message msg)
  127. {
  128. Request request;
  129. if (msg.RequestID != 0 && requestIDsToRequests.TryGetValue(msg.RequestID, out request)) {
  130. try {
  131. request.HandleMessage(msg);
  132. } finally {
  133. requestIDsToRequests.Remove(msg.RequestID);
  134. }
  135. return;
  136. }
  137. RequestCallback callbackHolder;
  138. if (notificationCallbacks.TryGetValue(msg.Type, out callbackHolder))
  139. {
  140. callbackHolder.HandleMessage(msg);
  141. }
  142. }
  143. #endregion
  144. }
  145. }