[gambit-list] Gambit and event-based systems

Estevo euccastro at gmail.com
Thu Aug 7 19:19:23 EDT 2014


One thing I'd try would be to launch a gambit thread running
##repl-debug-main and set up a timer or idle handler in the main gambit
thread that just 'thread-sleep!'s for a small amount of time.  Hopefully
experimentation yields a delay that is small enough to be unnoticeable in
your application, but large enough to give the REPL enough time to do its
work.  If you use a timer for this (or, I imagine, if you handle timers in
Gambit at all), the trick to run it in the same OS thread would be
required.  I don't know, from the top of my head, whether and how SDL does
idle events.

A fancier approach would be to look up the implementation of
##repl-debug-main and try and see if there are any hooks by which the trick
I mentioned in the previous message could be enabled.  If there are not,
you could try running your own modified version of ##repl-debug-main
(factoring out the hooks that would enable the
just-wait-for-as-long-as-the-REPL-is-doing-actual-work trick would be a
nice contribution to gambit IMHO).


On Thu, Aug 7, 2014 at 7:06 PM, Álvaro Castro-Castilla <
alvaro.castro.castilla at gmail.com> wrote:

>
> On Thu, Aug 7, 2014 at 6:37 PM, Estevo <euccastro at 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.txt
>
> It 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
> <http://wiki.libsdl.org/SDL_AddTimer?highlight=%28%5CbCategoryAPI%5Cb%29%7C%28SDLFunctionTemplate%29>
> but that would block Gambit until (##repl-debug-main) exits, since is not
> running in a different Gambit thread.
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20140808/17bbc67d/attachment.htm>


More information about the Gambit-list mailing list