Как обрабатывать JNI, аппаратное прерывание в cocos2dx
Я сталкиваюсь с большим количеством сбоев, когда пытаюсь добавить addChild, removeChild внутри аппаратных прерываний или обратного вызова JAVA.
В моей игре есть программная кнопка для вызова java, чтобы использовать распознавание голоса.
Контекст:
C++: btnRecord pressed -> JAVA: startVoiceRecognition -> C++: return;
JAVA: hasResult -> C++: resultHandler -> C++: addchild, removechild, etc.-> crashed randomly.
Я понял, что он разбился из-за того, что пытался изменить данные игры, когда кокосы делают то же самое, в той же области.
Пример: когда cocos выполняет рендеринг layerA, JAVA также пытался удалить layerA -> crash.
Есть ли у кокосов какое-то решение для этого контекста?
Может быть очередь обратного вызова, которая будет обработана в следующем игровом цикле?
Я думаю, что необходимость изменить сцену рисования, когда вы нажимаете какую-то жесткую кнопку: клавишу возврата, клавишу громкости или любое событие аппаратного прерывания, очень необходима.
1 ответ
Да, наконец-то я решил это дерьмо
Обратный вызов JNI выполняется в отдельном потоке. Это означает, что когда JNI выполняет обратный вызов, он не может блокировать основной поток Cocos.
Я боялся, что обратный вызов JNI заблокирует основной поток Cocos. Я должен сначала проверить это:(
Хорошо! Чтобы решить эту проблему, просто используйте std::mutex
а также scheduleOnce
,
как это:
void MyGame::update(float dt)
{
jniMutex.unlock();
// do something
jniMutex.lock();
}
JNI callback()
{
jniMutex.lock();
// scheduleOnce something
jniMutex.unlock();
}
Я хочу убедиться, что обратный вызов JNI работает внутри MyGame::update(float)
поэтому и звоню unlock()
с самого начала, и позвоните lock()
в конце.
Кроме того, мы должны использовать scheduleOnce
вместо того, чтобы пытаться изменить структуру узла непосредственно внутри функции обновления.