On May 31, 2011, at 5:23 PM, Thomas Friedrichsmeier wrote:

> On Tuesday 31 May 2011, Simon Urbanek wrote:
>> The history entries are somewhat in a grey area, because most GUIs use
>> their own implementation of history (and thus they are irrelevant) and the
>> *history() commands are documented to only use readline-backend. That
>> said, they could be easily used by all GUIs if the Windows code is
>> amended.
> 
> Actually, I would suggest to use a different solution, though: This is not 
> really a problem that needs to be addressed on a low level of pointers to C 
> functions. Perhaps it would make more sense to allow to set some R 
> function(s) 
> to handle these via options() (or perhaps via a dedicated gui.options()).
> 

I suppose, yes, it's possible, but I see somewhat of an asymmetry if done that 
way : GUIs are like plug-ins in that there is a set of functions they have to 
implement to work properly. In the current state this is done using the C-level 
hooks, but they are incomplete in that some of the required hooks are not 
available on all platforms. However, if you introduce an additional layer of R 
function hooks, there will be two sets of competing ways for the GUI so 
register and some of them are simply not feasible on the R level (console 
handling, for example, which is why we have C-level hooks). It also makes the 
GUI unnecessary messy, since they will need to provide both C code and R code, 
where the R code essentially just points to C code, practically replicating 
what the C-level hooks would do (just more complicated as it requires embedded 
symbol registrations etc.).

Currently I'm more inclined to make the hooks cross-platform (maybe conditional 
on the GUI type set to "custom" or something like that). But if someone wants 
to devise some nice way of customizing parts using R callback, I won't oppose 
it.


>>> - utils::select.list() and utils::menu(): I want to show my own UI if
>>> graphics==TRUE. Currently, select.list() has special code for windows,
>>> "aqua" and tcltk; menu() essentially assumes the same code. Give me a
>>> way to run register my own UI.
>> 
>> ptr_do_selectlist provides the customization and could be extended to other
>> platforms.
> 
> See above. But yes, if at least it was cross-platform, that would be nice.
> 
>>> - base::system(), base::system2(): As you will be aware, capturing the
>>> output of system commands in a GUI is tricky on Unix. I do have a
>>> solution for that, but I need to run synchronization code at the start
>>> and end of system() and system2(), in order to get interleaving right.
>>> Give me a hook, each, at the start and end of these functions.
>> 
>> I'm not sure I understand your concern here. What exactly is your worry?
>> Capturing output is trivial since it simply involves creating a pipe when
>> you initialize R which you can read while R is running and the
>> synchronization is provided by the OS, no magic involved.
> 
> Is that pipe buffered?

No (although you could buffer it if you wanted).


> In my setup it is. And so consider code like this:
>   for (i in 1:10) {
>       print (i)
>       system (paste ("echo", i)) 
>   }
> How do you ensure that this results in
> 1
> 1
> 2
> 2
> ...
> rather than e.g.
> 1
> 2
> 3
> 1
> 2
> 4
> 3
> 5
> 6
> ...
> 

In R the output will be 
1
1
2
2
by design - system() is synchronous, so stdout will arrive between the 
WriteConsole calls - try in the the R for Mac GUI and you'll see:

>   for (i in 1:10) {
+       print (i)
+       system (paste ("echo", i)) 
+   }
[1] 1
1
[1] 2
2
[1] 3
3
[1] 4
4
[1] 5
5
[1] 6
6
[1] 7
7
[1] 8
8
[1] 9
9
[1] 10
10
> 

Obviously, for wait=FALSE all bets are off. [Note: although the Mac GUI uses a 
hook for system, it is to run commands as root, not to do any special handling 
of I/O].


> I could not get it to work for RKWard without adding code to make sure the 
> "other" output is flushed.

If you have issues with stdout buffer before the pipe, use can use setvbuf() to 
disable buffering.


> (Note: I'm capturing regular R output via 
> R_WriteConsoleEx, since I am interested in the differentiation between output 
> types that this provides. So I cannot simply push that down the same pipe.).
> 
>>> - graphics::plot.new(): I need a hook *before* the new plot is started,
>>> in order to properly implement device-independent plot history. I would
>>> appreciate not having to implement my own graphics device just to be
>>> able to run some code at this point.
>>> 
>>> - grDevices::dev.off(): I need a hook before the device is closed. Also
>>> for plot history.
>>> 
>>> - grDevices::dev.set(): I need a hook after the new device has been set.
>>> Also for plot history.
>>> 
>>> - grid::newpage(): See graphics::plot.new(). Of course, even better, I
>>> would like to have a hook that is called every time before a new page /
>>> frame is started on a device.
>> 
>> For all of the above: all of them are already available a device callbacks
>> (newPage, close, activate and newPage again).
> 
> Quoting myself: I would appreciate not having to implement my own graphics 
> device just to be able to run some code at [these] point[s].
> 

Cautiously I would argue you have to the moment you're outside R, essentially 
since the built-in graphics devices are not guaranteed to work when embedded. 
In practice, I think if you write a GUI, you have to provide a GD - that is the 
only reasonable way you can seamlessly incorporate R graphics into your GUI.

That said, there is a precedent for graphics hooks. The problem I see is the 
same that became apparent with grid last time we added hooks - there are 
potentially multiple ways to get to the same C level point, and they are either 
easily forgotten, or even hard to enumerate. For example, dev.set() is not the 
only way to activate a device - it can be activated from the menu and other 
means via selectDevice() which is at C level, so there is no R code involved at 
all, thus setting a hook on dev.set() is will work only in a  subset of cases 
and thus you cannot expect consistency in your GUI.

(Note: none of my comments are specific to RKWard, since it is not even 
available for OS X so I don't know anything about it)

Cheers,
Simon

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to