Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [A5] Backed up event queue?

This thread is locked; no one can reply to it. rss feed Print
[A5] Backed up event queue?
Erin Maus
Member #7,537
July 2006
avatar

Hey,

I have a simple game loop (excuse the C#):

#SelectExpand
1 bool wasUpdated = false; 2 isRunning = true; 3 while (isRunning) 4 { 5 AllegroMethods.al_wait_for_event(queue, ref e); 6 AllegroEventType type = (AllegroEventType)e.type; 7 8 switch (type) 9 { 10 case AllegroEventType.ALLEGRO_EVENT_JOYSTICK_AXIS: 11 OnJoystickAxisChange(new JoystickEventArgs() 12 { 13 Handle = new JoystickHandle(e.joystick.id), 14 Stick = e.joystick.stick, 15 Axis = e.joystick.axis, 16 Position = e.joystick.pos 17 }); 18 break; 19 case AllegroEventType.ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN: 20 OnJoystickButtonDown(new JoystickEventArgs() 21 { 22 Handle = new JoystickHandle(e.joystick.id), 23 Button = e.joystick.button 24 }); 25 break; 26 case AllegroEventType.ALLEGRO_EVENT_JOYSTICK_BUTTON_UP: 27 OnJoystickButtonUp(new JoystickEventArgs() 28 { 29 Handle = new JoystickHandle(e.joystick.id), 30 Button = e.joystick.button 31 }); 32 break; 33 case AllegroEventType.ALLEGRO_EVENT_JOYSTICK_CONFIGURATION: 34 AllegroMethods.al_reconfigure_joysticks(); 35 36 OnJoystickReconfiguration(EventArgs.Empty); 37 break; 38 case AllegroEventType.ALLEGRO_EVENT_KEY_DOWN: 39 OnKeyDown(new KeyboardEventArgs() 40 { 41 Key = (KeyCode)e.keyboard.keycode, 42 Modifiers = (KeyModifier)e.keyboard.modifiers 43 }); 44 break; 45 case AllegroEventType.ALLEGRO_EVENT_KEY_UP: 46 OnKeyUp(new KeyboardEventArgs() 47 { 48 Key = (KeyCode)e.keyboard.keycode, 49 Modifiers = (KeyModifier)e.keyboard.modifiers 50 }); 51 break; 52 case AllegroEventType.ALLEGRO_EVENT_MOUSE_AXES: 53 OnMouseMove(new MouseEventArgs() 54 { 55 Position = new Vector2(e.mouse.x, e.mouse.y), 56 Difference = new Vector2(e.mouse.dx, e.mouse.dy) 57 }); 58 break; 59 case AllegroEventType.ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: 60 OnMouseButtonDown(new MouseEventArgs() 61 { 62 Position = new Vector2(e.mouse.x, e.mouse.y), 63 Button = (int)e.mouse.button 64 }); 65 break; 66 case AllegroEventType.ALLEGRO_EVENT_MOUSE_BUTTON_UP: 67 OnMouseButtonUp(new MouseEventArgs() 68 { 69 Position = new Vector2(e.mouse.x, e.mouse.y), 70 Button = (int)e.mouse.button 71 }); 72 break; 73 case AllegroEventType.ALLEGRO_EVENT_TIMER: 74 Update(); 75 wasUpdated = true; 76 break; 77 case AllegroEventType.ALLEGRO_EVENT_DISPLAY_CLOSE: 78 OnClose(); 79 break; 80 } 81 82 if (AllegroMethods.al_is_event_queue_empty(queue) != 0 && wasUpdated) 83 { 84 Draw(); 85 wasUpdated = false; 86 } 87 }

When I run this using Allegro 5.0.7, the event queue gets backed up. However, with Allegro 5.0.5, the queue is never backed up. I tested it on an nVidia ION/Atom netbook, and that's where I noticed the backed up queue. My game also locked up at one point on a Core i7/nVidia 560 Ti. So I think the event queue is going nuts, but I don't know where. For now, reverting to 5.0.5 works...but I like staying up to date (and knowing what the problem is). So, is the problem on my end (I'm guessing so) and how would I fix it? My drawing isn't that intensive that it would lock up the queue on the aforementioned hardware.

---
ItsyRealm, a quirky 2D/3D RPG where you fight, skill, and explore in a medieval world with horrors unimaginable.
they / she

weapon_S
Member #7,859
October 2006
avatar

Your problem is weird.
Using new in a switch statement is weird. (C#?)
Having no default case is weird. (C#?)
Drawing before the event queue is "drained" could bring problems.

My drawing isn't that intensive that it would lock up the queue on the aforementioned hardware.

I had the same problems, and the same thought. Draining the event queue helped. Still I wouldn't exclude a bug in Allegro. (Because I love blaming the Allegro devs ;D)

Erin Maus
Member #7,537
July 2006
avatar

C# is garbage collected, so there's no memory leaks :P. As far as drawing, I only draw if there's no events in the queue... So it is drained by the time I draw.

---
ItsyRealm, a quirky 2D/3D RPG where you fight, skill, and explore in a medieval world with horrors unimaginable.
they / she

SiegeLord
Member #7,827
October 2006
avatar

weapon_S said:

Drawing before the event queue is "drained" could bring problems.

He is draining it, as far as I can tell.

Anyway... how do you tell that the event queue is backed up? The symptom of that would be lots and lots of events (which you could check by logging each event)... simply locking up is not necessarily caused by the event queue.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Kris Asick
Member #1,424
July 2001

C# is garbage collected, so there's no memory leaks

That's no excuse not to practice safe memory handling. :P

As for your problem, I seriously doubt you want to be using al_wait_for_event() because you will be completely pausing your game loop every time the queue is empty. :-X

Use "while (!al_is_event_queue_empty())" instead so that if the queue is empty, your game logic will continue as normal. That, or put the event handler into a separate thread, but that would be more trouble than it's worth for almost every circumstance.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Audric
Member #907
January 2001

You missed his case AllegroEventType.ALLEGRO_EVENT_TIMER : A user-defined timer puts 'clock tick' events in the same queue at regular intervals.

Thomas Fjellstrom
Member #476
June 2000
avatar

As for your problem, I seriously doubt you want to be using al_wait_for_event() because you will be completely pausing your game loop every time the queue is empty.

That is exactly what you want. You execute your logic on regular timer ticks. Any time that is left over, is spent sleeping, so your game doesn't peg your cpu and gpu doing absolutely nothing of any value what so ever. Laptop users, mobile device users, and people with insanely loud gfx/cpu coolers will appreciate you for it.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Kris Asick
Member #1,424
July 2001

Oh... I didn't realize the Allegro 5 timer system is tied in with its event system since I use my own timing routines and rely on vertical retrace and user-selectable idle rates to give processing time back to the CPU. ;D

In that case, yeah, al_wait_for_event() would probably work, though I just noticed that the drawing routine is dependent on the event queue being empty, instead of just drawing it when the timer is done updating, so that could have something to do with it... maybe...

*goes back to programming his own stuff* :P

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Thomas Fjellstrom
Member #476
June 2000
avatar

In that case, yeah, al_wait_for_event() would probably work, though I just noticed that the drawing routine is dependent on the event queue being empty, instead of just drawing it when the timer is done updating, so that could have something to do with it... maybe...

That does two things. First, it makes sure the event queue is completely drained every frame, and if you have more than one logic/draw timer event in the queue (maybe the computer is too slow, or you're doing too much relative to your update tick), it will skip those frames.

Essentially it gives you frame skipping/dropping.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Audric
Member #907
January 2001

if (AllegroMethods.al_is_event_queue_empty(queue) != 0 && wasUpdated)

Call me paranoiac, but I'd reverse the test (wasUpdated && al_is_event_queue_empty()).
I can't say al_is_event_queue_empty() is "costly", but it involves some mutual exclusion check. I'd rather not call it at all when wasUpdated==0 in the first place.

Kris Asick
Member #1,424
July 2001

That does two things. First, it makes sure the event queue is completely drained every frame, and if you have more than one logic/draw timer event in the queue (maybe the computer is too slow, or you're doing too much relative to your update tick), it will skip those frames.

Essentially it gives you frame skipping/dropping.

I'm so used to developing real-time, frame-interpolated engines now that the idea of frame skipping/dropping seems obsolete. ::)

But yeah, I'll be quiet now since I barely touch A5's event system. :P

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Thomas Fjellstrom
Member #476
June 2000
avatar

I'm so used to developing real-time, frame-interpolated engines now that the idea of frame skipping/dropping seems obsolete.

Its a cheap and easy way to get something that works for most cases :) if you need anything fancier, you'd obviously do something else.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Go to: