|
[A5] Main() timer's effect on called functions? |
Phrasz
Member #10,091
August 2008
|
So I finally understand the use of the timer with a single function. (see the fade animation post) How should I go about having a "global timer". The Current Method: 1main(){
2 //create timer
3
4 timer = al_create_timer(1.0 / 60);
5 queue = al_create_event_queue();
6 al_register_event_source(queue, al_get_keyboard_event_source());
7 al_register_event_source(queue, al_get_display_event_source(display));
8 al_register_event_source(queue, al_get_timer_event_source(timer));
9 al_start_timer(timer);
10
11 while (1) {
12 //The magic happens here
13 ALLEGRO_EVENT event;
14 al_wait_for_event(queue, &event);
15
16 }
17}
From my understanding when you call a function within the while loop it will not be under the control of the timers. (I'm basing this off of the experience of having a for loop execute. When a for loop is within while it will run at the speed of the machine vs the speed of the timer. ) Without functions the code would get messy real quick. Hopefully, I am missing something simple here...anyone able to instruct me on this vacancy? To be able to implement: 1main(){
2 //create timer
3
4 timer = al_create_timer(1.0 / 60);
5 queue = al_create_event_queue();
6 al_register_event_source(queue, al_get_keyboard_event_source());
7 al_register_event_source(queue, al_get_display_event_source(display));
8 al_register_event_source(queue, al_get_timer_event_source(timer));
9 al_start_timer(timer);
10
11 while (1) {
12 //The magic happens here
13 ALLEGRO_EVENT event;
14 al_wait_for_event(queue, &event);
15 function();
16 }
17}
18
19function(){
20}
|
Thomas Fjellstrom
Member #476
June 2000
|
Yes, as your code is, it won't be restricted to the timer. It will be close, but other events will cause the al_wait_for_event function to return. (at least if you had added other event sources to the queue) But try this instead: 1void main(int argc, char **argv)
2{
3 //create timer
4
5 timer = al_create_timer(1.0 / 60);
6 queue = al_create_event_queue();
7 al_register_event_source(queue, al_get_keyboard_event_source());
8 al_register_event_source(queue, al_get_display_event_source(display));
9 al_register_event_source(queue, al_get_timer_event_source(timer));
10 al_start_timer(timer);
11
12 while (1) {
13 //The magic happens here
14 ALLEGRO_EVENT event;
15 al_wait_for_event(queue, &event);
16
17 if(event.type == ALLEGRO_EVENT_TIMER && event.source == timer) {
18 function();
19 }
20 }
21}
22
23void function(){
24}
That should do what you want, even if you add more timers or other event sources. -- |
J-Gamer
Member #12,491
January 2011
|
Don't you need al_get_timer_event_source(timer) instead of timer? " There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo |
Thomas Fjellstrom
Member #476
June 2000
|
That would be more technically correct yes.[1][2] References
-- |
J-Gamer
Member #12,491
January 2011
|
I didn't know that... that's pretty handy " There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo |
Phrasz
Member #10,091
August 2008
|
I'm glad to see I'm on the right track, but wouldn't the function then operate at the system's speed vs the timers speed? Would I need to install a new set of timers? Also shouldn't I stop the main() timer until function() with new timer complete? Also, were you guys speaking of this implementation?: 1 if(event.type == ALLEGRO_EVENT_TIMER && event.source == al_get_timer_event_source(timer)){
2 function();
3 }
|
Thomas Fjellstrom
Member #476
June 2000
|
Phrasz said: I'm glad to see I'm on the right track, but wouldn't the function then operate at the system's speed vs the timers speed? Your code would just call the function every time through the loop. Wrapping it in that if will only call it when a timer event is fetched from the queue. Of course, due to the al_wait_for_event call, the loop will sleep till it gets a timer event, so right now even without the if() it won't actually get around to executing the function till any event arrives. -- |
Phrasz
Member #10,091
August 2008
|
Excellent to hear. So let's say that the function(); was desired to run at 60 fps. Would I need this function to have it's own timers? Since the first timer declarations are within the main() function? 1void main(int argc, char **argv)
2{
3 //create timer
4
5 timer = al_create_timer(1.0 / 60);
6 queue = al_create_event_queue();
7 al_register_event_source(queue, al_get_keyboard_event_source());
8 al_register_event_source(queue, al_get_display_event_source(display));
9 al_register_event_source(queue, al_get_timer_event_source(timer));
10 al_start_timer(timer);
11
12 while (1) {
13 //The magic happens here
14 ALLEGRO_EVENT event;
15 al_wait_for_event(queue, &event);
16
17 if(event.type == ALLEGRO_EVENT_TIMER && event.source == timer) {
18 al_stop_timer(timer);
19 function(); //Stop the timer to run during the function();
20 al_start_timer(timer);
21 }
22 }
23}
24
25void function(){
26 //create timer2
27
28 timer2 = al_create_timer(1.0 / 60);
29 queue2 = al_create_event_queue();
30 al_register_event_source(queue2, al_get_keyboard_event_source());
31 al_register_event_source(queue2, al_get_timer_event_source(timer2));
32 al_start_timer(timer2);
33
34 //do more magic
35
36 //destroy queue2 and timer2
37
38}
|
Thomas Fjellstrom
Member #476
June 2000
|
Phrasz said: So let's say that the function(); was desired to run at 60 fps Thats how that code will run function() as it is. You don't need a second timer or any other queue. that if(event.type == ALLEGRO_EVENT_TIMER && event.source == timer) { ... } block will only be run 60 times a second. There is no need for any further tricks. Also, you probably don't want to stop/start the timer like that either. -- |
Phrasz
Member #10,091
August 2008
|
There isn't any nesting issues? (trying to implement these ideas in my code as I've been responding)
|
Thomas Fjellstrom
Member #476
June 2000
|
Phrasz said: What happens if the function called takes longer than the timer(in this case greater than 1/60 of a second)? Timer events will stack up, and you'll end up getting behind. What I do in some of my code, is use the al_peek_next_event function to check to see if the next event is also a TIMER event, and pop it off (I actually do it in a while loop, to pop off all TIMER events from the main timer) after I've handled the frame. But generally you don't want to be doing so much that your function takes more than a single frame, or your game is going to end up being slow. -- |
Phrasz
Member #10,091
August 2008
|
Perfect... I'm stoked to see I'm think about this correctly. Basically, I'm making animations as functions, but they will take longer than a frame. So I'm trying to determine the best way to accomplish this w/o having a HUGE main file with a single while loop to get lost in.
|
Thomas Fjellstrom
Member #476
June 2000
|
Phrasz said: Basically, I'm making animations as functions, but they will take longer than a frame. Theres no way changing the frame of the animation will take more than a frame. I think you're making a simple mistake, you don't want to do the entire animation sequence in a single function. Instead, store your animations in such a way, so that you can just draw the current frame of all animations in your main loop (or in a single function that your main loop calls). That is to say, you don't want to think of the animation as a separate thread of execution. Instead, just draw the current frame of the animation in your normal drawing. Then your logic code will advance the animation's current frame when its supposed to. -- |
Edgar Reynaldo
Major Reynaldo
May 2007
|
I wrote a class to handle animations using Allegro 4, you can download the source code and a working executable here : It wouldn't be that hard to port it to Allegro 5. Just count the number of timer ticks, multiply by the number of seconds per tick, and pass that to AdvanceFrameTime. Replace BITMAP*'s with ALLEGRO_BITMAP*'s and replace the drawing calls with al_draw_bitmap calls and it should work. There's no need to put the entire animation inside it's own function, but you still could for clarity or modularity. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Phrasz
Member #10,091
August 2008
|
I was shooting to make the code more modular, and I was currently doing the prescribed method of animation per frame vs per function. (I had the fade animation that used a for loop to step through the rendered,modified alpha versions of the bit map to "fade" the image.H/e the for loop was too much for the pre-defined timer). Thanks for the help. I'll look into "cleaning" the code into functions that doesn't exceed the frame rate. However, has anyone looked into a global timer? Don't ask me how to accomplish this ... I'm just the Comp Engineer...
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
What do you mean a global timer? Do you know how to make a global variable? Header : extern ALLEGRO_TIMER* global_extern_timer; Source : ALLEGRO_TIMER* global_extern_timer = 0;
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Phrasz
Member #10,091
August 2008
|
So if that's the case wouldn't all the functions then work (main() to function() to etc) under this global timer? Or is it a queue issue at that point? (can't have multiple if (queue event ) across the functions)
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Phrasz said: Or is it a queue issue at that point? (can't have multiple if (queue event ) across the functions) You probably want to have a single ALLEGRO_EVENT_QUEUE and distribute the ALLEGRO_EVENT's that you receive from it to your different objects. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Phrasz
Member #10,091
August 2008
|
Thanks again guys. Sadly I've given up and I'm back to good old brute forcing code...
|
|