Sunday, February 22, 2009

Low-level graphics in Squeak

It wasn't until I dug into how low-level graphics worked in Squeak that I realised how trivial it was.

To draw on the screen, use the global variable "Display". This is an instance of a subclass of Form. A Form is a bitmap. To draw on Forms, you use "BitBlt" instances, which represent drawing commands.

For handling events from the mouse and keyboard, you use the global variable Sensor, which is an instance of EventSensor. In a loop, you call EventSensor>>nextEvent to get the next event, which is either "nil" or the next keyboard or mouse event. Yes, you need to poll it, and if you don't want to use 100% CPU, then you need to suspend your thread for, say, 20ms on every iteration.

Except for the details, that's all you need to do to draw on the screen and handle events. There's plenty of example code in a stock Squeak image.

Now comes the tricky part: how do you wrestle control of these objects from Morphic? Well, as it turns out, Morphic wasn't designed in the resiliant, secure and reactive way I would have designed it. Morphic is single threaded! When you run your code, you're running it in the same Process that handles event handling and screen drawing! So if you never return from your event polling loop, Morphic never runs (unless a Transcript is open and you write something to it).

I find the single-threadedness of Morphic rather quaint.

Alternatively, you can use:
Project uiProcess suspend. "This suspends the Morphic process; make sure your code runs in another process!"
Project spawnNewProcess " If you terminated the Morphic process, this makes a fresh one. "

No comments: