Weird input/event delay with Allegro 5.2.7

  allegro, allegro5, c++

Description:
The problem that I had with Allegro was that there was some kind of weird input delay where all of the events (keyboard, display, etc.) were only processed after a few seconds. I have pinpointed the source of the problem to the main loop since the if statement here actually fixes the problem:

if (al_is_event_queue_empty(eventqueue)) {
    al_flip_display();
    m_gl->update(&this->input);
}

I thought that forcing Allegro to process all the events before updating will solve the problem, and it actually did in the end, but I don’t know what is the source of the actual bug in the first place, which really bothers me. I am using Allegro 5.2.7 with Clang 11.0.3 on macOS Catalina 10.15.6.

Code:

#include "application.hpp"

eng::GameApplication::GameApplication(GameLogic &gl, int w, int h, unsigned int refrate) {
    al_init();
    al_init_image_addon();
    al_install_keyboard();
    al_install_mouse();
    this->window = al_create_display(w, h);
    this->eventqueue = al_create_event_queue();
    if (refrate!=0){
        this->timer = al_create_timer(1.0 / refrate);
    } else {
        this->timer = al_create_timer(1.0 / 60.0);
    }
    
    al_register_event_source(eventqueue, al_get_keyboard_event_source());
    al_register_event_source(eventqueue, al_get_display_event_source(window));
    al_register_event_source(eventqueue, al_get_timer_event_source(timer));
    al_register_event_source(eventqueue, al_get_mouse_event_source());
    
    memset(input.keystates, 0, sizeof(input.keystates));
    this->isRunning = true;
    this->m_gl = ≷
    this->m_gl->init();
    
    al_start_timer(timer);
}

eng::GameApplication::~GameApplication() {
    m_gl->exit();
    al_destroy_display(window);
    al_stop_timer(timer);
    al_destroy_timer(timer);
    al_destroy_event_queue(eventqueue);
    al_uninstall_keyboard();
}

void eng::GameApplication::run() { // Main Loop
    while(this->isRunning) {
        ALLEGRO_EVENT event;
        al_wait_for_event(this->eventqueue, &event);
        switch (event.type) {
                // Keyboard events
            case ALLEGRO_EVENT_KEY_DOWN:
                input.keystates[event.keyboard.keycode] = eng::keystate::pressed;
                break;
            case ALLEGRO_EVENT_KEY_UP:
                input.keystates[event.keyboard.keycode] = eng::keystate::unpressed;
                break;
                // Mouse events
            case ALLEGRO_EVENT_MOUSE_AXES:
                input.mousex = event.mouse.x;
                input.mousey = event.mouse.y;
                break;
            case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
                input.mousex = event.mouse.x;
                input.mousey = event.mouse.y;
                break;
            case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
                input.mousex = event.mouse.x;
                input.mousey = event.mouse.y;
                break;
                // Window events
            case ALLEGRO_EVENT_DISPLAY_CLOSE:
                this->isRunning = false;
                break;
            case ALLEGRO_EVENT_TIMER:
                if (al_is_event_queue_empty(eventqueue)) { // THE PROBLEM
                    al_flip_display();
                    m_gl->update(&this->input);
                }
                break;
        }
    }
}

Full Code: https://github.com/return0jz/allegro

Source: Windows Questions C++

LEAVE A COMMENT