Looper.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*******************************************************************************
  2. Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
  3. NOTICE:All information contained herein is, and remains the property of
  4. PICO Technology Co., Ltd. The intellectual and technical concepts
  5. contained herein are proprietary to PICO Technology Co., Ltd. and may be
  6. covered by patents, patents in process, and are protected by trade secret or
  7. copyright law. Dissemination of this information or reproduction of this
  8. material is strictly forbidden unless prior written permission is obtained from
  9. PICO Technology Co., Ltd.
  10. *******************************************************************************/
  11. using System;
  12. using System.Collections.Concurrent;
  13. using UnityEngine;
  14. namespace Pico.Platform
  15. {
  16. public class Looper
  17. {
  18. private static readonly ConcurrentDictionary<ulong, Delegate> TaskMap = new ConcurrentDictionary<ulong, Delegate>();
  19. private static readonly ConcurrentDictionary<MessageType, Delegate> NotifyMap = new ConcurrentDictionary<MessageType, Delegate>();
  20. public static readonly ConcurrentDictionary<MessageType, MessageParser> MessageParserMap = new ConcurrentDictionary<MessageType, MessageParser>();
  21. public static void ProcessMessages(uint limit = 0)
  22. {
  23. if (limit == 0)
  24. {
  25. while (true)
  26. {
  27. var msg = PopMessage();
  28. if (msg == null)
  29. {
  30. break;
  31. }
  32. dispatchMessage(msg);
  33. }
  34. }
  35. else
  36. {
  37. for (var i = 0; i < limit; ++i)
  38. {
  39. var msg = PopMessage();
  40. if (msg == null)
  41. {
  42. break;
  43. }
  44. dispatchMessage(msg);
  45. }
  46. }
  47. }
  48. public static Message PopMessage()
  49. {
  50. if (!CoreService.Initialized)
  51. {
  52. return null;
  53. }
  54. var handle = CLIB.ppf_PopMessage();
  55. if (handle == IntPtr.Zero)
  56. {
  57. return null;
  58. }
  59. MessageType messageType = CLIB.ppf_Message_GetType(handle);
  60. Message msg = MessageQueue.ParseMessage(handle);
  61. if (msg == null)
  62. {
  63. if (MessageParserMap.TryGetValue(messageType, out MessageParser parser))
  64. {
  65. msg = parser(handle);
  66. }
  67. }
  68. if (msg == null)
  69. {
  70. Debug.LogError($"Cannot parse message type {messageType}");
  71. }
  72. CLIB.ppf_FreeMessage(handle);
  73. return msg;
  74. }
  75. private static void dispatchMessage(Message msg)
  76. {
  77. if (msg.RequestID != 0)
  78. {
  79. // handle task
  80. if (TaskMap.TryGetValue(msg.RequestID, out var handler))
  81. {
  82. try
  83. {
  84. handler.DynamicInvoke(msg);
  85. }
  86. catch (Exception e)
  87. {
  88. Debug.LogError($"dispatchMessage failed {e}");
  89. }
  90. finally
  91. {
  92. TaskMap.TryRemove(msg.RequestID, out handler);
  93. }
  94. }
  95. else
  96. {
  97. Debug.LogError($"No handler for task: requestId={msg.RequestID}, msg.Type = {msg.Type}. You should call `OnComplete()` when use request API.");
  98. }
  99. }
  100. else
  101. {
  102. // handle notification
  103. if (NotifyMap.TryGetValue(msg.Type, out var handler))
  104. {
  105. handler.DynamicInvoke(msg);
  106. }
  107. else
  108. {
  109. //Debug.LogError($"No handler for notification: msg.Type = {msg.Type}");
  110. }
  111. }
  112. }
  113. public static void RegisterTaskHandler(ulong taskId, Delegate handler)
  114. {
  115. if (taskId == 0)
  116. {
  117. Debug.LogError("The task is invalid.");
  118. return;
  119. }
  120. TaskMap[taskId] = handler;
  121. }
  122. public static void RegisterNotifyHandler(MessageType type, Delegate handler)
  123. {
  124. if (handler == null)
  125. {
  126. Debug.LogError("Cannot register null notification handler.");
  127. return;
  128. }
  129. NotifyMap[type] = handler;
  130. }
  131. public static void RegisterMessageParser(MessageType messageType, MessageParser messageParser)
  132. {
  133. if (messageParser == null)
  134. {
  135. Debug.LogError($"invalid message parser for {messageType}");
  136. return;
  137. }
  138. if (MessageParserMap.ContainsKey(messageType))
  139. {
  140. Debug.LogWarning($"Duplicate register of {messageType}");
  141. }
  142. MessageParserMap.TryAdd(messageType, messageParser);
  143. }
  144. public static void Clear()
  145. {
  146. TaskMap.Clear();
  147. NotifyMap.Clear();
  148. }
  149. }
  150. }
粤ICP备19079148号