On Mon, Jul 1, 2019 at 11:40 AM Thomas Dickerson <
thomas_dicker...@alumni.brown.edu> wrote:

> On Fri, Jun 28, 2019 at 5:50 PM Philip McGrath <phi...@philipmcgrath.com>
> wrote:
>
>> Again, this part works just fine. In particular, because of the way Racket's
>> submodules
>> <https://docs.racket-lang.org/reference/eval-model.html#%28part._submodules%29>
>> work, the code in the "main" submodule *does not* run when you
>> instantiate the parent module, whether via `scheme_dynamic_require`,
>> `dynamic-require`, `require`, or some other way: the compiled form of the
>> submodule need not even be loaded into memory. So you can use rendering
>> code in the main submodule without creating a dependency for your main
>> application.
>>
>
> Specifically, this means we can avoid byte-compiling and loading any
> graphics modules the main submodule depends on, yes?
>

I believe the main submodule will still be compiled the enclosing module is
loaded from source, but that should be trivial: it really only needs a
`require` and a function call. If the file has already been compiled to
bytecode, the bytecode for the main submodule won't be loaded, nor for any
of its transitive dependencies.

Depending on how you are distributing your code, you may or may not want to
add an indirection via `dynamic-require` to prevent the distribution
building tools from shipping graphics libraries that you only need for the
main submodule. (Basically this would be the reverse of what
`racket/runtime-path` does.) I haven't done much with the tools for
distributing built artifacts beyond toy experiments, but I think some of
them may be able to do that stripping automatically or with e.g. a
command-line flag, without needing a `dynamic-require`. At the maximum, you
could put the graphics modules in their own package, analogous to the
`foo`+`foo-lib`+`foo-doc`+`foo-test` convention: in that case, the support
library for your main submodule (what I called
`hypothetical-lanugage/private/render`) would just be a stub to
`dynamic-require` the `render` function or do something useful if the
graphics package isn't installed, like print a message to standard error.


> It could certainly open a new GUI window, and it could also return a value
>> that renders as an embedded widget (snip) in the interactions pane. (See
>> the plot library for an example.)
>>
>
> Snips seem nice, but even browsing through the source for the 3d renderers
> for plot, I don't see any way to get an OpenGL context for a snip, since
> they appear to work on predefined DCs, rather than allowing you to
> construct a canvas.
>

I haven't used OpenGL, from Racket or otherwise, but it might be possible
to use a bitmap from `make-gl-bitmap` as a buffer for your OpenGL drawing
and copy it to the canvas via `draw-bitmap`. If you have an existing
foreign library that does the actual drawing, you can get a
platform-specific pointer via `gl-context<%>
<https://docs.racket-lang.org/draw/gl-context___.html>`.


> I haven't looked at the DrRacket extension APIs enough to be sure whether
>> you could open a new pane in the DrRacket window, but it certainly seems
>> possible.
>>
>
> Are you aware of any projects that usefully manipulate the interactions
> pane that I could turn to for example code? It looks like it's possible to
> extend that class.
>

I can't think of any examples that manipulate the DrRacket window from
within the program being evaluated. In general, DrRacket goes to a lot of
effort to isolate itself from the programs it runs, which is usually a good
thing. I suspect, though, that a solution would involve your support
library cooperating with an extension set up by your #lang. Communication
might need to go through a non-obvious channel like a logger: Alexis has a blog
post
<https://lexi-lambda.github.io/blog/2019/04/21/defeating-racket-s-separate-compilation-guarantee/>
about a wonderfully devious use for loggers as a communication mechanism,
but they're also used less deviously by e.g. the Future Visualizer
<https://docs.racket-lang.org/reference/futures.html#%28part._future-logging%29>
.

On the whole, though, either returning a snip or creating a new `frame%`
would probably be easier. Using a new `frame%` would also be entirely
independent of DrRacket: I expect it would work with racket-mode for Emacs,
for example.

-Philip

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAH3z3gY0qEB6VyR5xgT83aNgevSjzjMnvznFRVgSF5%2BGHrwpdQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to