using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.SceneManagement; namespace FlutterUnityIntegration { public class MessageHandler { public int id; public string seq; public String name; private readonly JToken data; public static MessageHandler Deserialize(string message) { var m = JObject.Parse(message); var handler = new MessageHandler( m.GetValue("id").Value(), m.GetValue("seq").Value(), m.GetValue("name").Value(), m.GetValue("data") ); return handler; } public T getData() { return data.Value(); } public MessageHandler(int id, string seq, string name, JToken data) { this.id = id; this.seq = seq; this.name = name; this.data = data; } public void send(object data) { var o = JObject.FromObject(new { id = id, seq = "end", name = name, data = data }); UnityMessageManager.Instance.SendMessageToFlutter(UnityMessageManager.MessagePrefix + o.ToString()); } } public class UnityMessage { public String name; public JObject data; public Action callBack; } public class UnityMessageManager : SingletonMonoBehaviour { public const string MessagePrefix = "@UnityMessage@"; private static int ID = 0; private static int generateId() { ID = ID + 1; return ID; } public delegate void MessageDelegate(string message); public event MessageDelegate OnMessage; public delegate void MessageHandlerDelegate(MessageHandler handler); public event MessageHandlerDelegate OnFlutterMessage; private readonly Dictionary waitCallbackMessageMap = new Dictionary(); private void Start() { SceneManager.sceneLoaded += OnSceneLoaded; } void OnSceneLoaded(Scene scene, LoadSceneMode mode) { NativeAPI.OnSceneLoaded(scene, mode); } public void ShowHostMainWindow() { NativeAPI.ShowHostMainWindow(); } public void UnloadMainWindow() { NativeAPI.UnloadMainWindow(); } public void QuitUnityWindow() { NativeAPI.QuitUnityWindow(); } public void SendMessageToFlutter(string message) { NativeAPI.SendMessageToFlutter(message); } public void SendMessageToFlutter(UnityMessage message) { var id = generateId(); if (message.callBack != null) { waitCallbackMessageMap.Add(id, message); } var o = JObject.FromObject(new { id = id, seq = message.callBack != null ? "start" : "", name = message.name, data = message.data }); UnityMessageManager.Instance.SendMessageToFlutter(MessagePrefix + o.ToString()); } void onMessage(string message) { OnMessage?.Invoke(message); } void onFlutterMessage(string message) { if (message.StartsWith(MessagePrefix)) { message = message.Replace(MessagePrefix, ""); } else { return; } var handler = MessageHandler.Deserialize(message); if ("end".Equals(handler.seq)) { // handle callback message if (!waitCallbackMessageMap.TryGetValue(handler.id, out var m)) return; waitCallbackMessageMap.Remove(handler.id); m.callBack?.Invoke(handler.getData()); // todo return; } OnFlutterMessage?.Invoke(handler); } } }