Event processing
J-Gamer

I'm currently trying to make a simulation with a few variables that I should be able to change while the program is running. To do that, I made a slider class that can be controlled trough the mouse, whereas my character is controlled trough the arrow keys. Here's some code(cut out the non-important stuff):

#SelectExpand
1while(!quit) 2{ 3 al_wait_for_event(e_queue,&ev); 4 switch(ev.type) 5 { 6 case ALLEGRO_EVENT_DISPLAY_CLOSE: 7 quit = true; 8 break; 9 case ALLEGRO_EVENT_KEY_UP: 10 case ALLEGRO_EVENT_KEY_DOWN: 11 if(ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) quit = true; 12 else 13 { 14 player.update(ev); 15 redraw = true; 16 } 17 break; 18 case ALLEGRO_EVENT_MOUSE_AXES: 19 case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: 20 case ALLEGRO_EVENT_MOUSE_BUTTON_UP: 21 slider.update(ev); 22 redraw = true; 23 break; 24 } 25 if(redraw) 26 { 27 //clear screen, draw player, draw slider, set redraw to false 28 } 29}

Now the problem I'm having is that this LAGS... When I move the mouse and then press a key, my player starts to move two/three seconds later :o
Any ideas?

kazzmir

You should probably process all existing events before doing a redraw, probably using al_peek_next_event

J-Gamer

I thought I'd seen this on the wiki... I'm a dumb ass...
Added this:
if(redraw && al_event_queue_is_empty(event_queue))
And it worked like a charm ^^

kazzmir

I wonder if a better model is to make a new event source that comes from a timer so you redraw only when a new tick comes by.

In your current model if there are a billion events in the queue you won't see the screen updated for a while.

Elias

Well, processing a billion events hopefully takes little time compared to doing game logic and redrawing so it should be fine.

J-Gamer

I haven't put it in my example, but I already have a timer to have the player update its position... I would want another timer for the drawing, but I don't know how to distinguish between them... there's only one ALLEGRO_EVENT_TIMER

AMCerasoli

You need to use timer.source (ALLEGRO_TIMER *)

no wait... let me think, I already did that, but I can't remember it .. dammit!

Evert
J-Gamer said:

I don't know how to distinguish between them...

Use the source field from the ALLEGRO_EVENT struct.

AMCerasoli

Now I can remember, this is what I did:

#SelectExpand
1#include <stdio.h> 2#include <allegro5/allegro.h> 3 4 5int main(int argc, char **argv) 6{ 7 ALLEGRO_DISPLAY *display = NULL; 8 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 9 ALLEGRO_EVENT ev; 10 ALLEGRO_TIMER *FPS = NULL; //Frames 11 ALLEGRO_TIMER *LPS = NULL; //Logic 12 bool redraw = true; 13 14 if(!al_init()) { 15 fprintf(stderr, "failed to initialize allegro!\n"); 16 return -1; 17 } 18 19 FPS = al_create_timer(1.0 / 30); 20 LPS = al_create_timer(1.0 / 60); 21 22 display = al_create_display(640, 480); 23 24 event_queue = al_create_event_queue(); 25 26 al_register_event_source(event_queue, al_get_display_event_source(display)); 27 28 al_register_event_source(event_queue, al_get_timer_event_source(FPS)); 29 30 al_register_event_source(event_queue, al_get_timer_event_source(LPS)); 31 32 al_clear_to_color(al_map_rgb(0,0,0)); 33 34 al_flip_display(); 35 36 al_start_timer(FPS); 37 al_start_timer(LPS); 38 39 while(1) 40 { 41 42 al_wait_for_event(event_queue, &ev); 43 44 if(ev.timer.source == LPS) { //LOGIC 45 46 } 47 48 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 49 break; 50 } 51 52 else if(ev.timer.source == FPS) { //DRAW 53 al_clear_to_color(al_map_rgb(0,0,0)); 54 al_flip_display(); 55 } 56 } 57 58 al_destroy_timer(FPS); 59 al_destroy_timer(LPS); 60 al_destroy_display(display); 61 al_destroy_event_queue(event_queue); 62 63 return 0; 64}

Edgar Reynaldo

      al_wait_for_event(event_queue, &ev);

      if(ev.timer.source == LPS) { //LOGIC
         
      }

You can't just check the event fields like that. You have to make sure the event is the correct type before you read the event type specific fields. Otherwise you are reading garbage produced by the event union.

al_wait_for_event(event_queue , &ev);

if (ev.type == ALLEGRO_EVENT_TIMER) {
   if (ev.timer.source == LPS) {
      // LOGIC
   }
}

AMCerasoli

Oh I didn't know that, Thanks man. :D

Evert

For common fields it doesn't actually matter whether you do this or not (in fact, you access event.any.source instead). But it's probably good practice to do it as indicated.

J-Gamer

Thanks to all ;D

Thread #606628. Printed from Allegro.cc