Обрабатывать события в wxWidgets - PullRequest
2 голосов
/ 15 июля 2009

Я создаю игровой движок, используя wxWidgets и OpenGL. Я пытаюсь настроить таймер, чтобы игра могла регулярно обновляться. Я не хочу использовать wxTimer, потому что он, вероятно, недостаточно точен для того, что мне нужно. Я использую время (true) и wxStopWatch:

while (true) {
    stopWatch.Start();
    <handle events> // I need a function for this
    game->OnUpdate();
    game->Refresh();
    if (stopWatch.Time() < 1000 / 60)
        wxMilliSleep(1000 / 60 - stopWatch.Time());
}

Мне нужна функция, которая будет обрабатывать все события wxWidgets, потому что сейчас мое приложение просто зависает.

ОБНОВЛЕНИЕ: это не так. В Windows это немного дёргано, а при тестировании на Mac это было очень вяло. Очевидно, EVT_IDLE не вызывается последовательно в Windows, а тем более на Mac.

ОБНОВЛЕНИЕ 2: На самом деле это в основном так. Это нормально на Mac; Я неправильно понял ответ моего тестера Mac.

Ответы [ 3 ]

1 голос
/ 01 октября 2011

"Вы запрашивали, чтобы события холостого хода генерировались с максимальной скоростью? Вы должны вызвать RequestMore () для события, если нет, вы получите следующее событие простоя только после обработки какого-либо другого события. эта постоянная обработка в режиме ожидания приведет к 100% загрузке ЦП на одно ядро. "

Это работает, у меня есть следующий код в графическом окне: -

BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
    EVT_PAINT  (MyCanvas::OnPaint)
    EVT_IDLE(MyCanvas::OnIdle)
    EVT_MOTION (MyCanvas::OnMouseMove)
END_EVENT_TABLE()

Холст должен обновляться при вызове my_canvas-> Refresh (bClearBackground), а не иначе. Для этого мне нужно было внести изменения, так как программа потребляла половину времени процессора (или 100% от 1 процессора на ядре дуэли).

void MyCanvas::OnIdle(wxIdleEvent &event)
{
    wxPaintEvent unused;
    OnPaint(unused);
    event.RequestMore(false);
}

Если для параметра RequestMore() установлено значение false, приложение будет запрашивать больше только тогда, когда это необходимо, то есть только при вызове Refresh().

1 голос
/ 15 июля 2009

Вместо использования цикла while (true) я использую EVT_IDLE, и он отлично работает.

ОБНОВЛЕНИЕ: это не так. В Windows это немного дёргано, а при тестировании на Mac это было очень вяло. Очевидно, EVT_IDLE не вызывается последовательно в Windows, а тем более на Mac.

ОБНОВЛЕНИЕ 2: На самом деле это в основном так. Это нормально на Mac; Я неправильно понял ответ моего Mac-тестера.

0 голосов
/ 07 августа 2009
  • Запрашивали ли вы генерировать пустые события с максимальной скоростью? Вы должны позвонить RequestMore() на событие, если вы этого не сделаете, вы получите следующее событие простоя только после обработки какого-либо другого события. Обратите внимание, что постоянная обработка в режиме ожидания приведет к 100% загрузке ЦП на одно ядро.
  • Даже если вы запрашиваете больше пустых событий, вы не можете быть уверены, сколько времени потребуется для прибытия следующего. Поэтому для получения плавной анимации вам необходимо рассчитать время, прошедшее с момента последнего события, и соответствующим образом обновить отображение.
...