|
[A5] Backed up event queue? |
Erin Maus
Member #7,537
July 2006
|
Hey, I have a simple game loop (excuse the C#): 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. --- |
weapon_S
Member #7,859
October 2006
|
Your problem is weird. Aaron Bolyard said: 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 ) |
Erin Maus
Member #7,537
July 2006
|
C# is garbage collected, so there's no memory leaks . As far as drawing, I only draw if there's no events in the queue... So it is drained by the time I draw. --- |
SiegeLord
Member #7,827
October 2006
|
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 |
Kris Asick
Member #1,424
July 2001
|
Aaron Bolyard said: C# is garbage collected, so there's no memory leaks That's no excuse not to practice safe memory handling. 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. 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) |
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
|
Kris Asick said: 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. -- |
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. 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* --- Kris Asick (Gemini) |
Thomas Fjellstrom
Member #476
June 2000
|
Kris Asick said: 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. -- |
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()). |
Kris Asick
Member #1,424
July 2001
|
Thomas Fjellstrom said: 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. --- Kris Asick (Gemini) |
Thomas Fjellstrom
Member #476
June 2000
|
Kris Asick said: 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. -- |
|