Squeak
  links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
Nebraska
Last updated at 10:22 pm UTC on 12 July 2007
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.

Nebraska was originally written by Lex Spoon, and has since been greatly updated by BobArning. In particular, there is now much better support for bitmap-based graphics. If you downlaod Squeak 3.0 or newer, then you'll have Nebraska. Have fun!


The Nebraska UI


The user interface to Nebraska is fairly simple. First, decide which machine is going to be the "server". Server in this case means the machine whose world will be shared with the client(s).

Requirements:


Steps:

On the server machine, hit the "Share" button on the orange navigator strip. A small morph will appear in the upper left of the display. This has controls for ending the Nebraska session (the X button) plus some information about the connected clients.

On each client machine, you will need a "badge" representing the server. If you don't already have one available (you probably don't), then get an EToySenderMorph from the new morph/experimental menu. This pink thing is often referred to as a badge and is the central point for many of the collaborative facilities in Squeak. Click on the area of the badge containing the IP address. Put the IP address for the server in the resulting dialog and hit Accept. On the bottom of the badge is a row of small colored buttons. The "S" button on the right end of this row is the button to connect you to the world represented by the badge. Press it now. The first thing you will see is a rectangle with an orange border. The server's world will appear within this border as soon as the data is received. You can resize the orange frame using the yellow resize handle from the halo (cmd-click or alt-click on the frame). There is also a small yellow palette of buttons floating above the server display.


Niceties:

If the server has a badge representing the client, then the client's name and/or picture will be associated with the client's cursor. If not, '???' will be used.


Trying it out

Programatically


Boris Gaertner March 10, 2005 The correct way to create an instance of NebraskaServer is either
  NebraskaServer serveWorld: World
or
  NebraskaServer serveWorld: World onPort: 
These initialize the instance, but a simple NebraskaServer new does not. To open a NebraskaServerMorph, it is seemingly sufficient to write:
  NebraskaServerMorph serveWorld: World onPort: 9091.
This creates a server, registers it with the current world and opens the morph. The morph in turn obtains the server from the current world. A bit tricky, but it works.
Blake These all DNU in the exact same place:
 world extent: newExtent.
BFAV2 Release 2.30 Nebraska should be in the image allready. Open the navigator flap and click on 'share' and the current project is shared over the network. Note that the SqueakLogo which is a FlashMorph will give a error if present. Get rid of the logo
or open a new project and share that.

Blake OK, so importing the Nebraska from the swiki page broke the installed Nebraska.I've often wondered about the "Share" thing. It works in a clean 3.7 install. And, if I comprehend correctly, it sets up a Squeak as a server
on 9091. The code for connecting programmatically seems to work. Cool.

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....

Playing with Nebraska (Lex Spoon)

Here are some things you can glue together, once you have the efficient remote interaction Nebraska gives you.
  1. You can give people flaps that live on the local machine, and let them drag and drop things into and out of the shared world.
  2. Conversely, you can swap modes and have the shared stuff be in a flap, for times when you are primarily working locally but want to have a collaboration window available.
  3. You can have a large shared world that is scrollable, like the original Kansas (in fact, the reason Kansas got its name). This way multiple people can really bump elbows. :)
  4. You could set it up to display only, and thus have a very efficient format for Squeak movies or Squeak streaming presentations.

There are also other nice things that could be done:
  1. NetworkTerminalMorph should have a border, so that you can interact with it on the client.
  2. The password-handling code I posted a while ago should be integrated into the main system.

Have a blast! Nebraska is just one of a load of components in Squeak
that you can combine in lots of interesting ways. A little bit of
programming can take you a long way, if you are programming in Squeak.

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.

This interface is extremely simplistic right now, but it shows how the system can be used....

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.

(Nowadays, regular PasteUpMorphs are used. Lex hasn't worked out the exact mechanism that is used nowadays, but the result is that you can share a regular PasteUpMorph – including the current World !)

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 made for this system along the way.


Extensions

NebraskaPassword.cs.gz
Nebraska.sar
NebraskaRemoval.sar