Exiting a program outside main function - c++

I m making a project with the allegro game library ,when the x button is clicked in the game
a function will be called ,i could then do std::exit(0) or the built in exit function of allegro "allegro_exit()" but my program won't exit well and it will be still open but not responding because i didn't return from the main function.
the only chance if i have is to do a while loop in the main function that performs stuff when the x button isn't clicked ,after the loop is done i could normally return from the main function,
however i don't think the while loop is good idea and it won't fit my program.
any chance of doing this in another way?

std::exit() function does all necessary cleanups and terminates a program in a normal way. If your program freezes and doesn't respond then consider to carefully review the code that is responsible for resources releasing (destructors etc.). Some libraries can react to exit function in some strange way so take this case in account. You can read more about std::exit() here.
Don't use std::abort() for normal program termination, because it is not aimed to be used for that and it doesn't cleanup after your application.
Anyway, I recommend you to review the architecture of your project and provide a return to the main function after all cleanups. while loop is ok, because it must exist somewhere to wait for user input.

Related

Can I poll for events using SDL2 on macOS outside of main thread?

I'm playing around with SLD2 and I've got a somewhat working game. It works great on Linux/Windows, but I'm getting an exception on macOS.
I've done input handling in a separate thread, basically it just polls for user input and then does calculations/moves sprites around etc. My problem is that on macOS it seems that the library is compiled in a way that when you call SDL_PollEvent, SDL_WaitEvent or SDL_HasEvents it calls SDL_PumpEvents from within itself, which can only be called from the main thread.
Is there a way to get the events without the functions calling SDL_PumpEvents? (I call that in main thread on every iteration, so it really isn't needed)

How to implement a dialogue system without stalling the main loop?

I'm interested in implementing a dialogue system similar to what is being done here http://fungusdocs.snozbot.com/lua_controlling_fungus.html .
-- Display text in a SayDialog
say("Hi there")
say "This syntax also works for say commands"
-- Display a list of options in a MenuDialog
-- (Note the curly braces here!)
local choice = choose{ "Go left", "Go right" }
if choice == 1 then
say("You chose left")
elseif choice == 2 then
say("You chose right")
end
My takeaway from this lua code snippet is that the code is very easy to write and follow along, and I look to use a similar approach. What I wonder is how this can be implemented without stalling the engine code while waiting for a choice.
the function call choose{ "Go left", "Go right" } return a value which makes me want to say that this is a synchronous call. Since we're calling the engine code synchronous we then halt the engine, yet this function call should not be the one directly answering the question - I believe that it needs to be answered in the regular main loop as not to interfere with the rest of the program.
To my understanding the only way to solve this would be to rely on multi-threading. to have the script handled on a separate thread that on the choose call first adds a prompt, then waits for the prompt to be answered, fetch the result, and then continues executing the lua script.
What would be a good way to solve this without making the lua code cumbersome to work with?
Normally you'd run the blocking code in Lua thread (coroutine).
Your choose{} call would yield internally, and the app would resume that thread periodically on external events (input/render/whatever). That way you can have the main loop running freely, taking results from that dialog on nearest iteration after dialog is ready.
The object serving choose{} call might trigger some event on completion, which might be monitored by application's bigger system, the same system that would wait for completion of other asynchronous tasks (file loaded, http request served, etc).

Progress Bar with Gtkmm

Hello I am looking for a signal for gtkmm. Basically I am doing some simulations and what I want is something like this :
I assume I do 5 simulations :
progressBar.set_fraction(0);
1 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
2 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
3 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
4 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
5 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
But I don't know which signal I have to use and how to translate to this.
Thank you a lot for your help !!!
The pseudo code which you presented in your question should actually work - no signal is necessary. However, you could introduce a signal into your simulation for update of the progress bar. IMHO this will not solve your problem and I will try to explain why and what to do to solve it:
You provided a little bit too less context, so, that I will introduce some more assumptions: You have a main window with a button or toolbar item or menu item (or even all of them) which start the simulation.
Let's imagine you set a breakpoint at Gtk::ProgressBar::set_fraction().
Once the debugger stopped at this break point you will find the following calls on the stack trace (probably with many other calls in between):
Gtk::Main::run()
the signal handler of the widget or action which started the simulation
the function which runs the five simulations
and last the call of Gtk::ProgressBar::set_fraction().
If you could inspect the internals of Gtk::ProgressBar you would notice that everything in Gtk::ProgressBar::set_fraction() is done properly. So what's wrong?
When you call Gtk::ProgressBar::set_fraction() it probably generates an expose event (i.e. adds an event to the event queue inside of Gtk::Main with a request for its own refresh). The problem is that you probably do not process the request until all five runs of the simulation are done. (Remember that Gtk::Main::run() which is responsible for this is the uppermost/outmost call of my imaginery stack trace.) Thus, the refresh does not happen until the simulation is over - that's too late. (Btw. the authors of Gtk+ stated somewhere in the manual about their cleverness to optimize events. I.e. there might be finally only one expose event for the Gtk::ProgressBar in the event queue but this does not make your situation better.)
Thus, after you called Gtk::ProgressBar::set_fraction() you must somehow flush the event queue before doing further progress with your simulation.
This sounds like leaving the simulation, leaving the calling widget signal handler, returning to Gtk::Main::run() for further event processing and finally coming back for next simulation step - terrible idea. But we did it much simpler. For this, we use essentially the following code (in gtkmm 2.4):
while (Gtk::Main::events_pending()) Gtk::Main::iteration(false);
(This should hopefully be the same in the gtkmm version you use but if in doubt consult the manual.)
It should be done immediately after updating the progress bar fraction and before simulation is continued.
This recursively enters (parts of) the main loop and processes all pending events in the event queue of Gtk::Main and thus, the progress bar is exposed before the simulation continues. You may be concerned to "recursively enter the main loop" but I read somewhere in the GTK+ manual that it is allowed (and reasonable to solve problems like this) and what to care about (i.e. to limit the number of recursions and to grant a proper "roll-back").
What in your case is the simulation we call in general long running functions. Because such long running functions are algorithms (in libraries for anything) which shall not be polluted with any GUI stuff, we built some administrational infra structure around this basic concept including
a progress "proxy" object with an update(double) method and a signal slot
a customized progress dialog which can connect a signal handler to such a progress object (i.e. its signal slot).
The long running function gets a progress object (as argument) and is responsible to call the Progress::update() method in appropriate intervals with an appropriate progress factor. (We simply use values in the range [0, 1].)
One issue is the interval of calling the progress update. If it is called to often the GUI will slow down your long running function significantly. The opposite case (calling it not often enough) results in less responsiveness of GUI. Thus, we decided for more often progress update. To lower the time consuming of GUI, we remember the time of last update in our progress dialog and skip the next refreshs until a certain duration since last refresh is measured. Thus, the long running function has still some extra effort for progress update but it is not recognizable anymore. (A good refresh interval is IMHO 0.1 s - the perception threshold of humans but you may choose 0.05 s if in doubt.)
Flushing all pending events results in processing of mouse events (and other GTK+ signals) also. This allows another useful feature: aborting the long running function.
When the "Cancel" button of our progress dialog is pressed it sets an internal flag. If the progress is updated next time it checks the flag. If the flag became true it throws a special exception. The throw aborts the caller of the progress update (the long running function) immediately. This exception must be catched in the signal handler of the button (or whatever called the long running function). Otherwise, it would "fall through" to the event dispatcher in Gtk::Main where it is catched definitely which would abort your application. (I saw it often enough whenever I forgot to catch.) On the other hand: catching the special exception tells clearly that the long running function has been aborted (in opposition to ended by regulary return). This may or may not be something which can be stated on GUI also.
Finally, the above solution can cause another issue: It enables to start the simulation (via GUI) while a simulation is already running. This is possible because button presses for simulation start could be processed while in progress update. To prevent this, there is actually a simple solution: set a flag at start of simulation in the GUI until it has finished and prevent further starts while the flag is set. Another option can be to make the widget/action insensitive when simulation is started. This topic becomes more complicated if you have multiple distinct long running functions in your application which may or may not exclude each other - leads to something like an exclusion matrix. Well, we solved it pragmatically... (but without the matrix).
And last but not least I want to mention that we use a similar concept for output of log views (e.g. visual logging of infos, warnings, and errors while anything long running is in progress). IMHO it is always good to provide some visual action for end users. Otherwise, they might get bored and use the telephone to complain about the (too) slow software which actually steals you the time to make it faster (a vicious cycle you have to break...)

My C++ Unity plugin runs once in the editor but not twice

I have a plugin that calls C++ code. When the game starts, it calls this extern C++ function:
void startPlugin() {
MyClass::instance = new MyClass();
MyClass::instance->process();
}
The process method runs an infinite loop that processes data and goes on, as long at the keepRunning member is true. Because it runs an infinite loop and blocks, this method is called within its own thread.
When the game ends I run this extern method from C#:
void stopPlugin() {
MyClass::instance->keepRunning = false;
sleep(1); // Make sure the process loop is done. It should take less than one frame, but just to be sure...
MyClass::cleanup();
}
Which refers to this method:
void MyClass::cleanup() {
delete instance;
instance = NULL;
}
Based on what the console says, these methods are indeed run.
On Mac, this works the first time. I can start the game in the editor and stop it in the editor and everything works fine. But if I try to run it a second time without restarting the Unity editor, the whole editor freezes. Sometimes it takes three times instead of two, but invariably the second or third attempt to play freezes Unity completely. The cursor changes to the spinning pinwheel.
The log says:
Starting.
(Filename: /Applications/buildAgent/work/d63dfc6385190b60/artifacts/MacEditorGenerated/UnityEngineDebug.cpp Line: 49)
Receiving unhandled NULL exception
Launching bug reporter
Obtained 37 stack frames.
#0 0x00000090019390 in _platform_memmove$VARIANT$sse42
And then the stack trace brings up the function that calls the extern function.
Trying to join the thread that was running startPlugin freezes the editor on stop. I don't think it should do that. After all, at that stage, the loop is over and the instance cleaned. This is not guesswork, there are visible side effects: ending the loop turns off the computer's camera and I can see the light of the camera go off. Also a debug message is sent in C# after the call to startPlugin returns. So there is no doubt that the loop is over.
A previous version that does not delete the instance works every time on Windows.
Am I doing something obviously wrong?
I found my answer.
Even though no thread is called inside of the C++, I still need call pthread_exit(this) at the end of the process method. This is not necessary on Windows, but it is on Mac. After that, all works.

How to play sound at the same time as the program?

I want to play sound while the program is running in c++. I am using the code:
void fighterplanesound()
{PlaySound(TEXT("bombdrop.wav"), NULL, SND_FILENAME|SND_ASYNC);}
I thought the SND_ASYNC flag would fix this problem but it did not. What is happening is the program will pause or control will not move on until the sound is done playing. How can I play the sound while the program continues to run. To clarify, the program is a Windows console program that operates in an MS-DOS window.
How about playing the sound in a different thread?
Ok. What I figured out was that you can't include the PlaySound method in the function because even though the ASYNC flag was there, control had to fully execute the PlaySound method before returning, so don't put it in the function unless there is more code in the function(in which case the sound will play while that code is executing) or in other words, control will not return from the function until PlaySound is finished executing and because there is no other code in the function to execute, control waits until PlaySound method is finished and then moves on.
Actually i had the same problem on my iOS app. You know the time that how long does it take to play your .wav file. You can create a Timer that calls your fighterplanesound() method each period of ending time of your file. Not the best solution but it works for me.