This demo application uses the Java PlugIn support to show how easy it is to code a multi-user application using TSpaces. Refer to the programming details below.
Use the Mouse to draw 1 or more lines or sets of points.
Press "Publish" to send your masterpiece to everyone else that is running the demo.
Press "Erase" to erase the lines that you drew since the last Publish.
Press "EraseALL" to erase the all the Whiteboards. Note: This
will erase everyone's whiteboard, not just yours!
TupleSpace.appletEnvironment(true); TupleSpace TSServer; TSServer = new TupleSpace("Whiteboard", Host,Port);The appletEnvironment(true) statement indicates that this is an applet environment, We then call the TupleSpace constructor which will access the TupleSpace named "Whiteboard" on the indicated Host:Port. If the TupleSpace does not exist, it will be created.
Tuple match = new Tuple("Whiteboard", new Field(Vector.class), new Field(Vector.class) );This creates a Tuple template object that will be used to match requests that we are interested in. This template indicates that we are interested in tuples that have 3 Fields. The first contains a String equal to "Whiteboard" and the 2nd and 3rd fields contain Vector object references.
int seqNum = TSServer.eventRegister(TupleSpace.WRITE,match, this);The eventRegister() method indicates the TupleSpace operation that we are interested in and the template that the related Tuple must match. The 3rd parameter is a Callback object that has a call() method that will be given control when the event occurs. In this case, the current class implements the Callback interface and is given control when anyone writes a matching Tuple to TSpaces.
Tuple tupleSet = TSServer.scan(match); if ( tupleSet != null) { Enumeration e = tupleSet.fields(); while (e.hasMoreElements() ) { Field f = (Field)e.nextElement(); Tuple tuple = (Tuple)f.getValue(); lines = (Vector)tuple.getField(1).getValue(); colors = (Vector)tuple.getField(2).getValue(); ... } }Because TSpaces is a database, it has stored all the line and color Vectors that have been generated by other users. So during initialization, we will read all the current line and color Vectors stored at the TSpaces server. The first line above issues the scan request to the tupleSpace using the template from earlier. This returns a tuple whose fields are each tuples, one for each tuple that matched the template. The fields() method returns an enumeration that can be followed to access each individual Tuple. Once the individual Tuple is accessed, the getField(int). getValue() method is used to access the line and color Vectors from the 2nd and 3rd field. The Vectors are then used to paint the initial contents of the panel.
try { Tuple publish = new Tuple("Whiteboard", linesNew, colorsNew); TSServer.write(publish); } catch(TupleSpaceException tse) { System.out.println("TupleSpaceException: " + tse.getMessage()); }When the user presses the Publish button, the collection of user actions since the last publish are contained in the "linesNew" and "colorsNew" Vector objects. A Tuple is created with "WhiteSpace" as the 1st field and Vector references as the 2nd and 3rd Field. The write(tuple) command is then used to write the tuple to the TupleSpace.
Note that the typical "try{} catch (TupleSpaceException tse) {}" blocks are included here. Although they were not shown earlier, catching TupleSpaceException is required for all TSpaces operations.
public class WhiteboardPanel extends Panel implements MouseListener, MouseMotionListener, Callback { public synchronized boolean call(String eventName_, String tsName_, int sequenceNumber_, SuperTuple tuple_, boolean isException_) { try { lines = (Vector)tuple_.getField(1).getValue(); colors = (Vector)tuple_.getField(2).getValue(); } catch(TupleSpaceException tse) { ... return false; } ... process return false; } }The registerEvent method described earlier, gave this class as the Callback object that was responsible for processing the events. So the class statement for WhiteboardPanel states that it implements the Callback interface. The Callback interface requires the implementation of a call method that is shown above. The call method is passed the Tuple that was written to TupleSpace so that all that is needed is to process the fields of the Tuple.
try { linesNew = new Vector(20); colorsNew = new Vector(20); TSServer.write("Whiteboard", linesNew, colorsNew); TSServer.deleteAll(); } catch(TupleSpaceException tse) { ... }This sends an empty vector to the other clients as a signal that an erase has occurred and then deletes all the stored Tuples from the database.
The above is all of the TSpaces code that is required to support both the network and database requirements for a multi-client application. multi-client application.