|
Having Trouble with exit(1) - Stalling Program |
AceBlkwell
Member #13,038
July 2011
|
I am still working on the Vivace tutorial. I'm working with sound now. Due to an oversight on my part I didn't catch the file downloaded didn't have the same name as the code. The program would drop into a "must_init" function design to cut down on repetitive coding. The program wouldn't print via the printf command so I didn't realize the program was crashing within this function. The Include section included stdio.h but I also included cstdio. It solved the print problem but not the crash/hang. Having said all of that, my question is, why would exit(1) stall? Is there a better command? I'm compiling with g++. Reading over the code, could the problem with the function being void, yet exit appears to be trying to return something? If you are interested here are the snippets of code involved 1
2ALLEGRO_SAMPLE* elephant = al_load_sample("elephant.wav");// file was actually audio_elephant.wav
3must_init(elephant, "elephant");
4
5void must_init(bool test, const char *description)
6{
7 if(test) return;
8 printf("couldn't initialize %s\n", description);
9 exit(1); // after including cstdio this is where it's stalling. It's not making it out of the function.
10}
Thanks |
DanielH
Member #934
January 2001
|
If not too big, post the entire file. Got to be something else. Nothing looks wrong with function. Except, I'd make it cleaner.
|
AceBlkwell
Member #13,038
July 2011
|
Here is the code. Keep in mind 1
2#include <stdio.h>
3#include <stdlib.h>
4#include <allegro5/allegro5.h>
5#include <allegro5/allegro_font.h>
6#include <allegro5/allegro_primitives.h>
7#include <allegro5/allegro_audio.h>
8#include <allegro5/allegro_acodec.h>
9#include <allcolor_A5.h>
10#include <iostream>
11#include <cstdio>
12
13#define KEY_SEEN 1
14#define KEY_RELEASED 2
15
16void must_init(bool test, const char *description)
17{
18 if(test) return;
19 printf("couldn't initialize %s\n", description);
20 exit(1);
21}
22
23int main()
24{
25 must_init(al_init(), "allegro");
26 must_init(al_install_keyboard(), "keyboard");
27 must_init(al_install_mouse(), "mouse");
28 must_init(al_install_audio(), "audio");
29 must_init(al_init_acodec_addon(), "audio codecs");
30 must_init(al_reserve_samples(16), "reserve samples");
31
32 ALLEGRO_SAMPLE* elephant = al_load_sample("elephant.wav");
33 must_init(elephant, "elephant");
34
35 ALLEGRO_TIMER* timer = al_create_timer(1.0 / 30.0);
36 must_init(timer, "timer");
37
38 ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue();
39 must_init(queue, "queue");
40
41 al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
42 al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
43 al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
44
45 ALLEGRO_DISPLAY* disp = al_create_display(640, 480);
46 must_init(disp, "display");
47
48 ALLEGRO_FONT* font = al_create_builtin_font();
49 must_init(font, "font");
50
51 must_init(al_init_primitives_addon(), "primitives");
52 al_register_event_source(queue, al_get_keyboard_event_source());
53 al_register_event_source(queue, al_get_display_event_source(disp));
54 al_register_event_source(queue, al_get_timer_event_source(timer));
55 al_register_event_source(queue, al_get_mouse_event_source());
56
57 bool done = false;
58 bool redraw = true;
59 ALLEGRO_EVENT event;
60
61 float x, y;
62 x = 100;
63 y = 100;
64 float dx, dy;
65 dx = 0;
66 dy = 0;
67 unsigned char key[ALLEGRO_KEY_MAX];
68 memset(key, 0, sizeof(key));
69
70 al_grab_mouse(disp);
71 al_hide_mouse_cursor(disp);
72 al_start_timer(timer);
73
74
75 // ALLEGRO_KEYBOARD_STATE ks;
76 while(1)
77 {
78 al_wait_for_event(queue, &event);
79
80 /* switch(event.type)
81 {
82 case ALLEGRO_EVENT_TIMER:
83 if(key[ALLEGRO_KEY_UP])
84 y-=2;
85 if(key[ALLEGRO_KEY_DOWN])
86 y+=2;
87 if(key[ALLEGRO_KEY_LEFT])
88 x-=2;
89 if(key[ALLEGRO_KEY_RIGHT])
90 x+=2;
91
92 if(key[ALLEGRO_KEY_ESCAPE])
93 done = true;
94
95
96 for(int i = 0; i < ALLEGRO_KEY_MAX; i++)
97 key[i] &= KEY_SEEN;
98
99 redraw = true;
100 break;
101
102 case ALLEGRO_EVENT_KEY_DOWN:
103 key[event.keyboard.keycode] = KEY_SEEN | KEY_RELEASED;
104 break;
105 case ALLEGRO_EVENT_KEY_UP:
106 key[event.keyboard.keycode] &= KEY_RELEASED;
107 break;
108
109 case ALLEGRO_EVENT_DISPLAY_CLOSE:
110 done = true;
111 break;
112 }*/
113 switch(event.type)
114 {
115 case ALLEGRO_EVENT_TIMER:
116 if(key[ALLEGRO_KEY_ESCAPE])
117 done = true;
118
119 x += dx;
120 y += dy;
121
122 if(x < 0)
123 {
124 x *= -1;
125 dx *= -1;
126 }
127 if(x > 640)
128 {
129 x -= (x - 640) * 2;
130 dx *= -1;
131 }
132 if(y < 0)
133 {
134 y *= -1;
135 dy *= -1;
136 }
137 if(y > 480)
138 {
139 y -= (y - 480) * 2;
140 dy *= -1;
141 }
142
143 dx *= 0.9;
144 dy *= 0.9;
145
146 for(int i = 0; i < ALLEGRO_KEY_MAX; i++)
147 key[i] &= KEY_SEEN;
148
149 redraw = true;
150 break;
151
152 case ALLEGRO_EVENT_MOUSE_AXES:
153 dx += event.mouse.dx * 0.1;
154 dy += event.mouse.dy * 0.1;
155 al_set_mouse_xy(disp, 320, 240);
156 break;
157
158 case ALLEGRO_EVENT_KEY_DOWN:
159 if(event.keyboard.keycode == ALLEGRO_KEY_E)
160 al_play_sample(elephant, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL);
161 if(event.keyboard.keycode != ALLEGRO_KEY_ESCAPE)
162 break;
163 case ALLEGRO_EVENT_KEY_UP:
164 key[event.keyboard.keycode] &= KEY_RELEASED;
165 break;
166
167 case ALLEGRO_EVENT_DISPLAY_CLOSE:
168 done = true;
169 break;
170 }
171 if(done)
172 break;
173
174 if(redraw && al_is_event_queue_empty(queue))
175 {
176
177 al_clear_to_color(al_map_rgb(0, 0, 0));
178 al_draw_text(font, al_map_rgb(255, 255, 255), 640/2, 480/2, ALLEGRO_ALIGN_CENTER, "Knock knock, it's Nelly");
179 al_draw_filled_rectangle(x, y, x + 10, y + 10, al_map_rgb(255, 0, 0));
180
181 al_flip_display();
182
183 redraw = false;
184 }
185 }
186
187 al_destroy_sample(elephant);
188 al_destroy_font(font);
189 al_destroy_display(disp);
190 al_destroy_timer(timer);
191 al_destroy_event_queue(queue);
192
193 return 0;
194}
|
DanielH
Member #934
January 2001
|
At which step is it freezing? When it is loading the file? I'm staring at it and don't see anything. I can test it later tonight when I'm home. I don't normally use exit. cstdio over stdio.h if you are using C++. Quote: The difference (which is neither minor nor a matter of style) is that stdio. h and other C-like libraries when imported in a C++ file may pollute the global namespace, while the corresponding C++ headers (cstdio, cstdlib, cassert) place the corresponding functions, variables, etc., in the std namespace.
|
AceBlkwell
Member #13,038
July 2011
|
The program gets down to ALLEGRO_SAMPLE* elephant = al_load_sample("elephant.wav"); It attempts to load the sound file. Then enters must_init. While in must_init, it gets down past printf but doesn't come back out of the function. There is only one command after printf, exit(1) so I assume that's where it's stalling. void must_init(bool test, const char *description) All the other inits are successful so it never gets to exit(1). |
DanielH
Member #934
January 2001
|
I don't think it's the exit, but for testing purposes. Add another printf test string after the exit before the function ends. |
AceBlkwell
Member #13,038
July 2011
|
Daniel, don't waste a lot of time on it. I was just curious if there was an alternative to exit(1) or if it was problematic with C++. To your suggestion, here are my results. Before File load If didn't make it after exit(1) 1
2void must_init(bool test, const char *description)
3{
4 if(test) return;
5 std::cout<<"After If return in must_init"<<std::endl; //
6 printf("couldn't initialize %s\n", description);
7 std::cout<<"After printf in must_init"<<std::endl; //
8 exit(1);
9 std::cout<<"After exit(1) in must_init"<<std::endl; //
10}
11
12
13int main()
14{
15 must_init(al_init(), "allegro");
16 must_init(al_install_keyboard(), "keyboard");
17 must_init(al_install_mouse(), "mouse");
18 must_init(al_install_audio(), "audio");
19 must_init(al_init_acodec_addon(), "audio codecs");
20 must_init(al_reserve_samples(16), "reserve samples");
21
22 std::cout<<"Before File load"<<std::endl; //
23 ALLEGRO_SAMPLE* elephant = al_load_sample("elephant.wav");
24 std::cout<<"Before must_init in main"<<std::endl; //
25 must_init(elephant, "elephant");
26 std::cout<<"After must_init in main"<<std::endl; //
|
DanielH
Member #934
January 2001
|
1// remove exit
2bool must_init(bool test, const char *description)
3{
4 if (!test)
5 {
6 std::cout << "couldn't initialize" << description < <std::endl;
7 }
8
9 return test;
10}
11
12int main()
13{
14 if (!(must_init(al_init(), "allegro")) return -1;
15
16}
This is mine // what are we attempting std::cout << "Initializing Allegro Library: "; if (!al_init()) { std::cout << "failed" << std::endl; return -1; } std::cout << "pass" << std::endl; it does get messy 1int32_t init()
2{
3 std::cout << "Initialization Begin" << std::endl;
4
5 std::cout << "Initializing Allegro Library: ";
6 if (!al_init())
7 {
8 std::cout << "failed" << std::endl;
9 return -1;
10 }
11 std::cout << "pass" << std::endl;
12
13 std::cout << "Initializing Mouse: ";
14 if (!al_install_mouse())
15 {
16 std::cout << "failed" << std::endl;
17 return -1;
18 }
19 std::cout << "pass" << std::endl;
20
21 std::cout << "Initializing Keyboard: ";
22 if (!al_install_keyboard())
23 {
24 std::cout << "failed" << std::endl;
25 return -1;
26 }
27 std::cout << "pass" << std::endl;
28
29 std::cout << "Initializing Image Addon: ";
30 if (!al_init_image_addon())
31 {
32 std::cout << "failed" << std::endl;
33 return -1;
34 }
35 std::cout << "pass" << std::endl;
36
37 std::cout << "Creating Display: ";
38 al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE);
39 if (!(this->m_display = al_create_display(App::SCREEN_W, App::SCREEN_H)))
40 {
41 std::cout << "failed" << std::endl;
42 return -1;
43 }
44 std::cout << "pass" << std::endl;
45
46 ALLEGRO_BITMAP* icon = al_load_bitmap("data\\images\\icon.png");
47 if (icon)
48 {
49 al_set_display_icon(this->m_display, icon);
50 al_destroy_bitmap(icon);
51 }
52 al_set_window_title(this->m_display, App::APPNAME);
53
54 std::cout << "Creating Event Queue: ";
55 if (!(this->m_queue = al_create_event_queue()))
56 {
57 std::cout << "failed" << std::endl;
58 return -1;
59 }
60 std::cout << "pass" << std::endl;
61
62 std::cout << "Creating Logic Timer: ";
63 if (!(this->m_timer = al_create_timer(1.0/App::TIMING)))
64 {
65 std::cout << "failed" << std::endl;
66 return -1;
67 }
68 std::cout << "pass" << std::endl;
69
70 al_register_event_source(this->m_queue, al_get_display_event_source(this->m_display));
71 al_register_event_source(this->m_queue, al_get_timer_event_source(this->m_timer));
72 al_register_event_source(this->m_queue, al_get_keyboard_event_source());
73 al_register_event_source(this->m_queue, al_get_mouse_event_source());
74
75 al_start_timer(this->m_timer);
76
77 std::cout << "Initialization Complete" << std::endl << std::endl;
78
79 return 0;
80}
Personally, I don't like leaving things hanging. My shutdown function always gets called even if there is an error in init. In it, every object I allocated is checked and unallocated. int main() { if (init() ==0) { // proceed loop(); } shutdown(): }
|
AceBlkwell
Member #13,038
July 2011
|
Thanks for the insight Daniel. I appreciate the time. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
That said, avoid nasty things like exit and abort. It's easy enough to return non-zero in main. Also, must init should also report success, not just failure. 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 |
DanielH
Member #934
January 2001
|
I'm home and tested your code. It does just as expected. runs and exits after failing to load elephant. output: "couldn't initialize elephant" I put a wav file of my own and the program plays it when I press E. Some issues, how to exit program? You turned off the mouse cursor so I could not press the close button. You don't have any key presses that close the program either. I was able to close it pressing Alt+f4. {"name":"613302","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/b\/cbe4db979eece65810032c1c2bb1fb22.png","w":789,"h":590,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/b\/cbe4db979eece65810032c1c2bb1fb22"} |
AceBlkwell
Member #13,038
July 2011
|
Could be my computer at work. I ran it from home. Still Eclipse IDE but on Linux. It worked just like you said. Must have just been the computer at work. Doesn't make sense. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
If your program was hanging, it was probably because of a loose thread that was still running. Probably allegro's audio or window thread. 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 |
AceBlkwell
Member #13,038
July 2011
|
Could be Edgar. I still think it's something to do with Windows /Eclipse IDE / Mingw32. Or a combo there of. Here is why I say that Thanks for the follow up. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
If you're using the same code as before, you haven't shutdown audio or allegro itself. 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 |
Dizzy Egg
Member #10,824
March 2009
|
This code is horrible to me; why call every library initialisation method and then pass an optional null into a void method with a null as bool? Why not just have a setup function that returns a bool result and determine whether or not to continue or not based on setup success?
---------------------------------------------------- |
AceBlkwell
Member #13,038
July 2011
|
Yeah, I didn't create the code so I can't say why they did what they did. I figured the programmer knew more about it than I did. It seems to work well enough if the ducks are in a row. |
|