ntoronto / pict3d

3-dimensional picts
GNU Lesser General Public License v3.0
113 stars 23 forks source link

Displaying pict3d% instances in the REPL fails on HEAD #28

Closed lexi-lambda closed 9 years ago

lexi-lambda commented 9 years ago

When using HEAD or the snapshot builds for version 6.2.0.3, attempting to display a pict3d% instance directly in the REPL fails with the following error:

write: copying pict3d% instances is not supported

Note that manually calling (display ...) or (write ...) on a pict3d% instance works fine; the error only occurs when the raw instance is printed in the REPL.

ntoronto commented 9 years ago

Yes, Robby broke my snips.

I'm not sure when they'll be working again. Fixing them on this end would require serializing and unserializing Pict3D instances, which aside from taking a long time to code, would be tricky. (Shapes in a Pict3D's scene database contain a function table.)

Sorry about this.

lexi-lambda commented 9 years ago

I'm curious—could you direct me to a commit or some other source of information about what specifically breaks them? I just find it odd that they work totally fine if I call display on them, but they fail when used directly.

ntoronto commented 9 years ago

Interesting! Plots work interactively if you send them to display, too. This is probably unintentional, and they should also have been broken.

The change to DrRacket is https://github.com/racket/drracket/commit/01a19794ff9ab8188c0eb269b0ab12509096de1a. That won't tell you much, though.

The idea is to close a "security hole" in DrRacket that's been there for a long time. DrRacket generally does a great job separating programs from each other using custodians, custom evaluators, etc. (I don't know the details.) But snips, such as Pict3D's interactive display, have never been separated like that. To display them in the REPL, DrRacket makes a copy of them and then runs the copy's code in DrRacket's thread and eventspace. There's no memory accounting, no way to cancel a runaway snip's execution, and no protection of DrRacket's internals.

Snips have always been meant to be saved in files, so they need to know how to serialize themselves. (An example is the fraction snip. If you run (/ 1 7) in the REPL and copy the result into a code file and save it, when you open it, it'll still be a fraction snip.) Robby's recent change makes DrRacket serialize and unserialize snips instead of just copying them, probably to keep them from interacting with other running code. I'm sure it's only the first of many changes.

But Pict3D (and plot) snips have never known how to serialize themselves. Their write method raises the error you got.

Having no control over a snip's execution has bitten me a few times, which is why I'm not wigging out about this and demanding that Robby fix it. He's working with me on it. Please stand by.

soegaard commented 9 years ago

Is there a chance that this could improve the situation for picts representing images produced by the FFI bindings to Poppler?

A little more detail: The poppler library receives a raw Cairo context and draws directly on it. This implies that DrRacket shows nothing (since it uses record-dc% to copy snips, and record-dc% has no chance of recording what Poppler does.)

My workaround in the DrRacket REPL has been to convert to bitmaps. ( https://github.com/soegaard/racket-poppler )

ntoronto commented 9 years ago

Robby has just pushed an evil hack that makes Pict3D instances display properly again. Closing.