// Parallel Computing // // Computer // // Author Matthew Caryl // Created 2.2.97 package Parallel; import java.awt.Graphics; import java.lang.Math; import java.awt.Color; import ADT.Random; import ADT.Queue; import ADT.QueueEmpty; public final class Computer { // // Public interface // public Computer(int width, int height, Random random) { int x, y; processors = new Processor[width][height]; for (x = width - 1; x >= 0; x--) for (y = height - 1; y >= 0; y--) processors[x][y] = new Processor((byte) x, (byte) y, random); // connect north y = 0; for (x = width - 1; x >= 0; x--) { processors[x][y].setPower(0, new Power()); processors[x][y].setInComm(0, new CommunicationQueue()); processors[x][y].setInCommSignal(0, new Wire()); } for (y = height - 1; y >= 1; y--) for (x = width - 1; x >= 0; x--) { processors[x][y].setPower(0, new Power()); processors[x][y].setInComm(0, processors[x][y - 1].getInComm(2)); processors[x][y].setInCommSignal(0, processors[x][y - 1].getInCommSignal(2)); } // connect east x = width - 1; for (y = height - 1; y >= 0; y--) { processors[x][y].setPower(1, new Power()); processors[x][y].setInComm(1, new CommunicationQueue()); processors[x][y].setInCommSignal(1, new Wire()); } for (x = width - 2; x >= 0; x--) for (y = height - 1; y >= 0; y--) { processors[x][y].setPower(1, new Power()); processors[x][y].setInComm(1, processors[x + 1][y].getInComm(3)); processors[x][y].setInCommSignal(1, processors[x + 1][y].getInCommSignal(3)); } // connect south y = height - 1; for (x = width - 1; x >= 0; x--) { processors[x][y].setPower(2, new Power()); processors[x][y].setInComm(2, new CommunicationQueue()); processors[x][y].setInCommSignal(2, new Wire()); } for (y = height - 2; y >= 0; y--) for (x = width - 1; x >= 0; x--) { processors[x][y].setPower(2, processors[x][y + 1].getPower(0)); processors[x][y].setInComm(2, processors[x][y + 1].getInComm(0)); processors[x][y].setInCommSignal(2, processors[x][y + 1].getInCommSignal(0)); } // connect west x = 0; for (y = height - 1; y >= 0; y--) { processors[x][y].setPower(3, new Power()); processors[x][y].setInComm(3, new CommunicationQueue()); processors[x][y].setInCommSignal(3, new Wire()); } for (x = width - 1; x >= 1; x--) for (y = height - 1; y >= 0; y--) { processors[x][y].setPower(3, processors[x - 1][y].getPower(1)); processors[x][y].setInComm(3, processors[x - 1][y].getInComm(1)); processors[x][y].setInCommSignal(3, processors[x - 1][y].getInCommSignal(1)); } // connect up for (y = height - 1; y >= 0; y--) for (x = width - 1; x >= 0; x--) { processors[x][y].setInComm(4, new CommunicationQueue()); processors[x][y].setInCommSignal(4, new Wire()); } } public void tick(int c) { for (int y = height() - 1; y >= 0; y--) for (int x = width() - 1; x >= 0; x--) processors[x][y].tick(c); } public void draw(Graphics g, int window_width, int window_height, int scroll_x, int scroll_y, int scrollable_size) { int d = scrollable_size / Math.max(width(), height()); int start_x = -scroll_x / d; int start_y = -scroll_y / d; int finish_x = Math.min(width() - 1, (-scroll_x + window_width) / d); int finish_y = Math.min(height() - 1, (-scroll_y + window_height) / d); int left = scroll_x + start_x * d; int top = scroll_y + start_y * d; for (int y = start_y, t = top; y <= finish_y; y++, t += d) for (int x = start_x, l = left; x <= finish_x; x++, l += d) processors[x][y].draw(g, l, t, d, d); } public void update(Graphics g, int window_width, int window_height, int scroll_x, int scroll_y, int scrollable_size) { int d = scrollable_size / Math.max(width(), height()); int start_x = -scroll_x / d; int start_y = -scroll_y / d; int finish_x = Math.min(width() - 1, (-scroll_x + window_width) / d); int finish_y = Math.min(height() - 1, (-scroll_y + window_height) / d); int left = scroll_x + start_x * d; int top = scroll_y + start_y * d; for (int y = start_y, t = top; y <= finish_y; y++, t += d) for (int x = start_x, l = left; x <= finish_x; x++, l += d) processors[x][y].update(g, l, t, d, d); } public boolean mouseDown(int window_width, int window_height, int scroll_x, int scroll_y, int scrollable_size, int x, int y) { int d = scrollable_size / Math.max(width(), height()); int scrollable_x = scroll_x + x; int scrollable_y = scroll_y + y; if (scrollable_x >= 0 & scrollable_x < width() * d && scrollable_y >= 0 & scrollable_y < height() * d) { int left = scroll_x + (-scroll_x / d) * d; int top = scroll_y + (-scroll_y / d) * d; return processors[scrollable_x / d][scrollable_y / d].mouseDown(left, top, d, d, x, y); } else return false; } public int pixelWidth(int scrollable_size) { int d = scrollable_size / Math.max(width(), height()); return d * width(); } public int pixelHeight(int scrollable_size) { int d = scrollable_size / Math.max(width(), height()); return d * height(); } public int width() { return processors.length; } public int height() { return processors[0].length; } public int maxWidth() { return width() * processors[0][0].maxWidth(); } public int maxHeight() { return height() * processors[0][0].maxHeight(); } public int maxSize() { return Math.max(maxWidth(), maxHeight()); } public int minWidth() { return width() * processors[0][0].minWidth(); } public int minHeight() { return height() * processors[0][0].minHeight(); } public int minSize() { return Math.min(minWidth(), minHeight()); } public Processor processor(int x, int y) { return processors[x][y]; } public static synchronized void registerComputer(Viewer viewer, String name, int width, int height) { System.out.println(name + " " + width + " " + height); if (computerPresent(name)) ; // do nothing else if (namePresent(name)) { if (width != 0 && height != 0) addComputer(name, width, height); } else { if (width != 0 && height != 0) addComputer(name, width, height); else addNullComputer(name); } addViewer(viewer, name); } // // Private interface // private Processor[][] processors; private static Computer[] computer_bank = new Computer[1]; private static String[] computer_names = new String[1]; private static Queue[] computer_viewers = new Queue[1]; private static int number_computers = 0; private static void expandBank() { int length = 2 * computer_bank.length; Computer[] cs = new Computer[length]; String[] ss = new String[length]; Queue[] qs = new Queue[length]; for (int i = number_computers - 1; i >= 0; i--) { cs[i] = computer_bank[i]; ss[i] = computer_names[i]; qs[i] = computer_viewers[i]; } computer_bank = cs; computer_names = ss; computer_viewers = qs; } private static int findComputer(String name) { for (int i = number_computers - 1; i >= 0; i--) if (name.equals(computer_names[i])) return i; return -1; } private static boolean namePresent(String name) { return findComputer(name) >= 0; } private static boolean computerPresent(String name) { int c = findComputer(name); return c >= 0 && computer_bank[c] != null; } private static void addNullComputer(String name) { if (computer_bank.length <= number_computers) expandBank(); computer_bank[number_computers] = null; computer_names[number_computers] = name; computer_viewers[number_computers] = new Queue(); number_computers++; } private static void addComputer(String name, int width, int height) { addNullComputer(name); int c = findComputer(name); computer_bank[c] = new Computer(width, height, new Random()); } private static void addViewer(Viewer viewer, String name) { int c = findComputer(name); computer_viewers[c].enqueue(viewer); if (computer_bank[c] != null) { try { for (int i = computer_viewers[c].size(); i > 0; i--) ((Viewer) computer_viewers[c].requeue()).setComputer(computer_bank[c]); } catch (QueueEmpty e) { System.err.println("report to programmer - addViewer"); } } } }