Console problem
BlitzMax Forums/BlitzMax Programming/Console problem
| ||
How can I (in a console program) a) Run some code after the user clicks the X button to close the program b) Catch some keyboard input without stopping the program. Keyhit, getchar etc won't work in console program. Input() stops the program. What I'm doing, is that my server has to do some cleanup at the end of the program, but I don't know how to execute CleanUp() function at the end of the program. |
| ||
Use the OnEnd() function. |
| ||
I'm having the exact same problem right now. OnEnd doesn't seem to work when the X button is closed in a console app. |
| ||
bmax can make games for consoles like Xbox? sorry but have I been uninformed this whole time? or is this c++? |
| ||
Nope, talking about a text-based console window, like when you run "cmd" from Windows. Sorry :) |
| ||
oh ok just making sure I wasn't missing out :) |
| ||
Use the OnEnd() function. This doesn't work, since "end" is not called when you close the program. |
| ||
This doesn't work, since "end" is not called when you close the program. Didn't know that. |
| ||
OnEnd doesn't seem to work when the X button is closed in a console app. It does seem to, in a sense, but it does not seem like you can actually return to regular process (after any instructions you give it, it stills exits, ultimately).SuperStrict Framework brl.blitz Import brl.standardio Import brl.system OnEnd(Cleanup) Input("Terminate me!") End Function Cleanup() CreateFile("Ahha.blah") ' Proof! End Function |
| ||
maybe have a loop that says if appterminate then do this |
| ||
I am working on a Console Control module as it happens but I have not got round to doing the KeyDown()/KeyHit() side of things I only have Input() so far as a method for reading the user input WINDOWS ONLY Examples of some of the commands: Console.Open "Test window" Console.SetColor RED,GREY Console.Cls Console.SetCursorPos 10,5 Console.Write "Hello world" t$=Console.Input("Enter your name > ") Console.Close |
| ||
Plash, you don't understand the problem. It's like this.'Server code Repeat 'Do server stuff UpdateClients() Forever 'I cannot use Input, it stops updating clients 'cannot use keyhit, getchar, etc etc.. OnEnd(Cleanup) Function Cleanup() CreateFile("Ahha.blah") ' Proof! End Function Cleanup will never be called if I run this as a console app and hit X to close the server. If I could somehow catch user input like (hit key escape) then that would be an okay solution too. The user should just hit escape to close the program. But keyhit, getchar doesn't work in console mode. |
| ||
@nawi, For non-halting input, try some of the functions from c stdio/conio..Extern "C" Function getchar:Int() Function getch:Int() Function getche:Int() Function kbhit:Int() EndExtern |
| ||
Cleanup will never be called if I run this as a console app and hit X to close the server. Uhm.. Given the position you put your OnEnd call, that is absolutely correct.How do you expect the Cleanup function to be called when it is never told to before the program actually exits? (OnEnd never gets called because it completely stops at whatever point in your loop to do the exit, at which point it calls all OnEnd callbacks) EDIT: Think of it like this: Your program is doing its main loop, updating clients and whatever. Then the user hits the X button on the Console's window, which then goes through some stuff on the Win32 end. It eventually calls your program's exit function (keep in mind these times are within nano/milli-seconds), which then calls all OnEnd callbacks. If you will read that carefully, you will notice that you never actually called OnEnd. EDIT2: Code example of the first edit: SuperStrict Framework brl.blitz Import brl.system Repeat Delay(2000) ' Simulatory.. End() ' This will be our substitute for the user pressing the X button. ' Note that you could also just do an infinite loop and just hit the X button (not using End()) Forever OnEnd(Cleanup) ' NEVER gets called. Ever. Function Cleanup() CreateFile("Ahha.blah") End Function |
| ||
so you should put onend at the beginning right after super strict. |
| ||
Extern "WIN32" Function SetConsoleCtrlHandler:Int(func(),add:Int) End Extern Extern "C" Function getch:Int() Function kbhit:Int() EndExtern SetConsoleCtrlHandler(Cleanup,True) Local running=1 Print "Close window or type something" While running If kbhit() Then Print "keyhit: "+getch() Wend Function Cleanup() running=0 Notify "Cleaning..." End Function but this is windows only.. |
| ||
Plash, you don't understand the problem. End() is not called when the user clicks the X button in a console program, so placing OnEnd before the loop doesn't fix anything. Windows-only solutions don't help. ' Note that you could also just do an infinite loop and just hit the X button (not using End()) That's incorrect, I just tested. |
| ||
@nawi the code that Plash has posted does work clicking the x in a console will create a file called Ahha.blah example of infinite loop with no End SuperStrict Framework brl.blitz Import brl.system Import brl.standardio OnEnd(Cleanup) Print "Click x to exit" Repeat Forever Function Cleanup() CreateFile("Ahha.blah") End Function |
| ||
@Nurgle. I see now that it does work, but there seems to be a really small time to execute any code. If I try to loop 100 times and print stuff, I only get like 10 print's. Likewise, my goal is to connect to a server and there is no time for that either.. In fact, if you add delay 5000, the app still closes rapidly. What I'm trying to do, if that when the server is closed, the server connects to a serverlist-server, and notifys it to remove that server from the list. Yeah, I have a timeout system in plaec, and it will be removed after some time, but this causes the server to be on the list for a minute or too and players will try to connect to it, even though it should've been removed. |
| ||
Plash, you don't understand the problem. End() is not called when the user clicks the X button in a console program, so placing OnEnd before the loop doesn't fix anything. OnEnd adds functions to be called when 'exit' is called (for Max use, 'End' is the same as calling 'exit'). The 'exit' function is in C, and is automatically called WHENEVER the program shuts down (via normal means - a crash/taskkill probably wont call it, afaik)./mod/brl.mod/blitz.mod/blitz_app.c void bbEnd(){ exit(0); } void bbOnEnd( void (*f)() ){ atexit( f ); } Notice the internal functions for Max. 'End' actually does call 'exit' (with the exit code 0, meaning no error). OnEnd adds a function to be called when the program is closed (and, subsequently, when you call 'End'). |
| ||
Yes I know that now Plash, but I explained a new problem in my post above. |
| ||
There is no way to get around that issue unless you can capture the events for the console and do with them as you wish. |
| ||
I'm a bit late to the party(!) But, you could have used a 'boot' program to launch your main .exe. The boot program hangs around polling every now and again to see if the main program has finished. If it has, then it closes everything off nicely for you, then self-terminates. I've had to employ a similar set-up for my project.... I have one program that very graphically intensive but it needs to sit and wait for FTP feedback (not quick by any means!). So instead, I have an FTP program that launches the graphical program and passes data to it via a shared file. This way the FTP program can take as long as it likes, but the graphical program can run un-hindered. ( I also hide the FTP window so the user doesn't know it's there ). A kind of poor man's multi-thread. ;o) |