[R] Event handling in R
Henrik Bengtsson
hb at biostat.ucsf.edu
Wed Dec 21 14:28:44 CET 2011
Hi.
On Wed, Dec 21, 2011 at 4:20 AM, beetonn <Nicholas.Beeton at utas.edu.au> wrote:
> Thanks, Henrik! That's given me some food for thought, and evalWithTimeout certainly seems to be a nicer way of doing this than setTimeLimit.
>
> I should probably explain a little more clearly: I want to stop getGraphicsEvent() without stopping the program flow (assume we're running the code from a source file) - hence the error catching in my example. If we allow the exception through, it stops the program (which I don't want) but stops getGraphicsEvent() properly, meaning we can run it again (which I do want).
>
> If we don't, the exception is caught and getGraphicsEvent() keeps running - meaning we can't run it again without it throwing a recursion error.
>
> To illustrate, if we set up with:
>
> library(R.utils)
> plot(0)
> eventEnv <- getGraphicsEventEnv()
> setGraphicsEventHandlers(prompt = 'Test')
>
> and then
>
> while (TRUE) evalWithTimeout( {out <- getGraphicsEvent();}, timeout=1, onTimeout="error")
>
> it crashes out of the loop with a time-out error.
>
> If we instead use
>
> while (TRUE) evalWithTimeout( {out <- getGraphicsEvent();}, timeout=1, onTimeout="ignore")
>
> it throws a recursion error after running getGraphicsEvent() for the second time.
Ok, I see, so this issue has nothing to do with the timeout per se.
It looks as if the sanity checks of the internal getGraphicsEvent()
code believes getGraphicsEvent() was called from one of the event
functions (e.g. onKeybd), which is not the case. Looking at the
internal code:
do_getGraphicsEvent(SEXP call, SEXP op, SEXP args, SEXP env) {
...
if (dd->gettingEvent)
error(_("recursive use of getGraphicsEvent not supported"));
...
}
It seems that 'gettingEvent' is not reset to FALSE in case of a
timeout - only if a graphics event occurs (or something like that). I
don't know if there is a way to reset it manually. I've cc:ed Duncan
Murdoch, who I believe wrote these handlers.
>
>
>
> By the way, I may have found a bug in evalWithTimeout - there is a line
>
> else if (onTimeout == "silent") {
>
> but "silent" is not one of the allowed arguments to the function. I changed this to "ignore" and it seemed to work fine.
Thanks for pointing this out. In the next release (R.utils v1.9.7),
onTimeout="silent" will be one to use. (The term "ignore" is a bit
ambiguous).
/Henrik
>
>
> Cheers,
> Nick
>
>
>> ...because you're catching the timeout error with try() so it
>> has not
>> effect, and hence the while(TRUE) {} loop keeps running.
>>
>> Without knowing anything about graphics event handlers per se, here's
>> an alternative to catch the timeout event:
>>
>> library("R.utils");
>>
>> plot(0, 0);
>> eventEnv <- getGraphicsEventEnv();
>> setGraphicsEventHandlers(prompt='Test');
>>
>> q <- NULL;
>> evalWithTimeout({
>> q <- getGraphicsEvent();
>> }, timeout=1);
>> print(q);
>>
>> does it. See print(evalWithTimeout) to see what you are
>> doing differently.
>>
>> My $.02
>>
>> /Henrik
>>
>> On Thu, Dec 15, 2011 at 9:49 PM, beetonn
>> wrote:
>> > Dear R-helpers,
>> >
>> > I've just started playing with getGraphicsEvent() in R, and
>> was wondering if there is a simple way to stop this function
>> waiting for input after a pre-defined time, instead of relying
>> either on a non-NULL value from one of the event handlers or for
>> a user-interrupt for it to halt (as per the R manual).
>> >
>> > The only way that I've thought of to make this work is using
>> setTimeLimit to kill the function after a set time - here's a
>> (messy) example:
>> >
>> > setTimeLimit(cpu = 1)
>> > plot(0, 0)
>> > eventEnv <- getGraphicsEventEnv()
>> > setGraphicsEventHandlers(prompt = 'Test')
>> > while(TRUE)
>> > {
>> > err <- try(q <- getGraphicsEvent(), silent=TRUE)
>> > print(err)
>> > }
>> > # Not run
>> > setTimeLimit(cpu = Inf)
>> >
>> > but setTimeLimit doesn't seem to kill getGraphicsEvent()
>> properly, as running this code just ends up with the repeated
>> returned error of "Error in getGraphicsEvent(): recursive use of
>> getGraphicsEvent not supported" instead of the intended "Error:
>> reached CPU time limit" every second.
>> >
>> > Is there a way to get around this problem, or a different
>> method to make this work? Or should I quit dabbling in things
>> beyond my ken?
>> >
>> >
>> > Thanks,
>> > Nick
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
More information about the R-help
mailing list