| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /*******************************************************************************
- Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
- NOTICE:All information contained herein is, and remains the property of
- PICO Technology Co., Ltd. The intellectual and technical concepts
- contained herein are proprietary to PICO Technology Co., Ltd. and may be
- covered by patents, patents in process, and are protected by trade secret or
- copyright law. Dissemination of this information or reproduction of this
- material is strictly forbidden unless prior written permission is obtained from
- PICO Technology Co., Ltd.
- *******************************************************************************/
- using System;
- using System.Collections.Concurrent;
- using UnityEngine;
- namespace Pico.Platform
- {
- public class Looper
- {
- private static readonly ConcurrentDictionary<ulong, Delegate> TaskMap = new ConcurrentDictionary<ulong, Delegate>();
- private static readonly ConcurrentDictionary<MessageType, Delegate> NotifyMap = new ConcurrentDictionary<MessageType, Delegate>();
- public static readonly ConcurrentDictionary<MessageType, MessageParser> MessageParserMap = new ConcurrentDictionary<MessageType, MessageParser>();
- public static void ProcessMessages(uint limit = 0)
- {
- if (limit == 0)
- {
- while (true)
- {
- var msg = PopMessage();
- if (msg == null)
- {
- break;
- }
- dispatchMessage(msg);
- }
- }
- else
- {
- for (var i = 0; i < limit; ++i)
- {
- var msg = PopMessage();
- if (msg == null)
- {
- break;
- }
- dispatchMessage(msg);
- }
- }
- }
- public static Message PopMessage()
- {
- if (!CoreService.Initialized)
- {
- return null;
- }
- var handle = CLIB.ppf_PopMessage();
- if (handle == IntPtr.Zero)
- {
- return null;
- }
- MessageType messageType = CLIB.ppf_Message_GetType(handle);
- Message msg = MessageQueue.ParseMessage(handle);
- if (msg == null)
- {
- if (MessageParserMap.TryGetValue(messageType, out MessageParser parser))
- {
- msg = parser(handle);
- }
- }
- if (msg == null)
- {
- Debug.LogError($"Cannot parse message type {messageType}");
- }
- CLIB.ppf_FreeMessage(handle);
- return msg;
- }
- private static void dispatchMessage(Message msg)
- {
- if (msg.RequestID != 0)
- {
- // handle task
- if (TaskMap.TryGetValue(msg.RequestID, out var handler))
- {
- try
- {
- handler.DynamicInvoke(msg);
- }
- catch (Exception e)
- {
- Debug.LogError($"dispatchMessage failed {e}");
- }
- finally
- {
- TaskMap.TryRemove(msg.RequestID, out handler);
- }
- }
- else
- {
- Debug.LogError($"No handler for task: requestId={msg.RequestID}, msg.Type = {msg.Type}. You should call `OnComplete()` when use request API.");
- }
- }
- else
- {
- // handle notification
- if (NotifyMap.TryGetValue(msg.Type, out var handler))
- {
- handler.DynamicInvoke(msg);
- }
- else
- {
- //Debug.LogError($"No handler for notification: msg.Type = {msg.Type}");
- }
- }
- }
- public static void RegisterTaskHandler(ulong taskId, Delegate handler)
- {
- if (taskId == 0)
- {
- Debug.LogError("The task is invalid.");
- return;
- }
- TaskMap[taskId] = handler;
- }
- public static void RegisterNotifyHandler(MessageType type, Delegate handler)
- {
- if (handler == null)
- {
- Debug.LogError("Cannot register null notification handler.");
- return;
- }
- NotifyMap[type] = handler;
- }
- public static void RegisterMessageParser(MessageType messageType, MessageParser messageParser)
- {
- if (messageParser == null)
- {
- Debug.LogError($"invalid message parser for {messageType}");
- return;
- }
- if (MessageParserMap.ContainsKey(messageType))
- {
- Debug.LogWarning($"Duplicate register of {messageType}");
- }
- MessageParserMap.TryAdd(messageType, messageParser);
- }
- public static void Clear()
- {
- TaskMap.Clear();
- NotifyMap.Clear();
- }
- }
- }
|