On Thu, Aug 7, 2014 at 6:37 PM, Estevo <euccastro@gmail.com> wrote:
Okay, it wasn't that easy. I *do* need to have a Gambit thread running a loop in the background as well. How can I keep that loop running?
What do you need to do in this thread exactly?I imagine that loop will keep running as long as you are in the Scheme world, that is, handling any type of event. Unfortunately, in an event-based system your app will by default spend much of the time in the C world, waiting for things to happen. A way to work around that is suggested below.
When you said "install a timer in the host system and keep calling" you mean that I need to break up that loop into a callback which is called with a repeating timer? (I think this is not a good solution).If you really prefer to implement your background task as a loop in a gambit thread, you can communicate between the 'main' (event-system controlled) and 'worker' gambit threads via gambit thread mailboxes. So your timer handler just sends a message to the worker thread and waits for a message in response. So the worker loop blocks waiting for a message at the beginning of each iteration and sends a message back at the end. The content of these messages can be bogus and ignored both ways. What this achieves is setting apart some time to give your logic a chance to run.
Also, many event-based systems have an 'on idle' event type such that if you register to listen for it, your handler will get triggered whenever the application is doing nothing. So if you don't really need your background logic to happen in regularly timed ticks, using the idle handler instead might make better use of processing time left over from event handling and rendering.
As a step further in this direction, you can have *all* your event handlers works like this, just delegating the real work to the "worker" gambit thread through mailboxes, and then you can make your code feel pretty much as though you controlled the main event loop. In this case, the messages sent to mailboxes would contain information about the events. So the worker thread can switch over event type, just as in plain SDL. Note you still need a timer or idle handler to have stuff happen outside of user input and redraw events.
In this case your "worker" thread looks and feels pretty much like a "main" thread. The event handlers themselves only contain stubs.And then, where would you create and start that thread?I don't know the specifics of your platform. In some, starting the event loop is done explicitly, so you can create the thread before you do that. In others, there is an 'init' event type. Where would you, for example, initialize OpenGL state that will not change throughout your application? I bet somewhere around there you might be able to launch that thread too.
As a last resort, you can just do it the first time that any event handler gets called.Thank you for your replies.I'm working with SDL2, using SchemeSpheres' bindings. Everything is working smoothly, except for this requirement at the bottom of the README:
http://hg.libsdl.org/SDL/file/704a0bfecf75/README-ios.txtIt is easy to make it work, unless you want to run some continuous process in the background. Specifically, I'm running a remote REPL, which requires running (##repl-debug-main) after setting it up for the TCP ports. Once you call this function, you don't return from it until you exit the REPL, AFAIK.
I see how you could use SDL timers to call at certain intervals some Scheme code "in the background", but this code will be run in a different thread, breaking Gambit. You can avoid running the function in a different thread as explained here http://wiki.libsdl.org/SDL_AddTimer?highlight=%28\bCategoryAPI\b%29|%28SDLFunctionTemplate%29
but that would block Gambit until (##repl-debug-main) exits, since is not running in a different Gambit thread.