Как обрабатывать 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 вместо того, чтобы пытаться изменить структуру узла непосредственно внутри функции обновления.

Другие вопросы по тегам