Я разрабатываю плагин Unity, который использует BLE для связи с каким-либо устройством.У меня есть реализация как для Windows (использующая P / Invoke для SDK этого устройства), так и для Android, которая использует вспомогательные классы Unity для взаимодействия с JVM.SDK устройства в Java имеет обратный вызов для входящих новых данных, обратный вызов выглядит следующим образом:
@Override
public void onDeviceData(BluetoothDevice device, byte[] data) {
}
Я реализовал класс, который наследует AndroidJavaProxy
Unity для регистрации обработчика обратного вызова со стороны C #:
class Callbacks : AndroidJavaProxy
{
ConcurrentQueue<byte[]> IncomingMessages { get; private set; }
public Callbacks()
: base("com.example.sdk.SdkCallbacks")
{
IncomingMessages = new ConcurrentQueue<byte[]>();
}
void onDeviceData(AndroidJavaObject device, byte[] data)
{
IncomingMessages.Enqueue(data);
}
}
У меня есть сценарий в сцене, который запрашивает эти данные в функции Update()
следующим образом:
while (!_device.IncomingMessages.IsEmpty)
{
byte[] data;
if (_device.IncomingMessages.TryDequeue(out data))
{
// do something with the data
}
}
В моем конкретном случае я использую данные, поступающие изустройство для перемещения точки на экране (например, «беспроводная мышь»).
Это работает довольно хорошо, пока мне не нужно получать высокоскоростные данные с устройства (около ~ 60 обратных вызовов в секунду с помощью data
параметр, содержащий массив ~ 30 байт).Сначала все выглядит хорошо, но через несколько секунд точка начинает сильно отставать от фактического ввода с устройства, и отставание только увеличивается со временем.
Я пытался проверить, если IncomingMessages
очередь становится слишком большой, что означает, что производитель намного опережает потребителя, вызывая постоянно увеличивающуюся задержку, но это не имело место, IncomingMessages.Count
всегда показывает 0-2.
Этого не происходитпри запуске кода в Windows и использовании SDK устройства из обычного приложения для Android также хорошо работает.
Может ли это быть чрезмерной нагрузкой между JNI и CLR?Или что-то подобное?
Если так, могу ли я что-нибудь с этим сделать?Я знаю, что у Unity есть другой способ связи между native и средой выполнения сценариев с UnitySendMessage
, но я не уверен, что у него не будет такой же проблемы.