=== Top of the Swiki === Attachments ===

Nebraska

Nebraska is a toolkit for building remote interactions with Morphic in Squeak. It is modelled somewhat after Kansas, although as yet it's a much simpler system. There is a shared world on some server on a network, and other people can connect to that world from afar. Whenever the shared world tries to draw to its screen, it sends drawing commands across the network. Whenever a user tries to perform a mouse or keyboard interaction, those interactions are forwarded to the server where a RemoteControlledHand acts on their behalf.

The status is that you can do useful things and even develop code remotely. The performance is reasonable over a local T1 connection (I haven't actually tested it otherwise....) However, some things don't work. Many things still draw to the server's world instead of the shared world. And I haven't even touched 3D.

It's being worked on by Lex Spoon. It's being integrated with Squeak Central new collaborative system under the name "Midwest Telemorphic" by Bob Arning -- stay tuned!

Getting the Code

Load the following code, in order:
WARNING: the last changeset changes around some system code, so you may not want to load it into your main image.


Trying it out


To start a server, execute the following code:
| server |server := NebraskaServer new.
server startListeningOnPort: 9091.
(NebraskaServerMorph new server: server) openInWorld.
Feel free to run it on another port than port 9091.

To start a client, run the following in another image:
NetworkTerminalMorph openAndConnectTo: 'servername' port: 9091

Fill in your server's hostname for 'servername'. At this point, everything should be working!

NOTE: if you want to have a local view of the server, you shouldn't use the TCP connections. The problem is that the server will occasionally do a #flush, and it won't work due to single threading. The better solution is to use a LoopBackStringSocket instead of a regular StringSocket, but there is no handy method for that right now....

Small Tweaks


Accessing the Shared World Progammatically


You can access the shared world with Smalltalk code on the server. Just do "server sharedWorld". For example, you can use this to add some morph you want to edit to the world:

| server |server := NebraskaServer new.
server startListeningOnPort: 9091.
server sharedWorld addMorph: (some morph).
(NebraskaServerMorph new server: server) openInWorld.

Changing the Size of the Shared World


The proper way to change the size of the shared world is as follows:
server extent: 600@400 depth: 32
The server will broadcast the change to all connected clients.


Architecture


The basic system provided here isn't the only possible scenario this toolkit can be used for. For example, you may wish to make Nebraska the main UI for the system and allow project switches inside of the shared world. You may wish to make a client image which automatically connects to some server. There are lots of possibilities for the components herein.


StringSocket

StringSocket's are wrappers around regular sockets that allow sending arrays of strings. I have found this more convenient that dealing with raw binary streams. The encoders and decoders use StringSocket's instead of talking to Socket's directly.


CanvasEncoder/CanvasDecoder

CanvasEncoder accepts canvas commands, encodes them into string arrays and forwards them over an underlying string socket. CanvasDecoder does the opposite, decoding string arrays and drawing onto an actual canvas.

There are two commands other than drawing commands that CanvasEncoder/Decoders work with. First, they handle screen resizes. Second, they handle "force to screen" commands.


RemoteCanvas

A RemoteCanvas wraps a CanvasEncoder, and has a clipping rectangle and a transformation associated with it. Whenever you draw to a RemoteCanvas, it will first establish the clipping rectangle and transformation, and only then will it forward the actual drawing commands. The purpose of RemoteCanvas, instead of just having CanvasEncoder, is to allow multiple clipping rectangles and transformations to be live at the same time. However, clip rectangles and transformations don't work perfectly at the moment, so this part of the system might change....

MorphicEventEncoder/Decoder

These classes encode and decode MorphicEvents, similar to CanvasEncoder/Decoder.

RemoteControlledHandMorph

This is similar to RemoteHandMorph. It accepts events from a MorphicEventDecoder, and acts on those events.

NetworkTerminalMorph

A NetworkTerminalMorph is a simple morph which accepts drawing commands from a CanvasDecoder, and which forwards all events sent to it to a MorphicEventEncoder.

NebraskaPasteUpMorph

NebraskaPasteUpMorph is a variant of PasteUpMorph which has an additional set of remote canvases. The most notable difference from a regular PasteUpMorph is that #assuredCanvas builds a canvas out of these remote canvases, instead of building a FormCanvas on the Display.


NebraskaServer and NebraskaServerMorph

These are the heart of the server setup described above. The server does basic things like accepting new connections and updating the underlying NebraskaPasteUpMorph whenever the set of clients changes. The ServerMorph at this time mostly just step's the server periodically.

Other Kinds of Canvases

There are several kinds of canvases floating around in the system that others might find useful. There are: