[racket] Saving and restoring many parameters
Executive summary: Is there a good way to save a large set of parameter
values, or *all* the parameter values, and then restore them when needed?
In the new PLoT, much of a plot's appearance is controlled by
parameters. I use parameters because there are so many
appearance-controlling values that passing them into the plot area as
arguments would get silly very quickly. I dislike functions with 20
arguments, and I *really* dislike duplicating all those arguments in
every function in a call chain. Parameters are a perfect remedy.
There's one problem, though: to produce a slideshow pict of a plot, I
need to do this:
(dc (lambda (the-dc x y)
(plot/dc ... the-dc x y ...)) ...)
where 'plot/dc' draws a plot on a device context. Because the call to
'plot/dc' is in a thunk, it gets the *current* parameter values, which
is very wrong. That makes it impossible to, for example, change the
background color of only one plot in a slideshow by doing
(parameterize ([plot-background "red"])
(plot-pict ...))
The problem is that the pict returned by 'dc' calls the drawing thunk
*after* the dynamic scope in which 'plot-background' is "red".
To fix the problem, I'm doing this:
(define foreground (plot-foreground))
(define background (plot-background))
(define foreground-alpha (plot-foreground-alpha))
(define background-alpha (plot-background-alpha))
(define font-size (plot-font-size))
...
(define animating? (plot-animating?))
(dc (lambda (the-dc x y)
(parameterize ([plot-foreground foreground]
[plot-background background]
[plot-foreground-alpha foreground-alpha]
[plot-background-alpha background-alpha]
[plot-font-size font-size]
...
[plot-animating? animating?])
(plot/dc ... the-dc x y ...))) ...)
Besides looking evil, it's barely maintainable. Every time I add an
appearance-controlling parameter, I have to remember to add it to the
above incantation. (Actually, there are two.)
I've had a similar problem with the click-and-drag-to-rotate 3D plots.
Because I was already using threads for that, I just made sure the
render thread is always (transitively) a child of the thread in which
the call to 'plot3d' was made. It therefore inherits the original
parameter values.
So I can use threads to save parameter values. I could make a render
thread to solve my 'plot-pict' problem. But is there a better way?
Neil T