/* * Synchro.java - An applet to graphically illustrate synchro lists. * * Copyright (c) 1998, Chuck McManis, all rights reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL purposes and without * fee is hereby granted provided that this copyright notice * appears in all copies. * * CHUCK MCMANIS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. CHUCK MCMANIS * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT * OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ import java.awt.*; import java.awt.event.*; import java.applet.*; import java.util.Random; import java.util.Enumeration; import java.util.Vector; /** * This is a relatively complex applet that starts some threads that * manipulate a synchronized lists and displays the state of the list * during manipulation. */ public class Synchro extends Applet { Image offscreen = null; Graphics gcx = null; SynchroList myList; TickMe clockTicker; ListWriter writer1 = null; Thread readers[] = new Thread[3]; class TickMe extends Thread { Applet thisApplet; public boolean runstate; TickMe() { runstate = true; } public void run() { while (clockTicker == Thread.currentThread()) { repaint(); // this is so cool, its the applet's repaint method! try { sleep(200); } catch (InterruptedException e) { break; } } } } class ListWriter extends Thread { int delay; public boolean active; ListWriter(int dd) { super(); delay = dd; } public void run() { Random r = new Random(); active = true; while (writer1 == Thread.currentThread()) { for (int i = 0; myList.size() < 50; i++) { myList.add(new Integer(r.nextInt() % 50)); try { sleep(100); } catch (InterruptedException e) { break; } } System.out.println("Done writing list."); try { sleep(5000); } catch (InterruptedException e) { break; } for (int i = 0; myList.size() > 10; i++) { myList.delete(new Integer(r.nextInt() % 50)); try { sleep(100); } catch (InterruptedException e) { break; } } } } } Vector reader_list[] = new Vector[3]; final static int BOX_SIZE = 10; final static int BORDER_SIZE = 1; class ListReader extends Thread { int reader_id; Integer low, high; public boolean active; ListReader(int rangeLow, int rangeHi, int lst) { super(); low = new Integer(rangeLow); high = new Integer(rangeHi); reader_id = lst; } public void run() { while (readers[reader_id] == Thread.currentThread()) { Enumeration e1, e2; Vector v; Object oo; e2 = myList.elements(low, high); v = myList.stateEnum(low, high); if ((v != null) && (v.size() > 0)) { reader_list[reader_id] = v; repaint(); while (true) { Object o = e2.nextElement(); try { sleep(300); } catch (InterruptedException e) { break; } if (o == null) break; } } else { try { sleep(500); } catch (InterruptedException e) { } } } System.out.println("Reader "+reader_id+" exiting."); } } class AnotherReader extends Thread { int reader_id; int low, high; int delta; AnotherReader(int rangeLow, int rangeHi, int size, int lst) { super(); delta = size; low = rangeLow; high = rangeHi; reader_id = lst; } public void run() { Enumeration e1, e2; Vector v; Object oo; Integer startingPoint = new Integer(0); Integer endingPoint = new Integer(0); while (readers[reader_id] == Thread.currentThread()) { for (int pos = low; pos+delta/2 < high; pos += delta/2) { startingPoint = new Integer(pos); endingPoint = new Integer(pos+delta); e2 = myList.elements(startingPoint, endingPoint); v = myList.stateEnum(startingPoint, endingPoint); if ((v != null) && (v.size() > 0)) { reader_list[reader_id] = v; repaint(); while (true) { Object o = e2.nextElement(); try { sleep(300); } catch (InterruptedException e) { break; } if (o == null) break; } } else { try { sleep(500); } catch (InterruptedException e) { } } } } System.out.println("Reader "+reader_id+" exiting."); } } //Get a parameter value public String getParameter(String key, String def) { return (getParameter(key) != null ? getParameter(key) : def); } //Construct the applet public Synchro() { } //Initialize the applet public void init() { resize(500, 300); myList = new SynchroList(new IntCompare()); } //Start the applet public void start() { System.out.println("Starting the Synchro applet."); clockTicker = new TickMe(); clockTicker.start(); writer1 = new ListWriter(250); writer1.start(); readers[0] = new ListReader(-10, 50, 0); readers[0].start(); readers[1] = new ListReader(-50, 10, 1); readers[1].start(); readers[2] = new AnotherReader(-50, 50, 20, 2); readers[2].start(); } private void drawbox(Graphics g, int x, int y, Color c) { g.setColor(Color.black); g.drawLine(x, y, x, y+BOX_SIZE); g.setColor(c); g.fillRect(x+1, y, BOX_SIZE-2, BOX_SIZE); g.setColor(Color.black); g.drawLine(x+BOX_SIZE-1, y, x+BOX_SIZE-1, y+BOX_SIZE); } private void drawState(Graphics g) { int x = 50, y = 40; Color nodeColor; g.setColor(Color.blue); g.drawString("SyncroList Demonstration Applet", 0, 30); Vector yy = myList.stateEnum(); x = 0; for (int i = 0; (yy != null) && (i < yy.size()); i++) { State s = (State)(yy.elementAt(i)); switch (s.players) { case 0: nodeColor = Color.green; break; case 1: nodeColor = Color.yellow; break; case 2: nodeColor = Color.orange; break; default: nodeColor = Color.red; break; } if (s.blocking) { nodeColor = Color.blue; } drawbox(g, x, y, nodeColor); x += BOX_SIZE; } for (int q = 0; q < reader_list.length; q++) { if (reader_list[q] != null) { for (int i = 0; i < reader_list[q].size(); i++) { State dx = ((State) reader_list[q].elementAt(i)); drawbox(g, dx.pos*BOX_SIZE, 41+BOX_SIZE + (q*(BOX_SIZE+1)), Color.green); } } } } public void paint(Graphics g) { update(g); } public void update(Graphics g) { if (offscreen == null) { offscreen = createImage(500, 300); } gcx = offscreen.getGraphics(); gcx.setColor(Color.lightGray); gcx.fillRect(0,0,500,300); drawState(gcx); gcx.dispose(); g.drawImage(offscreen, 0, 0, null); } //Stop the applet public void stop() { clockTicker = null; writer1 = null; for (int i = 0; i < readers.length; i++) readers[i] = null; } //Destroy the applet public void destroy() { } //Get Applet information public String getAppletInfo() { return "Applet Information"; } //Get parameter info public String[][] getParameterInfo() { return null; } }