| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using AOT;
- using UnityEngine;
- using UnityEngine.Events;
- using System.Threading;
- namespace MySerialPortInterface
- {
- [System.Serializable]
- public class SerialPortSystemEventObject : UnityEngine.Events.UnityEvent<SerialPortInterface, string> { }
- public class SerialPortInterface : MonoBehaviour
- {
- private const string SERIALPORTAPI = "com/example/serialport/serialport_api";
- //java对象
- private AndroidJavaObject serialPortApiObj = null;
- public string ComPort = "/dev/ttyS0";
- public int BaudRate = 115200;
- public string DeviceName = "ttyS0";
- int serialPortId = -1;
- // 使用 UnityEvent 使事件公开在 Inspector 中
- [System.Serializable]
- public class SerialPortUpdateEvent : UnityEvent<byte[], int> { }
- [HideInInspector]
- public SerialPortSystemEventObject SystemEventObject = new SerialPortSystemEventObject();
- // 在 Inspector 中可以赋值的事件
- public SerialPortUpdateEvent OnSerialPortUpdateEvent;
- private SynchronizationContext _syncContext;
- void Awake()
- {
- // 获取主线程的 SynchronizationContext
- _syncContext = SynchronizationContext.Current;
- try
- {
- // 创建 serialPortApi 对象
- serialPortApiObj = new AndroidJavaObject(SERIALPORTAPI);
- }
- catch (Exception e)
- {
- Debug.LogError("UVC_MANAGER Exception: " + e.Message);
- }
- }
- void Start()
- {
- //初始化端口
- //Open();
- }
- public void Open()
- {
- //如果已经注册过了
- if (serialPortId != -1) return;
- serialPortId = serialPortApiObj.Call<int>("initSerialPort", ComPort, BaudRate);
- if (serialPortId != -1)
- {
- Debug.Log("initSerialPort 初始化成功!");
- if (SystemEventObject != null)
- SystemEventObject.Invoke(this, "OPENED");
- //注册c回调
- Add(this);
- }
- else
- {
- Debug.LogError("initSerialPort 初始化失败!");
- if (SystemEventObject != null)
- SystemEventObject.Invoke(this, "OPEN_ERROR");
- }
-
- //SendTest();
- }
- private void OnDestroy()
- {
- if (Application.platform == RuntimePlatform.Android) {
- Remove(this);
- Close();
- }
-
- }
- public void SendTest()
- {
- serialPortApiObj.Call("SendTest");
- }
- public void Close()
- {
- serialPortApiObj.Call("closeSerialPort");
- if (SystemEventObject != null)
- SystemEventObject.Invoke(this, "CLOSED");
- serialPortId = -1;
- }
- public void Write(byte[] data)
- {
- //
- // Debug.Log("Unity调用Android的sendSerialPort方法");
- sbyte[] mySByte = new sbyte[data.Length];
- for (int i = 0; i < data.Length; i++)
- {
- if (data[i] > 127)
- mySByte[i] = (sbyte)(data[i] - 256);
- else
- mySByte[i] = (sbyte)data[i];
- }
- serialPortApiObj.Call("sendSerialPort", new object[] { mySByte, data.Length });
- Debug.Log($"[SerialPortInterface]Write:{ComPort}, data: {BitConverter.ToString(data)},length: {data.Length}");
- }
- public void OnSerialPortUpdate(byte[] buffer, int size)
- {
- // 处理数据
- Debug.Log($"[SerialPortInterface]回调:{ComPort}, data: {BitConverter.ToString(buffer)},length: {buffer.Length} ,size: {size}");
- // 触发事件
- OnSerialPortUpdateEvent?.Invoke(buffer, size);
- }
- [UnmanagedFunctionPointer(CallingConvention.StdCall)]
- public delegate void SerialPortUpdateDelegate(Int32 id, IntPtr buffer, int size);
- [DllImport("SerialPortCustom")]
- private static extern void RegisterSerialPortUpdateCallback(Int32 id, SerialPortUpdateDelegate callback);
- [DllImport("SerialPortCustom")]
- private static extern void UnregisterSerialPortUpdateCallback(Int32 id, SerialPortUpdateDelegate callback);
- //记录MyUVCInterface
- private static Dictionary<Int32, SerialPortInterface> mSerialPortInterfaces = new Dictionary<Int32, SerialPortInterface>();
- private static SerialPortUpdateDelegate serialPortUpdateDelegate;
- //注册回调事件
- public static void Add(SerialPortInterface mySerialPortInterface)
- {
- Int32 id = mySerialPortInterface.serialPortId;
- serialPortUpdateDelegate = new SerialPortUpdateDelegate(SerialPortUpdateHandler);
- mSerialPortInterfaces.Add(id, mySerialPortInterface);
- RegisterSerialPortUpdateCallback(id, serialPortUpdateDelegate);
- }
- //移除回调事件
- public static void Remove(SerialPortInterface mySerialPortInterface)
- {
- Int32 id = mySerialPortInterface.GetHashCode();
- UnregisterSerialPortUpdateCallback(id, serialPortUpdateDelegate);
- mSerialPortInterfaces.Remove(id);
- }
- //数据更新时候回调
- [MonoPInvokeCallback(typeof(SerialPortUpdateDelegate))]
- // 修改回调处理
- private static void SerialPortUpdateHandler(Int32 id, IntPtr buffer, int size)
- {
- byte[] managedBuffer = new byte[size];
- Marshal.Copy(buffer, managedBuffer, 0, size);
- // Debug.Log($"Received buffer in C#: {BitConverter.ToString(managedBuffer)}, size: {size}, buffer.Length: {managedBuffer.Length}");
- var mySerialPortInterface = mSerialPortInterfaces.ContainsKey(id) ? mSerialPortInterfaces[id] : null;
- // 使用 SynchronizationContext 将操作调度到主线程
- mySerialPortInterface?.EnqueueOnMainThread(() => mySerialPortInterface.OnSerialPortUpdate(managedBuffer, size));
- }
- // 调度操作到主线程
- public void EnqueueOnMainThread(Action action)
- {
- // 如果 _syncContext 为 null,可能是没有正确初始化,可以检查并加以处理
- if (_syncContext != null)
- {
- _syncContext.Post(_ => action(), null);
- }
- else
- {
- // 如果找不到 SynchronizationContext,使用 Unity 的主线程调度
- UnityMainThreadDispatcher.Instance().Enqueue(action);
- }
- }
- }
- }
|