2015-01-30 3 views
0

Я пытаюсь предотвратить ввод в сцене, если некоторые вещи с сервера не загружаются, у меня есть флаг BOOLОтветный запроса никогда не вызывается, когда я ставлю станд :: this_thread :: sleep_for (1)

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; 

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

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

CallStack, когда он работает на точке останова внутри обратного вызова

enter image description here

+0

Это может помочь также показать код 'on_response', чтобы мы могли видеть, что там происходит. – Incubbus

+0

@Incubbus Ничего, кроме того, что я сделал done = true; и это не сработает. –

ответ

0

обратного вызова не другой поток, как вы могли бы подумать. Вы пытаетесь выполнить текущее выполнение функции 'до вызова обратного вызова'. Это неправильно. Вы должны вернуться от него и разрешить вызов callback. Это должно сделать:

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

Это не работает, я пытался, когда я поставил точки останова в обоих ветвях, если и еще, и в обратном вызове сначала достигается, если и тогда в обратном вызове, например, вызов асинхронный или запланированный, он не блокирует. –

+0

В вашем исходном вопросе обратный вызов так и не был достигнут.Теперь ваш callback вызван. Это верно? Возможно, вам нужно будет вызвать эту функцию в цикле, которая запускается в таймере, чтобы выполнить часть else (после того, как установлен флаг обратного вызова) – Atul

0

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

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

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

Например:

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

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

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

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 возвращают ложь, не более кода, а затем не позволит вашему пользователю взаимодействовать с элементом игры. Кроме того, чтобы не нажимать кнопки меню, установите флажок в свой родительский контейнер меню: menu->setEnabled(false), а затем верните его, если он включен.

+0

Спасибо за ответ, вы знаете, какой шаблон я могу использовать, или ссылку на любой учебник, если у вас была схожая проблема. –

+0

Я не совсем то, что вам нужно, поэтому этот пример, возможно, не ваш случай, но он будет охватывать некоторые. См. Мое редактирование. –

 Смежные вопросы

  • Нет связанных вопросов^_^