Обратный вызов запроса никогда не вызывается, когда я ставлю std :: this_thread :: sleep_for (1)

Я пытаюсь предотвратить вход в сцену, если некоторые вещи с сервера не загружены, у меня есть флаг bool

    done = false;
CCHttpRequest *pRequest;
// initialization ....
pRequest->setResponseCallback(this, httpresponse_selector(SceneController::on_response));

CCHttpClient::getInstance()->send(pRequest);
pRequest->release();

while(!done) {
std::chrono::milliseconds duration(1);
std::this_thread::sleep_for(duration);
}

в функции обратного вызова on_response Я поставил

done = true;

что должно (но не работает) выйти из бесконечного цикла.
Проблема этого подхода заключается в том, что обратный вызов никогда не вызывается (точка останова на первой строке обратного вызова никогда не достигается). Когда я комментирую while loop это называется обратным вызовом.

Кто-нибудь знает, в чем проблема и как предотвратить дальнейшее выполнение, пока я не получу данные с сервера?

Callstack, когда он работает на точке останова внутри callback

введите описание изображения здесь

0

Решение

Обратный вызов — это НЕ другая нить, как вы думаете. Вы пытаетесь удержать текущее выполнение функции ‘пока обратный вызов не будет вызван’. Это не правильно. Вы должны вернуться из него и разрешить обратный вызов. Это должно сделать:

done = false;
CCHttpRequest *pRequest;
// initialization ....
pRequest->setResponseCallback(this, httpresponse_selector(SceneController::on_response));
CCHttpClient::getInstance()->send(pRequest);
pRequest->release();

if (!done)
{
return;
}
else
{
// Do here whatever you want to do after callback changes flag
}
0

Другие решения

Весь ваш код будет выполняться в потоке Cocos, CCHttpRequest имеет свой собственный поток для извлечения данных с сервера, а затем, когда все данные были извлечены, обратный вызов, который вы зарегистрировали ранее, также будет вызываться в потоке Cocos.

После регистрации обратного вызова поток Cocos продолжает выполняться на ваш while, теперь обратный вызов не вызывается (данные не завершены) ваш while будет работать вечно Когда данные завершены, необходимо выполнить обратный вызов в потоке Cocos, но вы видите while продолжайте блокировать это.

В асинхронном мире (посмотреть здесь, и здесь, вы должны понимать async), вы не можете «предотвратить дальнейшее выполнение, пока не получите данные с сервера» по шаблону, который вы используете. Попытайтесь предотвратить это своими done Переменная в местах, которые вы хотите, не будет выполнена.

Например:

done = false;
CCHttpRequest *pRequest;
// initialization ....
pRequest->setResponseCallback(this, httpresponse_selector(SceneController::on_response));

CCHttpClient::getInstance()->send(pRequest);
pRequest->release();

и затем в любом случае вы не хотите, чтобы пользователь взаимодействовал с вашим игровым интерфейсом, как в Touch:

void onTouchBegan(Event *pEvent, Touch *pTouch)
{
if (!done)
{
return false;
}

// code when `done == true`
}

void onTouchEnded(Event *pEvent, Touch *pTouch)
{
// Code here will not be executed if `onTouchBegan` return `false`
}

всякий раз, когда onTouchBegan верните false, сенсорный код больше не будет выполняться, и пользователь не сможет взаимодействовать с игровым элементом.
Также, чтобы предотвратить нажатие кнопок в меню, отключите родительский контейнер меню: menu->setEnabled(false) затем вернитесь к активному, когда загрузка завершена.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector