summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorcdgill <cdgill@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-01-07 22:46:07 +0000
committercdgill <cdgill@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-01-07 22:46:07 +0000
commit78552d9795151a325fe0d5701c2ea28c256ecdfb (patch)
tree286780950a8cedb569ecf57846b511c114e9bf14 /java
parent57e792805e7e43fbc649cc7efddbeff61f9aed87 (diff)
downloadATCD-78552d9795151a325fe0d5701c2ea28c256ecdfb.tar.gz
moved EAC from ACE_wrappers to ACE_wrappers/java
Diffstat (limited to 'java')
-rw-r--r--java/EAC/BoundsException.java13
-rw-r--r--java/EAC/Configuration.java220
-rw-r--r--java/EAC/Configurator.java58
-rw-r--r--java/EAC/ConnectionException.java14
-rw-r--r--java/EAC/Connector.java197
-rw-r--r--java/EAC/EACComponent.java460
-rw-r--r--java/EAC/EACFont.java21
-rw-r--r--java/EAC/EACLabel.java187
-rw-r--r--java/EAC/EACMenuBar.java198
-rw-r--r--java/EAC/EACPanel.java425
-rw-r--r--java/EAC/EACPrintStream.java16
-rw-r--r--java/EAC/EmptyQueueException.java13
-rw-r--r--java/EAC/File.java118
-rw-r--r--java/EAC/InputMode.java32
-rw-r--r--java/EAC/Intersection.java62
-rw-r--r--java/EAC/Operator.java206
-rw-r--r--java/EAC/Primitive.java121
-rw-r--r--java/EAC/Queue.java94
-rw-r--r--java/EAC/README6
-rw-r--r--java/EAC/ResourcePool.java46
-rw-r--r--java/EAC/Rubberband.java103
-rw-r--r--java/EAC/RubberbandLine.java28
-rw-r--r--java/EAC/Sink.java231
-rw-r--r--java/EAC/Source.java341
-rw-r--r--java/EAC/System Manual.docbin0 -> 83968 bytes
-rw-r--r--java/EAC/TooManyPrimitivesException.java13
-rw-r--r--java/EAC/Union.java56
-rw-r--r--java/EAC/User Manual.docbin0 -> 95232 bytes
28 files changed, 3279 insertions, 0 deletions
diff --git a/java/EAC/BoundsException.java b/java/EAC/BoundsException.java
new file mode 100644
index 00000000000..12010d570b0
--- /dev/null
+++ b/java/EAC/BoundsException.java
@@ -0,0 +1,13 @@
+/**
+ * Title: BoundsException
+ * Description: An exception class for when graphical objects are positioned
+ * partially out of their container's boundaries
+ */
+package EAC;
+
+public class BoundsException extends Exception {
+
+ public BoundsException(String msg) {
+ super(msg);
+ }
+} \ No newline at end of file
diff --git a/java/EAC/Configuration.java b/java/EAC/Configuration.java
new file mode 100644
index 00000000000..426a8ba2a5e
--- /dev/null
+++ b/java/EAC/Configuration.java
@@ -0,0 +1,220 @@
+/**
+ * Title: Configuration
+ * Description: A container of Event Analysis Configurator primitives,
+ * capable of executing interactions among those primitives
+ * one "tick" at a time.
+ */
+package EAC;
+import java.awt.*;
+import java.lang.*;
+
+public class Configuration extends Thread {
+
+ // highest simulation clock value
+ public final long MAX_SIM_CLOCK = 1000000;
+
+ // maximum number of primitives in a configuration
+ public final int MAX_PRIMITIVES = 100;
+
+ // execution modes
+ public final int INITIAL = 0;
+ public final int RUNNING = 1;
+ public final int STOPPED = 2;
+
+ // current mode
+ protected int mode = INITIAL;
+
+ // simulation "clock"
+ protected long simulation_time;
+
+ // one simulation time unit (msec)
+ public int tick; // will be set by runtime parameter
+
+ // number of missed execution deadlines
+ protected int missed_deadlines;
+
+ // simulated resource pool
+ protected ResourcePool rp;
+
+ // event queue
+ protected Queue eventQ;
+
+ // input and output areas
+ protected TextField inputArea;
+ protected Label reportArea;
+
+ // collection of primitives
+ private Primitive primitive[];
+
+ // number of primitives currently stored
+ private int primitive_count;
+
+ public Configuration(TextField i, Label r) {
+ inputArea = i;
+ reportArea = r;
+ eventQ = new Queue();
+ clear();
+ mode = INITIAL;
+ } /* constructor */
+
+ public void clear() {
+ primitive_count = 0;
+ simulation_time = 0;
+ missed_deadlines = 0;
+ rp = new ResourcePool();
+ primitive = new Primitive[MAX_PRIMITIVES];
+ eventQ.clear();
+ } /* clear */
+
+ public void restart() {
+ int i;
+
+ simulation_time = 0;
+ missed_deadlines = 0;
+ rp.release(rp.usage());
+ eventQ.clear();
+ for (i = 0; i < primitive_count; i++)
+ primitive[i].restart();
+
+ } /* restart */
+
+ public void setTick(int t) {
+ tick = t;
+ } /* setTick */
+
+ public void addLabel(Primitive p) {
+ reportArea.setText("Need a label");
+ } /* addLabel */
+
+ public int getPrimitiveCount() {
+ return primitive_count;
+ } /* getPrimitiveCount */
+
+ public Primitive getPrimitive(int n) {
+ return primitive[n];
+ } /* getPrimitive */
+
+ protected void setPrimitive(int n, Primitive p) {
+ primitive[n] = p;
+ } /* setPrimitive */
+
+ public int addPrimitive(Primitive p) throws TooManyPrimitivesException {
+ if (primitive_count == MAX_PRIMITIVES)
+ throw new TooManyPrimitivesException("ERROR: Too many primitives");
+
+ primitive[primitive_count++] = p;
+ return primitive_count;
+ } /* addPrimitive */
+
+ public boolean deletePrimitive(int i) {
+ if (primitive[i] == null)
+ return false;
+ else {
+ primitive[i] = null;
+ return true;
+ }
+ } /* deletePrimitive */
+
+ public int leftSideOverlaps(Primitive p) {
+ int i;
+
+ for (i = 0; i < primitive_count; i++) {
+ if (primitive[i] != null) {
+ if ((primitive[i].contains(p.upperLeft())) ||
+ (primitive[i].contains(p.lowerLeft())) ||
+ (p.contains(primitive[i].lowerLeft())) ||
+ (p.contains(primitive[i].upperLeft()))) {
+ return i;
+ } /* if */
+ } /* if */
+ } /* for */
+
+ // no overlap detected
+ return -1;
+ } /* leftSideOverlaps */
+
+ public int rightSideOverlaps(Primitive p) {
+ int i;
+
+ for (i = 0; i < primitive_count; i++) {
+ if (primitive[i] != null) {
+ if ((primitive[i].contains(p.lowerRight())) ||
+ (primitive[i].contains(p.upperRight())) ||
+ (p.contains(primitive[i].upperRight())) ||
+ (p.contains(primitive[i].lowerRight()))) {
+ return i;
+ } /* if */
+ } /* if */
+ } /* for */
+
+ // no overlap detected
+ return -1;
+ } /* rightSideOverlaps */
+
+ public Primitive primitiveContaining (Point p) {
+ int i;
+
+ for (i = 0; i < primitive_count; i++)
+ if (primitive[i].contains(p))
+ return primitive[i];
+
+ return null;
+ } /* primitiveContaining */
+
+ public void draw() {
+ int i;
+
+ for (i = 0; i < primitive_count; i++)
+ if (primitive[i] != null)
+ try {
+ primitive[i].draw();
+ } catch (BoundsException be) {
+ // can't happen
+ }
+ } /* draw */
+
+ public void eventEnqueue(Primitive p, long t) {
+ eventQ.enqueue(p,t);
+ } /* eventEnqueue */
+
+ public long getTime() {
+ return simulation_time;
+ } /* getTime */
+
+ public void run() {
+ Primitive nextP;
+
+ while (true) {
+ simulation_time += 1;
+ simulation_time %= MAX_SIM_CLOCK;
+ try {
+ reportArea.setText("Simulation Time: " +
+ java.lang.Long.toString(simulation_time) +
+ " Resource Consumption: " +
+ java.lang.Integer.toString(rp.usage()) +
+ "% Missed Deadlines: " +
+ java.lang.Integer.toString(missed_deadlines) +
+ " Next Event: " +
+ java.lang.Long.toString(eventQ.frontTime()));
+
+ // wake up all primitives who've set alarms for current time
+ while (simulation_time == eventQ.frontTime()) {
+ nextP = eventQ.dequeue();
+ nextP.wakeup(simulation_time);
+ } /* while */
+ } catch (EmptyQueueException eqe) {
+ System.out.println("Event queue empty. We're done?");
+ } catch (ConnectionException ce) {
+ System.out.println("Connection exception in run");
+ }
+
+ try {
+ sleep(tick);
+ }
+ catch (InterruptedException ie) {
+ System.out.println("Interrupted");
+ }
+ } /* outer while */
+ } /* run */
+
+} \ No newline at end of file
diff --git a/java/EAC/Configurator.java b/java/EAC/Configurator.java
new file mode 100644
index 00000000000..1a9bc7a0ed8
--- /dev/null
+++ b/java/EAC/Configurator.java
@@ -0,0 +1,58 @@
+/**
+ * Title: Configurator
+ * Description: The application class for the Event Analysis Configurator
+ */
+package EAC;
+import java.awt.*;
+import java.awt.event.*;
+
+public class Configurator extends Frame {
+
+ // Initial dimensions of the frame
+ public final int INITIAL_WIDTH = 800;
+ public final int INITIAL_HEIGHT = 600;
+
+ protected TextField inputArea = new TextField("Input Area", 80);
+ protected Label reportArea = new Label();
+ protected Configuration config = new Configuration(inputArea,reportArea);
+ protected EACPanel canvas = new EACPanel(config,inputArea,reportArea);
+ protected EACMenuBar menuBar = new EACMenuBar(canvas,config,inputArea,reportArea);
+
+ Configurator(int tick) {
+ config.setTick(tick);
+
+ setTitle("The Event Analysis Configurator");
+ setLayout(new BorderLayout());
+ reportArea.setText("Report Area");
+
+ // Input Area at top of frame
+ add(inputArea,"North");
+
+ // Report Area at bottom of frame
+ add(reportArea,"South");
+
+ // Canvas in the middle of frame
+ add(canvas,"Center");
+
+ // Menu Bar
+ setMenuBar(menuBar);
+
+ // Move and resize
+ setLocation(0,0);
+ setSize(INITIAL_WIDTH,INITIAL_HEIGHT);
+
+ // For exiting
+ addWindowListener(new Closer());
+ }
+
+ public static void main (String[] argv) {
+ new Configurator(java.lang.Integer.valueOf(argv[0]).intValue()).show();
+ }
+
+ class Closer extends WindowAdapter {
+ public void windowClosing (WindowEvent e) {
+ System.exit (0);
+ }
+ }
+
+} /* Configurator */
diff --git a/java/EAC/ConnectionException.java b/java/EAC/ConnectionException.java
new file mode 100644
index 00000000000..a1f3efab7ab
--- /dev/null
+++ b/java/EAC/ConnectionException.java
@@ -0,0 +1,14 @@
+/**
+ * Title: ConnectionException
+ * Description: An exception class for when an attempt is made to connect
+ * an input where one is already connected, or to add an
+ * output when the maximum number of outputs are already set
+ */
+package EAC;
+
+public class ConnectionException extends Exception {
+
+ public ConnectionException(String msg) {
+ super(msg);
+ }
+} \ No newline at end of file
diff --git a/java/EAC/Connector.java b/java/EAC/Connector.java
new file mode 100644
index 00000000000..27c02e820bc
--- /dev/null
+++ b/java/EAC/Connector.java
@@ -0,0 +1,197 @@
+/**
+ * Title: Connector
+ * Description: Connects two primitives in the Event Analysis Configurator
+ */
+package EAC;
+import java.awt.*;
+
+public class Connector extends Primitive {
+
+ // for drawing
+ protected RubberbandLine rbLine;
+
+ // Primitives connected by connector
+ Primitive startP,
+ endP;
+
+ // the second point of the connector
+ // (the anchor point is inherited from Primitive)
+ protected Point endpoint;
+
+ public Connector(EACPanel p) {
+ super(p);
+ rbLine = new RubberbandLine(p);
+ }
+
+ // inappropriate inherited methods: should not be used
+ public void setTop(Point p) {}
+ public Point getTop() { return null; }
+
+ public void setEndpoint(Point p) {
+ endpoint = p;
+ } /* setEndpoint */
+
+ public Point getEndpoint() {
+ return endpoint;
+ } /* getEndpoint */
+
+ // Anchor the rubberband line AND the connector itself
+ public void anchor(Point p) {
+ rbLine.anchor(p);
+ anchor = p;
+ } /* anchor */
+
+ // Stretch the rubberband line
+ public void stretch(Point p) {
+ rbLine.stretch(p);
+ } /* stretch */
+
+ // End the rubberband line AND the connector itself
+ public void end(Point p) {
+ rbLine.end(p);
+ endpoint = p;
+ } /* end */
+
+ public void draw() throws BoundsException {
+ if (inBounds()) {
+ Graphics g = canvas.getGraphics();
+
+ g.drawLine(anchor.x,anchor.y,endpoint.x,endpoint.y);
+ drawArrowhead(g);
+ } else
+ throw new BoundsException("ERROR: Attempted to place Connector endpoint out of bounds");
+ } /* draw */
+
+ private void drawArrowhead(Graphics g) {
+ final int arrowHeadWidth = 10;
+ Point P1 = anchor;
+ Point P2 = endpoint;
+
+ // Draw Arrowhead (using java.lang.Math and floating point)
+ // source provided by Erik in newsgroup posting
+ double dx = P2.x - P1.x;
+ double dy = P2.y - P1.y;
+ final double ra = java.lang.Math.sqrt(dx*dx + dy*dy);
+ final double ri = (double) arrowHeadWidth;
+ dx /= ra;
+ dy /= ra;
+ Point p2 = new Point((int)Math.round(P2.x - dx*ri),
+ (int)Math.round(P2.y - dy*ri));
+ int[] x = new int[3];
+ int[] y = new int[3];
+ double r = 0.4 * ri;
+ x[0] = (int)Math.round(p2.x + dy * r);
+ y[0] = (int)Math.round(p2.y - dx * r);
+ x[1] = P2.x;
+ y[1] = P2.y;
+ x[2] = (int)Math.round(p2.x - dy * r);
+ y[2] = (int)Math.round(p2.y + dx * r);
+ g.fillPolygon(x, y, x.length);
+ } /* drawArrowhead */
+
+ public boolean contains(Point p) {
+ return false;
+ } /* contains */
+
+ public Point upperLeft() {
+ return anchor;
+ } /* upperLeft */
+
+ public Point lowerRight() {
+ return endpoint;
+ } /* lowerRight */
+
+ public Point upperRight() {
+ return endpoint;
+ } /* upperRight */
+
+ public Point lowerLeft() {
+ return anchor;
+ } /* lowerLeft */
+
+ public boolean inBounds() {
+ if (canvas.contains(endpoint))
+ return true;
+ else
+ return false;
+ } /* inBounds */
+
+ public void write(File f) throws java.io.IOException {
+ f.writeInt(f.CONNECTOR);
+ f.writeInt(anchor.x);
+ f.writeInt(anchor.y);
+ f.writeInt(endpoint.x);
+ f.writeInt(endpoint.y);
+ } /* write */
+
+ public void read(File f) throws java.io.IOException {
+ anchor = new Point();
+ endpoint = new Point();
+
+ anchor.x = f.readInt();
+ anchor.y = f.readInt();
+ endpoint.x = f.readInt();
+ endpoint.y = f.readInt();
+ } /* read */
+
+ public int addInput(Connector c) throws ConnectionException {
+ throw new ConnectionException("ERROR: Connectors cannot connect each other");
+ } /* addInput */
+
+ public int addOutput(Connector c) throws ConnectionException {
+ throw new ConnectionException("ERROR: Connectors cannot connect each other");
+ } /* addOutput */
+
+ public void setInput(Primitive p) {
+ startP = p;
+ } /* setInput */
+
+ public void setOutput(Primitive p) {
+ endP = p;
+ } /* setOutput */
+
+ public Primitive getInput() {
+ return startP;
+ } /* getInput */
+
+ public Primitive getOutput() {
+ return endP;
+ } /* getOutput */
+
+ public Connector getInput(int i) throws ConnectionException {
+ throw new ConnectionException("Internal error: wrong getInput() called on Connector");
+ } /* getInput */
+
+ public Connector getOutput(int i) throws ConnectionException {
+ throw new ConnectionException("Internal error: wrong getOutput() called on Connector");
+ } /* getOutput */
+
+ public void removeInput(int i) throws ConnectionException {
+ //throw new ConnectionException("ERROR: Attempted to remove input from connector");
+ startP = null;
+ } /* removeInput */
+
+ public void removeOutput(int i) throws ConnectionException {
+ //throw new ConnectionException("ERROR: Attempted to remove output from connector");
+ endP = null;
+ } /* removeOutput */
+
+ public int getInputCount() throws ConnectionException {
+ //throw new ConnectionException("ERROR: Attempted to retrieve input count from connector");
+ return (startP == null) ? 0 : 1;
+ } /* getInputCount */
+
+ public int getOutputCount() throws ConnectionException {
+ //throw new ConnectionException("ERROR: Attempted to retrieve output count from connector");
+ return (endP == null) ? 0 : 1;
+ } /* getOutputCount */
+
+ public void event(Source s) throws ConnectionException {
+ //throw new ConnectionException("ERROR: Attempted to push event to connector");
+ endP.event(s);
+ } /* event */
+
+ public void wakeup(long t) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to wake up connector");
+ } /* wakeup */
+} \ No newline at end of file
diff --git a/java/EAC/EACComponent.java b/java/EAC/EACComponent.java
new file mode 100644
index 00000000000..f26aca96880
--- /dev/null
+++ b/java/EAC/EACComponent.java
@@ -0,0 +1,460 @@
+/**
+ * Title: Component
+ * Description: A real-time component emulator, for use in the Event Analysis
+ * Configurator.
+ */
+package EAC;
+import java.awt.*;
+
+public class EACComponent extends Primitive {
+
+ class QueueEntry {
+
+ Source source;
+ long request_time;
+ boolean running;
+
+ } /* QueueEntry */
+
+ public class ServiceQueue {
+
+ public QueueEntry queue[];
+
+ public int size;
+
+ void enqueue(QueueEntry e) {
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (e.source == queue[i].source) {
+ System.out.println("Internal error: attempt to enqueue duplicate source");
+ System.exit(-1);
+ }
+
+ if (size >= MAX_INPUTS) {
+ System.out.println("Internal error: queue size at max");
+ System.exit(-1);
+ }
+
+ queue[size++] = e;
+ } /* enqueue */
+
+ QueueEntry dequeue() {
+ QueueEntry front = queue[0];
+ int i;
+
+ for (i = 0; i < size; i++)
+ queue[i] = queue[i+1];
+
+ --size;
+
+ return front;
+ } /* dequeue */
+
+ boolean containsSource (Primitive p) {
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (queue[i].source == p)
+ return true;
+
+ return false;
+ } /* containsSource */
+
+ } /* ServiceQueue */
+
+ // queue of running/waiting event sources
+ protected ServiceQueue sq;
+
+ // Font for text
+ protected Font text_font = new EACFont().getFont();
+
+ // dimensions of the rectangle to be drawn on-screen
+ protected final int HEIGHT = 40;
+ protected final int WIDTH = 30;
+
+ // Configuration to which the component belongs
+ protected Configuration config;
+
+ // percentage of Resource Pool consumed during execution
+ protected int resource_consumption;
+
+ // duration of execution
+ protected int duration;
+
+ // input
+ protected Connector input;
+
+ // outputs
+ protected Connector output[] = new Connector[MAX_OUTPUTS];
+ protected int output_count = 0;
+
+ // helps with dragging the component
+ protected boolean selected = false;
+ protected Point old_anchor;
+
+ // Black-on-white (normal) or white-on-black (reversed)?
+ protected boolean reverse_color = false;
+
+ public EACComponent(EACPanel p, Configuration c) {
+ super(p);
+ config = c;
+ sq = new ServiceQueue();
+ sq.queue = new QueueEntry[MAX_INPUTS];
+ sq.size = 0;
+ } /* constructor */
+
+ public void restart() {
+ sq.size = 0;
+ reverse_color = false;
+ selected = false;
+ } /* restart */
+
+ public void setTop(Point p) {
+ anchor = new Point(p.x - (int) (WIDTH / 2), p.y);
+ } /* setTop */
+
+ public Point getTop() {
+ return new Point(anchor.x + (int) (WIDTH / 2), anchor.y);
+ } /* getTop */
+
+ public void setResourceConsumption(int rc) throws NumberFormatException {
+ if ((rc > 0) && (rc <= 100))
+ resource_consumption = rc;
+ else
+ throw new NumberFormatException();
+ } /* setResourceConsumption */
+
+ public int getResourceConsumption() {
+ return resource_consumption;
+ } /* getResourceConsumption */
+
+ public void setDuration(int d) throws NumberFormatException {
+ if (d > 0)
+ duration = d;
+ else
+ throw new NumberFormatException();
+ } /* setDuration */
+
+ public int getDuration() {
+ return duration;
+ } /* getDuration */
+
+ public void event(Source s) throws ConnectionException {
+ long time = config.getTime();
+
+ s.reverseColor();
+ try {
+ s.draw();
+ } catch (BoundsException be) {}
+
+ //System.out.print(label.getText());
+ //System.out.print(" event at: ");
+ //System.out.println(time);
+
+ if (sq.containsSource(s)) { // missed a deadline
+ config.missed_deadlines++;
+ System.out.print(label.getText());
+ System.out.print(" missed a deadline for ");
+ System.out.print(s.getLabel().getText());
+ System.out.print(" at: ");
+ System.out.println(java.lang.Long.toString(time));
+ } else { // there's no existing service call for this source
+ // prepare to add new entry to Service Queue
+ QueueEntry e = new QueueEntry();
+ e.source = s;
+ e.request_time = time;
+ if (config.rp.reserve(resource_consumption)) { // resource reservation succeeded
+ reverseColor(); // indicate we're working it
+ try {
+ draw();
+ } catch (BoundsException be) {}
+ config.eventEnqueue(this,time + duration); // set wakeup call to release resources
+
+ // new entry will be running
+ e.running = true;
+ } else { // resource reservation failed
+ config.eventEnqueue(this,time + 1); // set wakeup call to try for resources again
+
+ // new entry will be waiting
+ e.running = false;
+ } /* else */
+
+ sq.enqueue(e); // add new entry to Service Queue
+ } /* else */
+ } /* event */
+
+ public void wakeup(long t) throws ConnectionException {
+ int i;
+
+ //System.out.print(label.getText());
+ //System.out.println(" wakeup at: " + java.lang.Long.toString(t));
+
+ while (sq.size > 0) {
+ if ((sq.queue[0].running) && (sq.queue[0].request_time + duration <= t)) { // time to release
+ config.rp.release(resource_consumption);
+ try {
+ Source s = sq.dequeue().source; // dequeue and get the source
+ s.normalColor(); // indicates we're done
+ normalColor();
+ s.draw();
+ draw();
+ } catch (BoundsException be) {}
+ } else
+ break;
+ } /* while */
+
+ // satisfy as many waiting service calls as possible
+ for (i = 0; i < sq.size; i++) {
+ if (!sq.queue[i].running) {
+ if (config.rp.reserve(resource_consumption)) { // resource reservation succeeded
+ config.eventEnqueue(this,t + duration); // set wakeup call to release resources
+ sq.queue[i].request_time = t;
+ sq.queue[i].running = true;
+ sq.queue[i].source.reverseColor(); // indicates we're working it
+ reverseColor();
+ try {
+ draw();
+ sq.queue[i].source.draw();
+ } catch (BoundsException be) {}
+ } else { // resource reservation failed
+ config.eventEnqueue(this,t + 1); // set wakeup call to try for resources again
+ break; // no reason to keep trying right now
+ } /* else */
+ } /* if */
+ } /* while */
+
+ } /* wakeup */
+
+ public int addInput(Connector c) throws ConnectionException {
+ if (input == null) {
+ input = c;
+ return 1;
+ }
+ else
+ throw new ConnectionException("ERROR: Input already established for this component");
+ } /* setInput */
+
+ public int addOutput(Connector c) throws ConnectionException {
+ if (output_count < MAX_OUTPUTS)
+ output[output_count++] = c;
+ else
+ throw new ConnectionException("ERROR: Maximum outputs established for this component");
+
+ return output_count;
+ } /* addOutput */
+
+ public Connector getInput(int i) throws ConnectionException {
+ if (i != 0)
+ throw new ConnectionException("ERROR: Bad input index for component");
+ else if (input == null)
+ throw new ConnectionException("ERROR: No input for this component");
+ else
+ return input;
+ } /* getInput */
+
+ public Connector getOutput(int i) throws ConnectionException {
+ if ((i >= 0) && (i < output_count))
+ return output[i];
+ else
+ throw new ConnectionException("ERROR: Bad output index for component");
+ } /* getOutput */
+
+ public void removeInput(int i) throws ConnectionException {
+ if (i != 0)
+ throw new ConnectionException("ERROR: Bad input index for component");
+ else
+ input = null;
+ } /* removeInput */
+
+ public void removeOutput(int i) throws ConnectionException {
+ if ((i >= 0) && (i < output_count)) {
+ output[i] = output[output_count-1];
+ --output_count;
+ } else
+ throw new ConnectionException("ERROR: Bad output index for component");
+ } /* removeOutput */
+
+ public int getOutputCount() throws ConnectionException {
+ return output_count;
+ } /* getOutputCount */
+
+ public int getInputCount() throws ConnectionException {
+ return (input == null) ? 0 : 1;
+ } /* getInputCount */
+
+ public boolean contains(Point p) {
+ if ((p.x >= anchor.x) &&
+ (p.x <= anchor.x + WIDTH) &&
+ (p.y >= anchor.y) &&
+ (p.y <= anchor.y + HEIGHT))
+ return true;
+ else
+ return false;
+ } /* contains */
+
+ public Point upperLeft() {
+ return anchor;
+ } /* upperLeft */
+
+ public Point lowerRight() {
+ return new Point(anchor.x + WIDTH, anchor.y + HEIGHT);
+ } /* lowerRight */
+
+ public Point upperRight() {
+ return new Point(anchor.x + WIDTH, anchor.y);
+ } /* upperRight */
+
+ public Point lowerLeft() {
+ return new Point(anchor.x, anchor.y + HEIGHT);
+ } /* lowerLeft */
+
+ public void draw() throws BoundsException {
+ if (selected)
+ selected = false;
+ else if (inBounds()) {
+ Graphics g = canvas.getGraphics();
+ char stringData[];
+ Color bg,
+ fg;
+
+ if (reverse_color) {
+ bg = Color.black;
+ fg = Color.white;
+ } else {
+ bg = Color.white;
+ fg = Color.black;
+ }
+
+ g.setColor(Color.black); // rectangle is always black
+ g.drawRect(anchor.x,anchor.y,WIDTH,HEIGHT);
+
+ g.setColor(bg); // interior
+ g.fillRect(anchor.x+1,anchor.y+1,WIDTH-1,HEIGHT-1);
+
+ g.setColor(fg); // middle line and text
+ g.drawLine(anchor.x,anchor.y + (int) (HEIGHT / 2),
+ anchor.x + WIDTH, anchor.y + (int) (HEIGHT / 2));
+
+ // print resource consumption percentage
+ g.setFont(text_font);
+ g.drawString(java.lang.String.valueOf(resource_consumption),
+ anchor.x + 16 - (3 * java.lang.String.valueOf(resource_consumption).length()),
+ anchor.y + (int) (HEIGHT / 3));
+
+ // print duration
+ g.drawString(java.lang.String.valueOf(duration),
+ anchor.x + 16 - (3 * java.lang.String.valueOf(duration).length()),
+ anchor.y + (int) (HEIGHT * 3 / 4) + 3);
+
+ } else
+ throw new BoundsException("ERROR: Attempted to place Component partially out of bounds");
+ } /* draw */
+
+ public void reverseColor() {
+ reverse_color = true;
+ } /* reverseColor */
+
+ public void normalColor() {
+ reverse_color = false;
+ } /* normalColor */
+
+ public void specialDraw() {
+ Graphics g = canvas.getGraphics();
+
+ g.setXORMode(canvas.getBackground());
+ g.drawRect(anchor.x,anchor.y,WIDTH,HEIGHT);
+ } /* specialDraw */
+
+ public void specialUndraw() {
+ Graphics g = canvas.getGraphics();
+
+ g.setColor(canvas.getBackground());
+ g.setXORMode(canvas.getForeground());
+ g.drawRect(anchor.x,anchor.y,WIDTH,HEIGHT);
+ } /* specialUndraw */
+
+ public void selectedDraw() {
+ // this will preclude drawing this component for one repaint() call
+ selected = true;
+
+ old_anchor = anchor;
+
+ super.selectedDraw();
+ } /* selectedDraw */
+
+ public void reconnect() {
+ int i;
+
+ // move output anchors
+ for (i = 0; i < output_count; i++)
+ output[i].setAnchor(new Point(output[i].getAnchor().x + anchor.x - old_anchor.x,
+ output[i].getAnchor().y + anchor.y - old_anchor.y));
+
+ // move input endpoint
+ input.setEndpoint(new Point(input.upperRight().x + anchor.x - old_anchor.x,
+ input.upperRight().y + anchor.y - old_anchor.y));
+
+ // move label anchor
+ label.setAnchor(new Point(label.getAnchor().x + anchor.x - old_anchor.x,
+ label.getAnchor().y + anchor.y - old_anchor.y));
+ } /* reconnect */
+
+ public boolean inBounds() {
+ if ((canvas.contains(upperLeft())) &&
+ (canvas.contains(lowerRight())))
+ return true;
+ else
+ return false;
+ } /* inBounds */
+
+ public void write(File f) throws java.io.IOException {
+ char temp[]; // for writing label
+ int i, n;
+
+ f.writeInt(f.COMPONENT);
+ f.writeInt(anchor.x);
+ f.writeInt(anchor.y);
+ f.writeInt(resource_consumption);
+ f.writeInt(duration);
+
+ // Write out the associated label
+ n = label.getText().length();
+ f.writeInt(n); // text length
+ temp = new char[n];
+ temp = label.getText().toCharArray();
+ for (i = 0; i < n; i++)
+ f.writeChar(temp[i]);
+ f.writeInt(label.getAnchor().x); // label position
+ f.writeInt(label.getAnchor().y);
+ } /* write */
+
+ public void read(File f) throws java.io.IOException {
+ char temp[]; // for reading label
+ int i, n;
+ int label_x, label_y;
+
+ anchor = new Point();
+ anchor.x = f.readInt();
+ anchor.y = f.readInt();
+ resource_consumption = f.readInt();
+ duration = f.readInt();
+
+ // get label info
+ n = f.readInt(); // text length
+ label = new EACLabel(canvas,n);
+ temp = new char[n];
+ for (i = 0; i < n; i++)
+ temp[i] = f.readChar();
+ label.setText(java.lang.String.valueOf(temp));
+ label_x = f.readInt();
+ label_y = f.readInt();
+ label.setAnchor(new Point(label_x,label_y));
+ label.setLabelee(this);
+ try {
+ config.addPrimitive(label);
+ } catch (TooManyPrimitivesException tmpe) {
+ // have faith :-)
+ }
+ } /* read */
+} \ No newline at end of file
diff --git a/java/EAC/EACFont.java b/java/EAC/EACFont.java
new file mode 100644
index 00000000000..97f4d39b6cb
--- /dev/null
+++ b/java/EAC/EACFont.java
@@ -0,0 +1,21 @@
+/**
+ * Title: EACFont
+ * Description: The font to be used for on-screen text
+ */
+package EAC;
+import java.awt.*;
+
+public class EACFont {
+
+ // Use 9-point Courier New
+ public final int FONT_SIZE = 10;
+ protected Font eac_font = new Font("Courier New",Font.PLAIN,FONT_SIZE);
+
+ public EACFont() {
+ }
+
+ public Font getFont() {
+ return eac_font;
+ } /* getFont */
+
+} \ No newline at end of file
diff --git a/java/EAC/EACLabel.java b/java/EAC/EACLabel.java
new file mode 100644
index 00000000000..e841c4e4c40
--- /dev/null
+++ b/java/EAC/EACLabel.java
@@ -0,0 +1,187 @@
+/**
+ * Title: EACLabel
+ * Description: Text labels for Event Analysis Configurator graphical
+ * primitives
+ */
+package EAC;
+import java.awt.*;
+
+public class EACLabel extends Primitive {
+
+ // Font for labels
+ protected Font label_font = new EACFont().getFont();
+
+ // Font Metrics for sizing and bounds checking labels
+ protected FontMetrics fm = canvas.getFontMetrics(label_font);
+
+ // Label text
+ protected char[] text;
+
+ // associated Primitive
+ protected Primitive labelee;
+
+ public EACLabel(EACPanel p, int n) {
+ super(p);
+ text = new char[n];
+ } /* constructor */
+
+ public void setLabelee(Primitive p) {
+ labelee = p;
+ } /* setLabelee */
+
+ public Primitive getLabelee() {
+ return labelee;
+ } /* getLabelee */
+
+ public void setText(String s) {
+ text = s.toCharArray();
+ } /* setText */
+
+ public String getText() {
+ return java.lang.String.valueOf(text);
+ } /* getText */
+
+ public void setTop(Point p) {
+ anchor = new Point(p.x - (3 * text.length),
+ p.y + 9);
+ } /* setTop */
+
+ public Point getTop() {
+ return new Point(anchor.x + (3 * text.length),
+ anchor.y - 9);
+ } /* getTop */
+
+ public void draw() throws BoundsException {
+ if (inBounds()) {
+ Graphics g = canvas.getGraphics();
+ g.setFont(label_font);
+ g.drawChars(text,0,text.length,anchor.x,anchor.y);
+ } else
+ throw new BoundsException("Attempted to place Label partially out of bounds");
+ } /* draw */
+
+ public void specialDraw() {
+ Graphics g = canvas.getGraphics();
+
+ g.setXORMode(canvas.getBackground());
+ g.drawRect(upperLeft().x, upperLeft().y,
+ upperRight().x - upperLeft().x, // WIDTH
+ lowerRight().y - upperRight().y); // HEIGHT
+ } /* specialDraw */
+
+ public void specialUndraw() {
+ Graphics g = canvas.getGraphics();
+
+ g.setColor(canvas.getBackground());
+ g.setXORMode(canvas.getForeground());
+ g.drawRect(upperLeft().x, upperLeft().y,
+ upperRight().x - upperLeft().x, // WIDTH
+ lowerRight().y - upperRight().y); // HEIGHT
+ } /* specialUndraw */
+
+ public boolean contains(Point p) {
+ return ((p.x >= upperLeft().x) &&
+ (p.x <= upperRight().x) &&
+ (p.y <= lowerLeft().y) &&
+ (p.y >= upperLeft().y));
+ } /* contains */
+
+ public boolean inBounds() {
+ // don't know why we need this, but fm.stringWidth seems to return a
+ // value that's bigger than the actual width of the text
+ //final int xTweak = 20;
+
+ //if (canvas.contains(anchor.x + fm.stringWidth(text.toString()) - xTweak,
+ // anchor.y - fm.getHeight()))
+ if ((canvas.contains(upperLeft())) &&
+ (canvas.contains(upperRight())) &&
+ (canvas.contains(lowerLeft())) &&
+ (canvas.contains(lowerRight())))
+ return true;
+ else
+ return false;
+ } /* inBounds */
+
+ public Point upperLeft() {
+ return new Point(anchor.x,anchor.y - 9);
+ } /* upperLeft */
+
+ public Point upperRight() {
+ return new Point(anchor.x + (6 * text.length),anchor.y - 9);
+ } /* upperRight */
+
+ public Point lowerLeft() {
+ return anchor;
+ } /* lowerLeft */
+
+ public Point lowerRight() {
+ return new Point(anchor.x + (6 * text.length),anchor.y);
+ } /* lowerRight */
+
+ public void write(File f) throws java.io.IOException {
+ int i;
+
+ // if there's an associated primitive, that primitive
+ // is responsible for writing out the label info too,
+ // so only write out the info if there is no labelee
+ if (labelee == null) {
+ f.writeInt(f.LABEL);
+ f.writeInt(text.length);
+ f.writeInt(anchor.x);
+ f.writeInt(anchor.y);
+ for (i = 0; i < text.length; i++)
+ f.writeChar(text[i]);
+ }
+ } /* write */
+
+ public void read(File f) throws java.io.IOException {
+ int i;
+
+ anchor = new Point();
+ anchor.x = f.readInt();
+ anchor.y = f.readInt();
+
+ for (i = 0; i < text.length; i++)
+ text[i] = f.readChar();
+ } /* read */
+
+ public int addInput(Connector c) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to add input to label");
+ } /* addInput */
+
+ public int addOutput(Connector c) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to add output to label");
+ } /* addOutput */
+
+ public Connector getInput(int i) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to retrieve input from label");
+ } /* getInput */
+
+ public Connector getOutput(int i) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to retrieve output from label");
+ } /* getOutput */
+
+ public int getInputCount() throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to retrieve input count from label");
+ } /* getInputCount */
+
+ public int getOutputCount() throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to retrieve output count from label");
+ } /* getOutputCount */
+
+ public void removeInput(int i) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to remove input from label");
+ } /* removeInput */
+
+ public void removeOutput(int i) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to remove output from label");
+ } /* removeOutput */
+
+ public void event(Source s) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to push event to label");
+ } /* event */
+
+ public void wakeup(long t) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to wake up label");
+ } /* wakeup */
+} \ No newline at end of file
diff --git a/java/EAC/EACMenuBar.java b/java/EAC/EACMenuBar.java
new file mode 100644
index 00000000000..d34a776635d
--- /dev/null
+++ b/java/EAC/EACMenuBar.java
@@ -0,0 +1,198 @@
+/**
+ * Title: EACMenuBar
+ * Description: A subclass of MenuBar for the Event Analysis Configurator
+ */
+package EAC;
+import java.awt.*;
+import java.awt.event.*;
+
+public class EACMenuBar extends MenuBar {
+
+ protected EACPanel canvas;
+ protected Configuration config;
+ protected TextField inputArea;
+ protected Label reportArea;
+
+ public EACMenuBar(EACPanel p, Configuration c, TextField i, Label r) {
+ canvas = p;
+ config = c;
+ inputArea = i;
+ reportArea = r;
+
+ // Configuration menu
+ Menu menu = new Menu("Configuration");
+
+ // Configuration menu options
+ MenuItem mi = new MenuItem("Clear");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode == config.RUNNING) {
+ config.suspend();
+ config.mode = config.STOPPED;
+ } /* if */
+ config.clear();
+ canvas.repaint();
+ inputArea.setText("");
+ reportArea.setText("Configuration cleared");
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Load");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode == config.RUNNING) {
+ config.suspend();
+ config.mode = config.STOPPED;
+ } /* if */
+ config.clear();
+ canvas.repaint();
+ inputArea.setText("");
+ reportArea.setText("Please enter a filename");
+ canvas.mode = canvas.LOAD;
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Save");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode == config.RUNNING) {
+ config.suspend();
+ config.mode = config.STOPPED;
+ } /* if */
+ canvas.repaint();
+ canvas.mode = canvas.SAVE;
+ inputArea.setText("");
+ reportArea.setText("Please enter a filename");
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Run/Restart");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode == config.INITIAL) {
+ config.start();
+ } else if (config.mode == config.STOPPED) {
+ config.restart();
+ canvas.repaint();
+ config.resume();
+ }
+ System.out.println();
+ System.out.println("Configuration running...");
+ config.mode = config.RUNNING;
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Pause/Unpause");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode == config.RUNNING) {
+ config.suspend();
+ config.mode = config.STOPPED;
+ } else if (config.mode == config.STOPPED) {
+ config.resume();
+ config.mode = config.RUNNING;
+ }
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ add(menu);
+
+ // New menu
+ menu = new Menu("New");
+
+ // New menu options
+ mi = new MenuItem("Component");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode != config.RUNNING) {
+ canvas.current_component = new EACComponent(canvas,config);
+ canvas.repaint();
+ canvas.mode = canvas.COMPONENT;
+ }
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Union");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode != config.RUNNING) {
+ canvas.current_shape = new Union(canvas);
+ canvas.repaint();
+ canvas.mode = canvas.EDIT;
+ }
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Intersection");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode != config.RUNNING) {
+ canvas.current_shape = new Intersection(canvas);
+ canvas.repaint();
+ canvas.mode = canvas.EDIT;
+ }
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Source");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode != config.RUNNING) {
+ canvas.current_source = new Source(canvas,config);
+ canvas.repaint();
+ canvas.mode = canvas.SOURCE;
+ }
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Sink");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode != config.RUNNING) {
+ canvas.current_shape = new Sink(canvas);
+ canvas.repaint();
+ canvas.mode = canvas.EDIT;
+ }
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Connector");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode != config.RUNNING) {
+ canvas.repaint();
+ canvas.mode = canvas.CONNECTING;
+ }
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ mi = new MenuItem("Label");
+ mi.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (config.mode != config.RUNNING) {
+ reportArea.setText("Enter the text for your label in the input area");
+ inputArea.setText("");
+ canvas.repaint();
+ canvas.mode = canvas.LABEL_TYPING;
+ }
+ } /* actionPerformed */
+ }); /* addActionListener */
+ menu.add(mi);
+
+ add(menu);
+
+ } /* constructor */
+
+} /* EACMenuBar */
+
diff --git a/java/EAC/EACPanel.java b/java/EAC/EACPanel.java
new file mode 100644
index 00000000000..333321ef545
--- /dev/null
+++ b/java/EAC/EACPanel.java
@@ -0,0 +1,425 @@
+/**
+ * Title: EACPanel
+ * Description: A subclass of Panel for the Event Analysis Configurator
+ */
+package EAC;
+import java.awt.*;
+import java.awt.event.*;
+
+public class EACPanel extends Panel {
+
+ protected TextField inputArea;
+ protected Label reportArea;
+
+ // input modes
+ public final int COMMAND = 0;
+ public final int SELECT = 1;
+ public final int CUT = 2;
+ public final int COPY = 3;
+ public final int PASTE = 4;
+ public final int EDIT = 5;
+ public final int CONNECTING = 6;
+ public final int COMPONENT = 7;
+ public final int LABEL_TYPING = 8;
+ public final int LABEL_ADDING = 9;
+ public final int RC_TYPING = 10;
+ public final int DURATION_TYPING = 11;
+ public final int PERIOD_TYPING = 12;
+ public final int SOURCE = 13;
+ public final int CONNECTING_END = 14;
+ public final int LOAD = 15;
+ public final int SAVE = 16;
+
+ // current input mode
+ protected int mode;
+
+ // current primitive for drawing
+ protected Primitive current_shape;
+
+ // current text label
+ protected EACLabel current_label;
+
+ // current component
+ protected EACComponent current_component;
+
+ // current source
+ protected Source current_source;
+
+ // current connector, and associated primitives (indices into config's collection)
+ protected Connector current_connector;
+ protected int connector_start_index;
+ protected int connector_end_index;
+
+ // flag for associating the required label with a component or source
+ protected boolean component_needs_label = false;
+ protected boolean source_needs_label = false;
+
+ // Component Configuration associated with this panel
+ protected Configuration config;
+
+ // for dragging primitives around the panel
+ int moving_dx,
+ moving_dy;
+ boolean repainted;
+
+
+ // Constructor
+ public EACPanel(Configuration c, TextField i, Label r) {
+ config = c;
+ inputArea = i;
+ inputArea.addKeyListener(eac_key_adapter);
+ reportArea = r;
+ mode = COMMAND;
+ addMouseListener(eac_mouse_adapter);
+ addMouseMotionListener(eac_mm_adapter);
+ } /* constructor */
+
+ // Mouse Adapter
+ private class EACMouseAdapter extends MouseAdapter
+ implements MouseListener {
+
+ EACPanel canvas;
+
+ public EACMouseAdapter(EACPanel p) {
+ canvas = p;
+ } /* constructor */
+
+ public void mousePressed(MouseEvent e) {
+ switch (mode) {
+ case EDIT:
+ current_shape.setTop(new Point(e.getX(),e.getY()));
+ try {
+ if ((config.leftSideOverlaps(current_shape) == -1) &&
+ (config.rightSideOverlaps(current_shape) == -1)) {
+ current_shape.draw();
+ reportArea.setText("");
+ config.addPrimitive(current_shape);
+ mode = COMMAND;
+ } else {
+ reportArea.setText("ERROR: Primitives too close together");
+ } /* if */
+ } catch (BoundsException be) {
+ reportArea.setText(be.getMessage());
+ } catch (TooManyPrimitivesException tmpe) {
+ reportArea.setText(tmpe.getMessage());
+ } /* try */
+ break;
+ case SOURCE:
+ current_source.setTop(new Point(e.getX(),e.getY()));
+ try {
+ if ((config.leftSideOverlaps(current_source) == -1) &&
+ (config.rightSideOverlaps(current_source) == -1)) {
+ current_source.draw();
+ config.addPrimitive(current_source);
+ reportArea.setText("Please enter the period for this source in the input area");
+ inputArea.setText("");
+ mode = PERIOD_TYPING;
+ } else {
+ reportArea.setText("ERROR: Primitives too close together");
+ } /* if */
+ } catch (BoundsException be) {
+ reportArea.setText(be.getMessage());
+ } catch (TooManyPrimitivesException tmpe) {
+ reportArea.setText(tmpe.getMessage());
+ } /* try */
+ break;
+ case COMPONENT:
+ current_component.setTop(new Point(e.getX(),e.getY()));
+ try {
+ if ((config.leftSideOverlaps(current_component) == -1) &&
+ (config.rightSideOverlaps(current_component) == -1)) {
+ current_component.draw();
+ config.addPrimitive(current_component);
+ reportArea.setText("Please enter the resource consumption for this component in the input area");
+ inputArea.setText("");
+ mode = RC_TYPING;
+ } else {
+ reportArea.setText("ERROR: Primitives too close together");
+ } /* if */
+ } catch (BoundsException be) {
+ reportArea.setText(be.getMessage());
+ } catch (TooManyPrimitivesException tmpe) {
+ reportArea.setText(tmpe.getMessage());
+ } /* try */
+ break;
+ case CONNECTING:
+ current_connector = new Connector(canvas);
+ current_connector.anchor(new Point(e.getX(),e.getY()));
+ connector_start_index = config.leftSideOverlaps(current_connector);
+ if (connector_start_index == -1)
+ reportArea.setText("ERROR: Connector must begin inside a primitive");
+ else
+ mode = CONNECTING_END;
+ break;
+ case LABEL_ADDING:
+ current_label.setTop(new Point(e.getX(),e.getY()));
+ try {
+ current_label.specialUndraw();
+ current_label.draw();
+ reportArea.setText("");
+ config.addPrimitive(current_label);
+ mode = COMMAND;
+ } catch (BoundsException be) {
+ reportArea.setText(be.getMessage());
+ } catch (TooManyPrimitivesException tmpe) {
+ reportArea.setText(tmpe.getMessage());
+ } /* try */
+ break;
+ default: // SELECT mode
+ mode = SELECT;
+ current_shape = config.primitiveContaining(new Point(e.getX(),e.getY()));
+ repaint();
+ if (current_shape != null) {
+ repaint(); // if there was a previously selected shape, it ignored
+ // the last repaint() (kludge--looks better for dragging)
+ moving_dx = e.getX() - current_shape.getTop().x;
+ moving_dy = e.getY() - current_shape.getTop().y;
+ current_shape.selectedDraw();
+ repainted = false;
+ } else
+ repaint(); // need to repaint a second time
+ break;
+ } /* switch */
+ } /* mousePressed */
+
+ public void mouseReleased(MouseEvent e) {
+ switch (mode) {
+ case CONNECTING_END:
+ current_connector.end(new Point(e.getX(),e.getY()));
+ try {
+ connector_end_index = config.rightSideOverlaps(current_connector);
+ if (connector_end_index != -1) {
+ if (connector_end_index == connector_start_index)
+ reportArea.setText("ERROR: Connector cannot start and end at same primitive");
+ else {
+ Primitive startP = config.getPrimitive(connector_start_index);
+ Primitive endP = config.getPrimitive(connector_end_index);
+
+ // connect primitives
+ try {
+ startP.addOutput(current_connector);
+ current_connector.setInput(startP);
+ current_connector.setOutput(endP);
+ endP.addInput(current_connector);
+
+ // if everything okay, draw arrow
+ current_connector.draw();
+ reportArea.setText("");
+ config.addPrimitive(current_connector);
+
+ mode = COMMAND;
+
+ } catch (ConnectionException ce) {
+ reportArea.setText(ce.getMessage());
+ }
+ } /* else */
+ } else {
+ reportArea.setText("ERROR: Connector must terminate inside a primitive");
+ } /* if */
+ } catch (BoundsException be) {
+ reportArea.setText(be.getMessage());
+ } catch (TooManyPrimitivesException tmpe) {
+ reportArea.setText(tmpe.getMessage());
+ } /* try */
+ mode = CONNECTING;
+ break;
+ case SELECT:
+ if (current_shape != null)
+ current_shape.reconnect();
+ if (repainted) // dragging occurred
+ repaint();
+ break;
+ default:
+ //no-op
+ } /* switch */
+ } /* mouseReleased */
+
+ public void mouseClicked(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+
+ } /* EACMouseAdapter */
+
+ // Mouse Motion Adapter
+ private class EACMouseMotionAdapter extends MouseMotionAdapter
+ implements MouseMotionListener {
+
+ public void mouseDragged(MouseEvent e) {
+ switch (mode) {
+ case CONNECTING_END:
+ current_connector.stretch(new Point(e.getX(),e.getY()));
+ break;
+ case SELECT:
+ if (current_shape != null) {
+ Point old_top = current_shape.getTop();
+ if (!repainted) {
+ repaint();
+ repainted = true;
+ } /* if */
+ current_shape.specialUndraw();
+ current_shape.setTop(new Point(e.getX() - moving_dx,e.getY() - moving_dy));
+ if (!current_shape.inBounds())
+ current_shape.setTop(old_top);
+ current_shape.specialDraw();
+ } /* if */
+ default:
+ //no-op
+ } /* switch */
+ } /* mouseDragged */
+
+ public void mouseMoved(MouseEvent e) {
+ switch (mode) {
+ case COMPONENT:
+ if (current_component.getAnchor() != null)
+ current_component.specialUndraw();
+ current_component.setTop(new Point(e.getX(),e.getY()));
+ current_component.specialDraw();
+ break;
+ case SOURCE:
+ if (current_source.getAnchor() != null)
+ current_source.specialUndraw();
+ current_source.setTop(new Point(e.getX(),e.getY()));
+ current_source.specialDraw();
+ break;
+ case EDIT:
+ if (current_shape.getAnchor() != null)
+ current_shape.specialUndraw();
+ current_shape.setTop(new Point(e.getX(),e.getY()));
+ current_shape.specialDraw();
+ break;
+ case LABEL_ADDING:
+ if (current_label.getAnchor() != null)
+ current_label.specialUndraw();
+ current_label.setTop(new Point(e.getX(),e.getY()));
+ current_label.specialDraw();
+ break;
+ default:
+ //no-op
+ } /* switch */
+ } /* mouseMoved */
+
+ } /* EACMouseMotionAdapter */
+
+ // Key Adapter
+ private class EACKeyAdapter extends KeyAdapter implements KeyListener {
+
+ EACPanel canvas;
+
+ public EACKeyAdapter(EACPanel p) {
+ canvas = p;
+ } /* constructor */
+
+ public void keyPressed(KeyEvent e) {
+ Graphics g = getGraphics();
+ String input;
+
+ if ((mode == RC_TYPING) && (e.getKeyChar() == '\n')) {
+ input = new String(inputArea.getText());
+ try {
+ current_component.setResourceConsumption(Integer.parseInt(input));
+ current_component.draw();
+ reportArea.setText("Please enter the duration for this component in the input area");
+ inputArea.setText("");
+ mode = DURATION_TYPING;
+ } catch (NumberFormatException nfe) {
+ reportArea.setText("Please enter an integer value between 1 and 100, inclusive");
+ inputArea.setText("");
+ return;
+ } catch (BoundsException be) {
+ reportArea.setText(be.getMessage());
+ } /* try */
+ } else if ((mode == DURATION_TYPING) && (e.getKeyChar() == '\n')) {
+ input = new String(inputArea.getText());
+ try {
+ current_component.setDuration(Integer.parseInt(input));
+ current_component.draw();
+ reportArea.setText("Please enter a label for this component in the input area");
+ inputArea.setText("");
+ component_needs_label = true;
+ mode = LABEL_TYPING;
+ } catch (NumberFormatException nfe) {
+ reportArea.setText("Please enter an integer value");
+ inputArea.setText("");
+ return;
+ } catch (BoundsException be) {
+ reportArea.setText(be.getMessage());
+ } /* try */
+ } else if ((mode == LABEL_TYPING) && (e.getKeyChar() == '\n')) {
+ current_label = new EACLabel(canvas,inputArea.getText().length());
+ current_label.setText(inputArea.getText());
+ if (component_needs_label) {
+ component_needs_label = false;
+ current_component.setLabel(current_label);
+ current_label.setLabelee(current_component);
+ } else if (source_needs_label) {
+ source_needs_label = false;
+ current_source.setLabel(current_label);
+ current_label.setLabelee(current_source);
+ }
+ reportArea.setText("Click at desired label location");
+ inputArea.setText("");
+ mode = LABEL_ADDING;
+ } else if ((mode == PERIOD_TYPING) && (e.getKeyChar() == '\n')) {
+ input = new String(inputArea.getText());
+ try {
+ current_source.setPeriod(Integer.parseInt(input));
+ current_source.draw();
+ inputArea.setText("");
+ reportArea.setText("Please enter a label for this source in the input area");
+ mode = LABEL_TYPING;
+ source_needs_label = true;
+ } catch (NumberFormatException nfe) {
+ reportArea.setText("Please enter a positive integer value");
+ inputArea.setText("");
+ return;
+ } catch (BoundsException be) {
+ reportArea.setText(be.getMessage());
+ } /* try */
+ } else if ((mode == LOAD) && (e.getKeyChar() == '\n')) {
+ File input_file;
+ input = new String(inputArea.getText());
+ try {
+ input_file = new File(input,"r",config,canvas);
+ input_file.readConfiguration();
+ input_file.close();
+ reportArea.setText("Configuration loaded successfully");
+ inputArea.setText("");
+ } catch (java.io.FileNotFoundException fnfe) {
+ } catch (java.io.IOException ioe) {
+ } catch (TooManyPrimitivesException tmpe) {
+ reportArea.setText(tmpe.getMessage());
+ }
+ } else if ((mode == SAVE) && (e.getKeyChar() == '\n')) {
+ File output_file;
+ input = new String(inputArea.getText());
+ try {
+ output_file = new File(input,"rw",config,canvas);
+ output_file.writeConfiguration();
+ output_file.close();
+ reportArea.setText("Configuration saved successfully");
+ inputArea.setText("");
+ } catch (java.io.FileNotFoundException fnfe) {
+ } catch (java.io.IOException ioe) {}
+ } /* if */
+ } /* keyPressed */
+ } /* EACKeyAdapter */
+
+ // Mouse Adapter Instances
+ private EACMouseAdapter eac_mouse_adapter = new EACMouseAdapter(this);
+ private EACMouseMotionAdapter eac_mm_adapter = new EACMouseMotionAdapter();
+
+ // Key Adapter Instance
+ private EACKeyAdapter eac_key_adapter = new EACKeyAdapter(this);
+
+ public void paint(Graphics g) {
+ g.setColor(getBackground());
+ g.fillRect(0,0,getSize().width,getSize().height);
+ g.setColor(getForeground());
+ g.drawRect(0,0,getSize().width - 1,getSize().height - 1);
+ config.draw();
+ } /* paint */
+
+ public void repaint() {
+ paint(getGraphics());
+ } /* repaint */
+} \ No newline at end of file
diff --git a/java/EAC/EACPrintStream.java b/java/EAC/EACPrintStream.java
new file mode 100644
index 00000000000..9e8d82d03f0
--- /dev/null
+++ b/java/EAC/EACPrintStream.java
@@ -0,0 +1,16 @@
+/**
+ * Title: EACFileStream
+ * Description: A stream class for conducting file I/O in the Event Analysis Configurator.
+ */
+package EAC;
+
+import java.io.RandomAccessF;
+
+public class EACPrintStream {
+
+ PrintStream ps;
+
+ public EACPrintStream(String filename) {
+ ps = new PrintStream(new FileOutputStream(filename), true);
+ }
+} \ No newline at end of file
diff --git a/java/EAC/EmptyQueueException.java b/java/EAC/EmptyQueueException.java
new file mode 100644
index 00000000000..0b2af00c36f
--- /dev/null
+++ b/java/EAC/EmptyQueueException.java
@@ -0,0 +1,13 @@
+/**
+ * Title: EmptyQueueException
+ * Description: An exception class for when an attempt is made to access
+ * the head of the event queue when the queue is empty
+ */
+package EAC;
+
+public class EmptyQueueException extends Exception {
+
+ public EmptyQueueException(String msg) {
+ super(msg);
+ }
+} \ No newline at end of file
diff --git a/java/EAC/File.java b/java/EAC/File.java
new file mode 100644
index 00000000000..6ba151cddc0
--- /dev/null
+++ b/java/EAC/File.java
@@ -0,0 +1,118 @@
+/**
+ * Title: File
+ * Description: A file I/O class for the Event Analysis Configurator
+ */
+package EAC;
+
+import java.io.RandomAccessFile;
+
+public class File extends RandomAccessFile {
+
+ public final int SOURCE = 1;
+ public final int SINK = 2;
+ public final int COMPONENT = 3;
+ public final int CONNECTOR = 4;
+ public final int UNION = 5;
+ public final int INTERSECTION = 6;
+ public final int LABEL = 7;
+
+ protected Configuration config;
+
+ protected EACPanel canvas;
+
+ public File(String filename, String mode, Configuration c, EACPanel p)
+ throws java.io.FileNotFoundException {
+ super(filename,mode);
+ config = c;
+ canvas = p;
+ } /* constructor */
+
+ public void writeConfiguration() throws java.io.IOException {
+ int i;
+
+ // write number of primitives
+ writeInt(config.getPrimitiveCount());
+
+ // write primitives
+ for (i = 0; i < config.getPrimitiveCount(); i++)
+ config.getPrimitive(i).write(this);
+
+ } /* writeConfiguration */
+
+ public void readConfiguration() throws java.io.IOException, TooManyPrimitivesException {
+ int i,
+ num,
+ label_length, // for reading the number of chars in an EACLabel
+ primitiveID;
+
+ Primitive next_primitive = new Union(canvas); // dummy initialization
+
+ Connector next_connector;
+
+ // read number of primitives
+ num = readInt();
+
+ for (i = 0; i < num; i++) {
+ primitiveID = readInt();
+ switch(primitiveID) {
+ case SOURCE:
+ next_primitive = new Source(canvas,config);
+ next_primitive.read(this);
+ i++; // Add one more to the loop counter 'cause we read our own label
+ break;
+ case SINK:
+ next_primitive = new Sink(canvas);
+ next_primitive.read(this);
+ break;
+ case COMPONENT:
+ next_primitive = new EACComponent(canvas,config);
+ next_primitive.read(this);
+ i++; // Add one more to the loop counter 'cause we read our own label
+ break;
+ case CONNECTOR:
+ next_connector = new Connector(canvas);
+ next_primitive = next_connector; // so it can be added to the config
+ next_connector.read(this);
+ try {
+ int connector_start_index = config.leftSideOverlaps(next_connector);
+ int connector_end_index = config.rightSideOverlaps(next_connector);
+
+ Primitive startP = config.getPrimitive(connector_start_index);
+ Primitive endP = config.getPrimitive(connector_end_index);
+
+ // reinstate connection
+ startP.addOutput(next_connector);
+ next_connector.setInput(startP);
+ next_connector.setOutput(endP);
+ endP.addInput(next_connector);
+
+ } catch (ConnectionException ce) {
+ // can't happen (right?)
+ } /* try */
+ break;
+ case UNION:
+ next_primitive = new Union(canvas);
+ next_primitive.read(this);
+ break;
+ case INTERSECTION:
+ next_primitive = new Intersection(canvas);
+ next_primitive.read(this);
+ break;
+ case LABEL:
+ label_length = readInt();
+ next_primitive = new EACLabel(canvas,label_length);
+ next_primitive.read(this);
+ break;
+ } /* switch */
+
+ // add to configuration
+ config.addPrimitive(next_primitive);
+
+ } /* for */
+
+ // draw the configuration
+ config.draw();
+
+ } /* readConfiguration */
+
+} \ No newline at end of file
diff --git a/java/EAC/InputMode.java b/java/EAC/InputMode.java
new file mode 100644
index 00000000000..c44e4a45c4d
--- /dev/null
+++ b/java/EAC/InputMode.java
@@ -0,0 +1,32 @@
+/**
+ * Title: InputMode
+ * Description: Maintains Configurator state for deciding how to handle input
+ */
+package EAC;
+
+public class InputMode {
+
+ public final int COMMAND = 0;
+ public final int SELECT = 1;
+ public final int CUT = 2;
+ public final int COPY = 3;
+ public final int PASTE = 4;
+ public final int EDIT = 5;
+ public final int RESIZE = 6;
+
+ protected int mode;
+
+ protected Primitive current_shape;
+
+ public InputMode() {
+ mode = COMMAND;
+ } /* constructor */
+
+ public int getMode() {
+ return mode;
+ } /* getMode */
+
+ protected void setMode(int m) {
+ mode = m;
+ } /* setMode */
+} \ No newline at end of file
diff --git a/java/EAC/Intersection.java b/java/EAC/Intersection.java
new file mode 100644
index 00000000000..1e1beafb770
--- /dev/null
+++ b/java/EAC/Intersection.java
@@ -0,0 +1,62 @@
+/**
+ * Title: Intersection
+ * Description: A binary intersection operator class for the Event Analysis
+ * Configurator. Acts as a sort of filter, combining two event
+ * streams into one.
+ */
+package EAC;
+import java.awt.*;
+
+public class Intersection extends Operator {
+
+ // Where did the last event come from?
+ protected Primitive last_event_source;
+
+ public Intersection(EACPanel p) {
+ super(p);
+ last_event_source = null;
+ } /* constructor */
+
+ public void draw() throws BoundsException {
+ // the intersection symbol
+ final char iSymbol = '^';
+
+ // subtle adjustments to position symbol within circle
+ final int xTweak = 2;
+ final int yTweak = -5;
+
+ char symbol[] = new char[1];
+ Graphics g = canvas.getGraphics();
+
+ super.draw();
+ symbol[0] = iSymbol;
+ g.drawChars(symbol,0,1,
+ anchor.x + (int) (DIAMETER / 2) - xTweak,
+ anchor.y + (int) (DIAMETER / 2) - yTweak);
+ } /* draw */
+
+ public void event(Source s) throws ConnectionException {
+ //System.out.println("Intersection event");
+ if (last_event_source == null)
+ last_event_source = s;
+ else if (last_event_source != s) { // we've now gotten events from two distinct sources
+ int i;
+
+ last_event_source = null;
+ for (i = 0; i < output_count; i++)
+ output[i].event(s);
+ } // else no-op, because this event is from the same source as the last event
+ } /* event */
+
+ public void write(File f) throws java.io.IOException {
+ f.writeInt(f.INTERSECTION);
+ f.writeInt(anchor.x);
+ f.writeInt(anchor.y);
+ } /* write */
+
+ public void read(File f) throws java.io.IOException {
+ anchor = new Point();
+ anchor.x = f.readInt();
+ anchor.y = f.readInt();
+ } /* read */
+} \ No newline at end of file
diff --git a/java/EAC/Operator.java b/java/EAC/Operator.java
new file mode 100644
index 00000000000..724c9583b20
--- /dev/null
+++ b/java/EAC/Operator.java
@@ -0,0 +1,206 @@
+/**
+ * Title: Operator
+ * Description: An abstract binary operator class for the Event Analysis
+ * Configurator
+ */
+package EAC;
+import java.awt.*;
+
+public abstract class Operator extends Primitive {
+
+ // Radius of the circle
+ protected final int DIAMETER = 40;
+
+ // inputs
+ protected Connector left_input,
+ right_input;
+
+ // outputs
+ protected Connector output[] = new Connector[MAX_OUTPUTS];
+ protected int output_count = 0;
+
+ // helps with dragging the operator
+ protected boolean selected;
+ Point old_anchor;
+
+ public Operator(EACPanel p) {
+ super(p);
+ } /* constructor */
+
+ public void setTop(Point p) {
+ anchor = new Point(p.x - (int) (DIAMETER / 2), p.y);
+ } /* setTop */
+
+ public Point getTop() {
+ return new Point(anchor.x + (int) (DIAMETER / 2), anchor.y);
+ } /* getTop */
+
+ public void draw() throws BoundsException {
+ Graphics g = canvas.getGraphics();
+
+ if (selected)
+ selected = false;
+ else if (inBounds())
+ g.drawOval(anchor.x, anchor.y, DIAMETER, DIAMETER);
+ else
+ throw new BoundsException("ERROR: Attempted to place Operator partially out of bounds");
+ } /* draw */
+
+ public void specialDraw() {
+ Graphics g = canvas.getGraphics();
+
+ g.setXORMode(canvas.getBackground());
+ g.drawOval(anchor.x,anchor.y,DIAMETER,DIAMETER);
+ } /* specialDraw */
+
+ public void specialUndraw() {
+ Graphics g = canvas.getGraphics();
+
+ g.setColor(canvas.getBackground());
+ g.setXORMode(canvas.getForeground());
+ g.drawOval(anchor.x,anchor.y,DIAMETER,DIAMETER);
+ } /* specialUndraw */
+
+ public void selectedDraw() {
+ old_anchor = anchor;
+ selected = true;
+ super.selectedDraw();
+ } /* selectedDraw */
+
+ public void reconnect() {
+ int i;
+
+ // move output anchors
+ for (i = 0; i < output_count; i++)
+ output[i].setAnchor(new Point(output[i].getAnchor().x + anchor.x - old_anchor.x,
+ output[i].getAnchor().y + anchor.y - old_anchor.y));
+
+ // move input endpoints
+ if (left_input != null)
+ left_input.setEndpoint(new Point(left_input.upperRight().x + anchor.x - old_anchor.x,
+ left_input.upperRight().y + anchor.y - old_anchor.y));
+ if (right_input != null)
+ right_input.setEndpoint(new Point(right_input.upperRight().x + anchor.x - old_anchor.x,
+ right_input.upperRight().y + anchor.y - old_anchor.y));
+
+ } /* reconnect */
+
+ public boolean contains(Point p) {
+ if ((p.x >= anchor.x) &&
+ (p.x <= anchor.x + DIAMETER) &&
+ (p.y >= anchor.y) &&
+ (p.y <= anchor.y + DIAMETER))
+ return true;
+ else
+ return false;
+ } /* contains */
+
+ public Point upperLeft() {
+ return anchor;
+ } /* upperLeft */
+
+ public Point lowerRight() {
+ return new Point(anchor.x + DIAMETER, anchor.y + DIAMETER);
+ } /* lowerRight */
+
+ public Point upperRight() {
+ return new Point(anchor.x + DIAMETER, anchor.y);
+ } /* upperRight */
+
+ public Point lowerLeft() {
+ return new Point(anchor.x, anchor.y + DIAMETER);
+ } /* lowerLeft */
+
+ public int addInput(Connector c) throws ConnectionException {
+ if (left_input == null) {
+ left_input = c;
+ return 0;
+ } else if (right_input == null) {
+ right_input = c;
+ return 1;
+ } else
+ throw new ConnectionException("ERROR: Operator already has two inputs");
+ } /* addInput */
+
+ public int addOutput(Connector c) throws ConnectionException {
+ if (output_count < MAX_OUTPUTS)
+ output[output_count++] = c;
+ else
+ throw new ConnectionException("ERROR: Maximum outputs established for this operator");
+
+ return output_count;
+ } /* addOutput */
+
+ public Connector getInput(int i) throws ConnectionException {
+ if ((i < 0) || (i > 1))
+ throw new ConnectionException("ERROR: Bad input index for operator");
+ else if (i == 0) {
+ if (left_input == null)
+ throw new ConnectionException("ERROR: No left input for operator");
+ else
+ return left_input;
+ } else // i == 1
+ if (right_input == null)
+ throw new ConnectionException("ERROR: No right input for operator");
+
+ return right_input;
+ } /* getInput */
+
+ public Connector getOutput(int i) throws ConnectionException {
+ if ((i >= 0) && (i < output_count))
+ return output[i];
+ else
+ throw new ConnectionException("ERROR: Bad output index for operator");
+ } /* getOutput */
+
+ public void removeInput(int i) throws ConnectionException {
+ if ((i < 0) || (i > 1))
+ throw new ConnectionException("ERROR: Bad input index for operator");
+ else if (i == 0) {
+ if (left_input == null)
+ throw new ConnectionException("ERROR: No left input for operator");
+ else
+ left_input = null;
+ } else if (i == 1) {
+ if (right_input == null)
+ throw new ConnectionException("ERROR: No right input for operator");
+ else
+ right_input = null;
+ }
+ } /* removeInput */
+
+ public void removeOutput(int i) throws ConnectionException {
+ if ((i < 0) || (i > output_count))
+ throw new ConnectionException("ERROR: Bad output index for operator");
+ else {
+ output[i] = output[output_count-1];
+ --output_count;
+ }
+ } /* removeOutput */
+
+ public int getOutputCount() throws ConnectionException {
+ return output_count;
+ } /* getOutputCount */
+
+ public int getInputCount() throws ConnectionException {
+ if (left_input == null)
+ return 0;
+ else if (right_input == null)
+ return 1;
+ else
+ return 2;
+ } /* getInputCount */
+
+ public void wakeup(long t) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to wake up operator");
+ } /* wakeup */
+
+ public boolean inBounds() {
+ if (canvas.contains(anchor.x,anchor.y) &&
+ canvas.contains(anchor.x + DIAMETER, anchor.y + DIAMETER))
+ return true;
+ else
+ return false;
+ } /* inBounds */
+
+} \ No newline at end of file
diff --git a/java/EAC/Primitive.java b/java/EAC/Primitive.java
new file mode 100644
index 00000000000..a0532a9731b
--- /dev/null
+++ b/java/EAC/Primitive.java
@@ -0,0 +1,121 @@
+/**
+ * Title: Primitive
+ * Description: An abstract class for Event Analysis Configurator graphical
+ * primitives
+ */
+package EAC;
+import java.awt.*;
+import java.io.*;
+
+public abstract class Primitive {
+
+ // maximum number of outputs from any primitive
+ public final int MAX_OUTPUTS = 8;
+
+ // maximum number of inputs to a sink
+ public final int MAX_INPUTS = 8;
+
+ // where the primitive will be drawn
+ protected EACPanel canvas;
+
+ // anchor point of the graphical shape
+ protected Point anchor;
+
+ // associated label
+ protected EACLabel label;
+
+ public Primitive(EACPanel p) {
+ canvas = p;
+ } /* constructor */
+
+ public void setAnchor(Point p) {
+ anchor = p;
+ } /* setAnchor */
+
+ public Point getAnchor() {
+ return anchor;
+ } /* getAnchor */
+
+ public void setLabel(EACLabel l) {
+ label = l;
+ } /* setLabel */
+
+ public EACLabel getLabel() {
+ return label;
+ } /* getLabel */
+
+ public void restart() {
+ // no-op for most primitives
+ // overload as needed
+ } /* restart */
+
+ public void specialDraw() {
+ // no-op for some primitives
+ // overload as needed
+ } /* specialDraw */
+
+ public void specialUndraw() {
+ // no-op for some primitives
+ // overload as needed
+ } /* specialUndraw */
+
+ public void reconnect() {
+ // no-op for some primitives
+ // overload as needed
+ } /* reconnect */
+
+ public void selectedDraw() {
+ final int d = 4; // dimension of hotspot
+ Graphics g = canvas.getGraphics();
+
+ g.setColor(java.awt.Color.darkGray);
+ g.drawRect(upperLeft().x - (d/2),upperLeft().y - (d/2), d, d);
+ g.drawRect(lowerLeft().x - (d/2),lowerLeft().y - (d/2), d, d);
+ g.drawRect(upperRight().x - (d/2),upperRight().y - (d/2), d, d);
+ g.drawRect(lowerRight().x - (d/2),lowerRight().y - (d/2), d, d);
+ } /* selectedDraw */
+
+ // establish the top center point of the graphical shape
+ public abstract void setTop(Point p);
+
+ public abstract Point getTop();
+
+ public abstract boolean inBounds();
+
+ public abstract int addInput(Connector c) throws ConnectionException;
+
+ public abstract int addOutput(Connector c) throws ConnectionException;
+
+ public abstract Connector getInput(int i) throws ConnectionException;
+
+ public abstract Connector getOutput(int i) throws ConnectionException;
+
+ public abstract void removeInput(int i) throws ConnectionException;
+
+ public abstract void removeOutput(int i) throws ConnectionException;
+
+ public abstract int getInputCount() throws ConnectionException;
+
+ public abstract int getOutputCount() throws ConnectionException;
+
+ public abstract void event(Source s) throws ConnectionException;
+
+ public abstract void wakeup(long t) throws ConnectionException;
+
+ public abstract void draw() throws BoundsException;
+
+ public abstract void write(File f) throws java.io.IOException;
+
+ public abstract void read(File f) throws java.io.IOException;
+
+ public abstract boolean contains(Point p);
+
+ public abstract Point upperLeft();
+
+ public abstract Point lowerRight();
+
+ public abstract Point upperRight();
+
+ public abstract Point lowerLeft();
+
+} \ No newline at end of file
diff --git a/java/EAC/Queue.java b/java/EAC/Queue.java
new file mode 100644
index 00000000000..20c4483a17a
--- /dev/null
+++ b/java/EAC/Queue.java
@@ -0,0 +1,94 @@
+/**
+ * Title: Queue
+ * Description: The primary event queue for the Event Analysis Configurator
+ */
+package EAC;
+
+public class Queue {
+
+ private class Node {
+
+ public Primitive primitive;
+ public long time;
+ public Node next;
+
+ public Node(Primitive p, long t, Node n) {
+ primitive = p;
+ time = t;
+ next = n;
+ } /* constructor */
+
+ } /* Node */
+
+ private Node head;
+
+ private int count;
+
+ public Queue() {
+ count = 0;
+ } /* constructor */
+
+ public boolean empty() {
+ return (count == 0);
+ } /* empty */
+
+ public void clear() {
+ while (!empty())
+ try {
+ dequeue();
+ } catch (EmptyQueueException eqe) {
+ // can't happen
+ }
+ } /* clear */
+
+ public void enqueue(Primitive p, long t) {
+ if (head == null) {
+ head = new Node(p,t,null);
+ count = 1;
+ } else { // non-empty
+ if ((head.time == t) && (head.primitive == p))
+ return; // no duplicates
+ else if (head.time >= t) { // need new head
+ Node temp = new Node(p,t,head);
+ head = temp;
+ } else { // find insertion point
+ Node ptr = head;
+
+ while (ptr.next != null)
+ if (ptr.next.time < t)
+ ptr = ptr.next;
+ else
+ break;
+
+ if (ptr.next == null)
+ ptr.next = new Node(p,t,null);
+ else if ((ptr.next.time == t) && (ptr.next.primitive == p))
+ return; // no duplicates
+ else {
+ Node temp = new Node(p,t,ptr.next);
+ ptr.next = temp;
+ }
+ }
+
+ count++;
+ } /* else */
+ } /* enqueue */
+
+ public Primitive dequeue () throws EmptyQueueException {
+ if (count == 0)
+ throw new EmptyQueueException("ERROR: dequeue called when queue empty");
+
+ Primitive temp = head.primitive;
+ head = head.next;
+ --count;
+ return temp;
+ } /* dequeue */
+
+ public long frontTime () throws EmptyQueueException {
+ if (count == 0)
+ throw new EmptyQueueException("ERROR: frontTime called when queue empty");
+
+ return head.time;
+ } /* frontTime */
+
+} \ No newline at end of file
diff --git a/java/EAC/README b/java/EAC/README
new file mode 100644
index 00000000000..91773ab16bd
--- /dev/null
+++ b/java/EAC/README
@@ -0,0 +1,6 @@
+This directory contains the source code for the Event Analysis Configurator (EAC).
+The EAC was built as a final project for an Advanced User Interface (CS 501) course,
+taught by Dr. Kimura in the fall of 2000.
+
+There are also two MS-Word documents which were written as part of the project.
+Hopefully these will explain what the EAC is, what it does, and how it works.
diff --git a/java/EAC/ResourcePool.java b/java/EAC/ResourcePool.java
new file mode 100644
index 00000000000..c2200baa2fc
--- /dev/null
+++ b/java/EAC/ResourcePool.java
@@ -0,0 +1,46 @@
+/**
+ * Title: ResourcePool
+ * Description: An abstraction of a collection of resources that can be
+ * reserved and released by real-time components
+ */
+package EAC;
+
+public class ResourcePool {
+
+ // percentage of resources reserved
+ protected int reserved;
+
+ public ResourcePool()
+ {
+ reserved = 0;
+ } /* default constructor */
+
+ public ResourcePool(int r) {
+ reserved = r;
+ } /* constructor */
+
+ public int usage() {
+ return reserved;
+ } /* usage */
+
+ public boolean reserve(int r) {
+ if (reserved + r > 100)
+ return false;
+ else {
+ //System.out.println("Reservation ok: " + java.lang.Integer.toString(r));
+ reserved += r;
+ return true;
+ } /* else */
+ } /* reserve */
+
+ public boolean release(int r) {
+ if (reserved - r < 0)
+ return false;
+ else {
+ //System.out.println("Release ok: " + java.lang.Integer.toString(r));
+ reserved -= r;
+ return true;
+ } /* else */
+ } /* release */
+
+} \ No newline at end of file
diff --git a/java/EAC/Rubberband.java b/java/EAC/Rubberband.java
new file mode 100644
index 00000000000..b5fcf7e60a0
--- /dev/null
+++ b/java/EAC/Rubberband.java
@@ -0,0 +1,103 @@
+/**
+ * A abstract base class for rubberbands.<p>
+ *
+ * Rubberbands do their rubberbanding inside of a Component,
+ * which must be specified at construction time.<p>
+ *
+ * Subclasses are responsible for implementing
+ * <em>void drawLast(Graphics g)</em> and
+ * <em>void drawNext(Graphics g)</em>.
+ *
+ * drawLast() draws the appropriate geometric shape at the last
+ * rubberband location, while drawNext() draws the appropriate
+ * geometric shape at the next rubberband location. All of the
+ * underlying support for rubberbanding is taken care of here,
+ * including handling XOR mode setting; extensions of Rubberband
+ * need not concern themselves with anything but drawing the
+ * last and next geometric shapes.<p>
+ *
+ * @version 1.00, 12/27/95
+ * @author David Geary
+ */
+package EAC;
+import java.awt.*;
+
+abstract public class Rubberband {
+ protected Point anchor = new Point(0,0);
+ protected Point stretched = new Point(0,0);
+ protected Point last = new Point(0,0);
+ protected Point end = new Point(0,0);
+
+ private Component component;
+ private boolean firstStretch = true;
+
+ abstract public void drawLast(Graphics g);
+ abstract public void drawNext(Graphics g);
+
+ public Rubberband(Component component) {
+ this.component = component;
+ }
+
+ public Point getAnchor () { return anchor; }
+ public Point getStretched() { return stretched; }
+ public Point getLast () { return last; }
+ public Point getEnd () { return end; }
+ public void setAnchor(Point p) { anchor = p; }
+ public void setEnd(Point p) { end = p; }
+
+ public void anchor(Point p) {
+ firstStretch = true;
+ anchor.x = p.x;
+ anchor.y = p.y;
+
+ stretched.x = last.x = anchor.x;
+ stretched.y = last.y = anchor.y;
+ }
+
+ public void stretch(Point p) {
+ last.x = stretched.x;
+ last.y = stretched.y;
+ stretched.x = p.x;
+ stretched.y = p.y;
+
+ Graphics g = component.getGraphics();
+ if (g != null) {
+ g.setXORMode(component.getBackground());
+
+ if (firstStretch == true)
+ firstStretch = false;
+ else
+ drawLast(g);
+
+ drawNext(g);
+ }
+ }
+
+ public void end(Point p) {
+ last.x = end.x = p.x;
+ last.y = end.y = p.y;
+
+ Graphics g = component.getGraphics();
+ if(g != null) {
+ g.setXORMode(component.getBackground());
+ drawLast(g);
+ }
+ }
+
+ public Rectangle bounds() {
+ return new Rectangle(stretched.x < anchor.x ?
+ stretched.x : anchor.x,
+ stretched.y < anchor.y ?
+ stretched.y : anchor.y,
+ Math.abs(stretched.x - anchor.x),
+ Math.abs(stretched.y - anchor.y));
+ }
+
+ public Rectangle lastBounds() {
+ return new Rectangle(
+ last.x < anchor.x ? last.x : anchor.x,
+ last.y < anchor.y ? last.y : anchor.y,
+ Math.abs(last.x - anchor.x),
+ Math.abs(last.y - anchor.y));
+ }
+}
diff --git a/java/EAC/RubberbandLine.java b/java/EAC/RubberbandLine.java
new file mode 100644
index 00000000000..8a4ebfd2230
--- /dev/null
+++ b/java/EAC/RubberbandLine.java
@@ -0,0 +1,28 @@
+/**
+ * Title: RubberbandLine
+ * Description: A line subclass of Rubberband
+ */
+package EAC;
+import java.awt.*;
+
+public class RubberbandLine extends Rubberband {
+
+ public RubberbandLine(EACPanel p) {
+ super(p);
+ } /* RubberbandLine constructor */
+
+ public void drawNext(Graphics g) {
+ g.drawLine(getAnchor().x,
+ getAnchor().y,
+ getStretched().x,
+ getStretched().y);
+ } /* drawNext */
+
+ public void drawLast(Graphics g) {
+ g.drawLine(getAnchor().x,
+ getAnchor().y,
+ getLast().x,
+ getLast().y);
+ } /* drawLast */
+
+} /* RubberbandLine */
diff --git a/java/EAC/Sink.java b/java/EAC/Sink.java
new file mode 100644
index 00000000000..f4f8d02d0fe
--- /dev/null
+++ b/java/EAC/Sink.java
@@ -0,0 +1,231 @@
+/**
+ * Title: Sink
+ * Description: An event sink for the Event Analysis Configurator
+ */
+package EAC;
+import java.awt.*;
+
+public class Sink extends Primitive {
+
+ // triangle dimensions
+ protected final int WIDTH = 20;
+ protected final int HEIGHT = 35;
+
+ // lower left and lower right corner points
+ // inherited anchor attribute holds the top point
+ protected Point p2,
+ p3;
+
+ // inputs
+ protected Connector input[] = new Connector[MAX_INPUTS];
+ protected int input_count;
+
+ // for help with dragging this Sink
+ Point old_anchor;
+
+ public Sink(EACPanel p) {
+ super(p);
+ } /* constructor */
+
+ public void draw() throws BoundsException {
+ int x[] = new int[3],
+ y[] = new int[3];
+
+ if (inBounds()) {
+ Graphics g = canvas.getGraphics();
+
+ g.drawLine(anchor.x,anchor.y,p2.x,p2.y);
+ g.drawLine(p2.x,p2.y,p3.x,p3.y);
+ g.drawLine(p3.x,p3.y,anchor.x,anchor.y);
+
+ /* Make it black */
+ x[0] = anchor.x;
+ x[1] = p2.x;
+ x[2] = p3.x;
+
+ y[0] = anchor.y;
+ y[1] = p2.y;
+ y[2] = p3.y;
+
+ g.fillPolygon(x,y,3);
+ } else
+ throw new BoundsException("ERROR: Attempted to place Sink partially out of bounds");
+ } /* draw */
+
+ public void selectedDraw() {
+ old_anchor = anchor;
+ super.selectedDraw();
+ } /* selectedDraw */
+
+ public void specialDraw() {
+ int x[] = new int[3],
+ y[] = new int[3];
+
+ Graphics g = canvas.getGraphics();
+
+ g.setXORMode(canvas.getBackground());
+ g.drawLine(anchor.x,anchor.y,p2.x,p2.y);
+ g.drawLine(p2.x,p2.y,p3.x,p3.y);
+ g.drawLine(p3.x,p3.y,anchor.x,anchor.y);
+
+ /* Make it black */
+ x[0] = anchor.x;
+ x[1] = p2.x;
+ x[2] = p3.x;
+
+ y[0] = anchor.y;
+ y[1] = p2.y;
+ y[2] = p3.y;
+
+ g.fillPolygon(x,y,3);
+ } /* specialDraw */
+
+ public void specialUndraw() {
+ int x[] = new int[3],
+ y[] = new int[3];
+
+ Graphics g = canvas.getGraphics();
+
+ g.setColor(canvas.getBackground());
+ g.setXORMode(canvas.getForeground());
+ g.drawLine(anchor.x,anchor.y,p2.x,p2.y);
+ g.drawLine(p2.x,p2.y,p3.x,p3.y);
+ g.drawLine(p3.x,p3.y,anchor.x,anchor.y);
+
+ /* Make it black */
+ x[0] = anchor.x;
+ x[1] = p2.x;
+ x[2] = p3.x;
+
+ y[0] = anchor.y;
+ y[1] = p2.y;
+ y[2] = p3.y;
+
+ g.fillPolygon(x,y,3);
+ } /* specialUndraw */
+
+ public void reconnect() {
+ int i;
+
+ for (i = 0; i < input_count; i++)
+ input[i].setEndpoint(new Point(input[i].upperRight().x + anchor.x - old_anchor.x,
+ input[i].upperRight().y + anchor.y - old_anchor.y));
+ } /* reconnect */
+
+ public boolean contains(Point p) {
+ if ((p.x >= p2.x) &&
+ (p.x <= p3.x) &&
+ (p.y >= anchor.y) &&
+ (p.y <= anchor.y + HEIGHT))
+ return true;
+ else
+ return false;
+ } /* contains */
+
+ public Point upperLeft() {
+ return new Point(p2.x,anchor.y);
+ } /* upperLeft */
+
+ public Point lowerRight() {
+ return p3;
+ } /* lowerRight */
+
+ public Point upperRight() {
+ return new Point(p3.x,anchor.y);
+ } /* upperRight */
+
+ public Point lowerLeft() {
+ return p2;
+ } /* lowerLeft */
+
+ public void setTop(Point p) {
+ anchor = p;
+ p2 = bottomLeft();
+ p3 = bottomRight();
+ } /* setTop */
+
+ public Point getTop() {
+ return anchor;
+ } /* getTop */
+
+ public boolean inBounds() {
+ if (canvas.contains(bottomLeft()) &&
+ canvas.contains(bottomRight()))
+ return true;
+ else
+ return false;
+ } /* inBounds */
+
+ private Point bottomLeft() {
+ return new Point(anchor.x - WIDTH, anchor.y + HEIGHT);
+ } /* bottomLeft */
+
+ private Point bottomRight() {
+ return new Point(anchor.x + WIDTH, anchor.y + HEIGHT);
+ } /* bottomRight */
+
+ public void write(File f) throws java.io.IOException {
+ f.writeInt(f.SINK);
+ f.writeInt(anchor.x);
+ f.writeInt(anchor.y);
+ } /* write */
+
+ public void read(File f) throws java.io.IOException {
+ anchor = new Point();
+ anchor.x = f.readInt();
+ anchor.y = f.readInt();
+ p2 = bottomLeft();
+ p3 = bottomRight();
+ } /* read */
+
+ public int addInput(Connector c) throws ConnectionException {
+ if (input_count == MAX_INPUTS)
+ throw new ConnectionException("ERROR: Maximum inputs established for sink");
+ else
+ input[input_count++] = c;
+
+ return input_count;
+ } /* addInput */
+
+ public int addOutput(Connector c) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to add output to sink");
+ } /* addOutput */
+
+ public Connector getInput(int i) throws ConnectionException {
+ if ((i < 0) || (i >= input_count))
+ throw new ConnectionException("ERROR: Bad input index for sink");
+ else
+ return input[i];
+ } /* getInput */
+
+ public Connector getOutput(int i) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to retrieve output from source");
+ } /* getOutput */
+
+ public void removeOutput(int i) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to remove output from source");
+ } /* removeOutput */
+
+ public void removeInput(int i) throws ConnectionException {
+ if ((i >= 0) && (i < input_count)) {
+ input[i] = input[input_count-1];
+ --input_count;
+ } else
+ throw new ConnectionException("ERROR: Bad input index for sink");
+ } /* removeInput */
+
+ public int getInputCount() throws ConnectionException {
+ return input_count;
+ } /* getInputCount */
+
+ public int getOutputCount() throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to retrieve output count from sink");
+ } /* getOutputCount */
+
+ public void event(Source s) {
+ } /* event */
+
+ public void wakeup(long t) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to wake up sink");
+ } /* wakeup */
+} \ No newline at end of file
diff --git a/java/EAC/Source.java b/java/EAC/Source.java
new file mode 100644
index 00000000000..d8b50ee224f
--- /dev/null
+++ b/java/EAC/Source.java
@@ -0,0 +1,341 @@
+/**
+ * Title: Source
+ * Description: An event source for the Event Analysis Configurator
+ */
+package EAC;
+import java.awt.*;
+
+public class Source extends Primitive {
+
+ // Font for text
+ protected Font text_font = new EACFont().getFont();
+
+ // triangle dimensions
+ protected final int WIDTH = 20;
+ protected final int HEIGHT = 35;
+
+ // lower left and lower right corner points
+ // inherited anchor attribute holds the top point
+ protected Point p2,
+ p3;
+
+ // period at which events will be generated
+ protected int period;
+
+ // where the Source was anchored prior to a move
+ protected Point old_anchor;
+
+ // where events will be pushed
+ protected Connector output[] = new Connector[MAX_OUTPUTS];
+ protected int output_count;
+
+ // Is this Source currently selected for dragging?
+ protected boolean selected = false;
+
+ // Black-on-white (normal) or white-on-black (reversed)?
+ protected boolean reverse_color = false;
+
+ // configuration to which the Source belongs
+ Configuration config;
+
+ public Source(EACPanel p, Configuration c) {
+ super(p);
+ config = c;
+ output_count = 0;
+ period = 0;
+ } /* constructor */
+
+ private void drawTriangle(Graphics g) {
+ g.drawLine(anchor.x,anchor.y,p2.x,p2.y);
+ g.drawLine(p2.x,p2.y,p3.x,p3.y);
+ g.drawLine(p3.x,p3.y,anchor.x,anchor.y);
+ } /* drawTriangle */
+
+ public void draw() throws BoundsException {
+ int x[] = new int[3],
+ y[] = new int[3];
+
+ if (selected)
+ selected = false;
+ else if (inBounds()) {
+ Graphics g = canvas.getGraphics();
+ Color bg,
+ fg;
+
+ x[0] = anchor.x;
+ x[1] = p2.x;
+ x[2] = p3.x;
+
+ y[0] = anchor.y;
+ y[1] = p2.y;
+ y[2] = p3.y;
+
+ if (reverse_color) {
+ bg = Color.black;
+ fg = Color.white;
+ } else {
+ bg = Color.white;
+ fg = Color.black;
+ }
+
+ g.setColor(bg); // for interior
+ g.fillPolygon(x,y,3);
+
+ g.setColor(Color.black); // triangle itself is always black
+ drawTriangle(g);
+
+ g.setColor(fg); // for text
+
+ // print period
+ if (period > 0) {
+ g.setFont(text_font);
+ g.drawString(java.lang.String.valueOf(period),
+ anchor.x - (3 * java.lang.String.valueOf(period).length()),
+ anchor.y + 28);
+ }
+ } else
+ throw new BoundsException("ERROR: Attempted to place source partially out of bounds");
+ } /* draw */
+
+ public void selectedDraw() {
+ Graphics g = canvas.getGraphics();
+ int x[] = new int[3],
+ y[] = new int[3];
+
+ old_anchor = anchor;
+ x[0] = anchor.x;
+ x[1] = p2.x;
+ x[2] = p3.x;
+
+ y[0] = anchor.y;
+ y[1] = p2.y;
+ y[2] = p3.y;
+
+ //drawTriangle();
+ g.setColor(canvas.getBackground());
+ g.fillPolygon(x,y,3);
+
+ // this will preclude drawing this Source for one repaint() call
+ selected = true;
+
+ super.selectedDraw();
+ } /* selectedDraw */
+
+ public void specialDraw() {
+ Graphics g = canvas.getGraphics();
+
+ g.setXORMode(canvas.getBackground());
+ drawTriangle(g);
+ } /* specialDraw */
+
+ public void specialUndraw() {
+ Graphics g = canvas.getGraphics();
+
+ g.setColor(canvas.getBackground());
+ g.setXORMode(canvas.getForeground());
+ drawTriangle(g);
+ } /* specialUndraw */
+
+ public void reverseColor() {
+ reverse_color = true;
+ } /* reverseColor */
+
+ public void normalColor() {
+ reverse_color = false;
+ } /* normalColor */
+
+ public void reconnect() {
+ int i;
+
+ for (i = 0; i < output_count; i++)
+ output[i].setAnchor(new Point(output[i].getAnchor().x + anchor.x - old_anchor.x,
+ output[i].getAnchor().y + anchor.y - old_anchor.y));
+
+ // move label anchor
+ label.setAnchor(new Point(label.getAnchor().x + anchor.x - old_anchor.x,
+ label.getAnchor().y + anchor.y - old_anchor.y));
+ } /* reconnect */
+
+ public boolean contains(Point p) {
+ if ((p.x >= p2.x) &&
+ (p.x <= p3.x) &&
+ (p.y >= anchor.y) &&
+ (p.y <= anchor.y + HEIGHT))
+ return true;
+ else
+ return false;
+ } /* contains */
+
+ public Point upperLeft() {
+ return new Point(p2.x,anchor.y);
+ } /* upperLeft */
+
+ public Point lowerRight() {
+ return p3;
+ } /* lowerRight */
+
+ public Point upperRight() {
+ return new Point(p3.x,anchor.y);
+ } /* upperRight */
+
+ public Point lowerLeft() {
+ return p2;
+ } /* lowerLeft */
+
+ public void setTop(Point p) {
+ anchor = p;
+ p2 = bottomLeft();
+ p3 = bottomRight();
+ } /* setTop */
+
+ public Point getTop() {
+ return anchor;
+ } /* getTop */
+
+ public void setPeriod(int p) throws NumberFormatException {
+ if (p > 0) {
+ period = p;
+ config.eventEnqueue(this,period); // Enqueue first wakeup time
+ }
+ else
+ throw new NumberFormatException();
+ } /* setPeriod */
+
+ public int getPeriod() {
+ return period;
+ } /* getPeriod */
+
+ public void restart() {
+ config.eventEnqueue(this,period);
+ reverse_color = false;
+ selected = false;
+ } /* restart */
+
+ public int addOutput(Connector c) throws ConnectionException {
+ if (output_count == MAX_OUTPUTS)
+ throw new ConnectionException("ERROR: Maximum outputs established for source");
+ else
+ output[output_count++] = c;
+
+ return output_count;
+ } /* addOutput */
+
+ public int addInput(Connector c) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to add input to source");
+ } /* addInput */
+
+ public Connector getOutput(int i) throws ConnectionException {
+ if ((i < 0) || (i >= output_count))
+ throw new ConnectionException("ERROR: Bad output index for source");
+ else
+ return output[i];
+ } /* getOutput */
+
+ public Connector getInput(int i) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to retrieve input from source");
+ } /* getInput */
+
+ public void removeInput(int i) throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to remove input from source");
+ } /* removeInput */
+
+ public void removeOutput(int i) throws ConnectionException {
+ if ((i >= 0) && (i < output_count)) {
+ output[i] = output[output_count-1];
+ --output_count;
+ } else
+ throw new ConnectionException("ERROR: Bad output index for source");
+ } /* removeOutput */
+
+ public int getOutputCount() throws ConnectionException {
+ return output_count;
+ } /* getOutputCount */
+
+ public int getInputCount() throws ConnectionException {
+ throw new ConnectionException("ERROR: Attempted to retrieve input count from source");
+ } /* getInputCount */
+
+ public void event(Source s) throws ConnectionException {
+ throw new ConnectionException("Internal error: event() called on source");
+ } /* event */
+
+ public void wakeup(long t) throws ConnectionException {
+ int i;
+
+ //System.out.println("Source wakeup at: " + java.lang.Long.toString(t));
+ config.eventEnqueue(this,t + period); // enqueue next wakeup time
+
+ // send an event to all outputs
+ for (i = 0; i < output_count; i++)
+ output[i].event(this);
+ } /* wakeup */
+
+ public boolean inBounds() {
+ if (canvas.contains(bottomLeft()) &&
+ canvas.contains(bottomRight()) &&
+ canvas.contains(anchor))
+ return true;
+ else
+ return false;
+ } /* inBounds */
+
+ private Point bottomLeft() {
+ return new Point(anchor.x - WIDTH, anchor.y + HEIGHT);
+ } /* bottomLeft */
+
+ private Point bottomRight() {
+ return new Point(anchor.x + WIDTH, anchor.y + HEIGHT);
+ } /* bottomRight */
+
+ public void write(File f) throws java.io.IOException {
+ char temp[]; // for reading label
+ int i, n;
+
+ f.writeInt(f.SOURCE);
+ f.writeInt(anchor.x);
+ f.writeInt(anchor.y);
+ f.writeInt(period);
+
+ // Write out the associated label
+ n = label.getText().length();
+ f.writeInt(n); // text length
+ temp = new char[n];
+ temp = label.getText().toCharArray();
+
+ for (i = 0; i < n; i++)
+ f.writeChar(temp[i]);
+ f.writeInt(label.getAnchor().x); // label position
+ f.writeInt(label.getAnchor().y);
+ } /* write */
+
+ public void read(File f) throws java.io.IOException {
+ char temp[]; // for reading label
+ int i, n;
+ int label_x, label_y;
+
+ anchor = new Point();
+ anchor.x = f.readInt();
+ anchor.y = f.readInt();
+ period = f.readInt();
+ config.eventEnqueue(this,period); // Enqueue first event
+ p2 = bottomLeft();
+ p3 = bottomRight();
+
+ // get label info
+ n = f.readInt(); // text length
+ label = new EACLabel(canvas,n);
+ temp = new char[n];
+ for (i = 0; i < n; i++)
+ temp[i] = f.readChar();
+ label.setText(java.lang.String.valueOf(temp));
+ label_x = f.readInt();
+ label_y = f.readInt();
+ label.setAnchor(new Point(label_x,label_y));
+ label.setLabelee(this);
+ try {
+ config.addPrimitive(label);
+ } catch (TooManyPrimitivesException tmpe) {
+ // have faith :-)
+ }
+ } /* read */
+} \ No newline at end of file
diff --git a/java/EAC/System Manual.doc b/java/EAC/System Manual.doc
new file mode 100644
index 00000000000..89d76eba720
--- /dev/null
+++ b/java/EAC/System Manual.doc
Binary files differ
diff --git a/java/EAC/TooManyPrimitivesException.java b/java/EAC/TooManyPrimitivesException.java
new file mode 100644
index 00000000000..d9cb8efa733
--- /dev/null
+++ b/java/EAC/TooManyPrimitivesException.java
@@ -0,0 +1,13 @@
+/**
+ * Title: TooManyPrimitivesException
+ * Description: An exception class for when an attempt is made to add a
+ * primitives when the maximum number have already been added
+ */
+package EAC;
+
+public class TooManyPrimitivesException extends Exception {
+
+ public TooManyPrimitivesException(String msg) {
+ super(msg);
+ }
+} \ No newline at end of file
diff --git a/java/EAC/Union.java b/java/EAC/Union.java
new file mode 100644
index 00000000000..107390dc560
--- /dev/null
+++ b/java/EAC/Union.java
@@ -0,0 +1,56 @@
+/**
+ * Title: Union
+ * Description: A binary union operator class for the Event Analysis
+ * Configurator. Acts as a sort of multiplexor, combining two
+ * event streams into one.
+ */
+package EAC;
+import java.awt.*;
+
+public class Union extends Operator {
+
+ public Union(EACPanel p) {
+ super(p);
+ } /* constructor */
+
+ public void draw() throws BoundsException {
+ // the union symbol
+ final char uSymbol = 'U';
+
+ // subtle adjustments to position symbol within circle
+ final int xTweak = 4;
+ final int yTweak = -4;
+
+ char symbol[] = new char[1];
+
+ Graphics g = canvas.getGraphics();
+
+ super.draw();
+ symbol[0] = (char) uSymbol;
+ g.drawChars(symbol,0,1,
+ anchor.x + (int) (DIAMETER / 2) - xTweak,
+ anchor.y + (int) (DIAMETER / 2) - yTweak);
+ } /* draw */
+
+ public void event(Source s) throws ConnectionException {
+ int i;
+
+ //System.out.println("Union event");
+
+ // send an event to all outputs
+ for (i = 0; i < output_count; i++)
+ output[i].event(s);
+ } /* event */
+
+ public void write(File f) throws java.io.IOException {
+ f.writeInt(f.UNION);
+ f.writeInt(anchor.x);
+ f.writeInt(anchor.y);
+ } /* write */
+
+ public void read(File f) throws java.io.IOException {
+ anchor = new Point();
+ anchor.x = f.readInt();
+ anchor.y = f.readInt();
+ } /* read */
+} \ No newline at end of file
diff --git a/java/EAC/User Manual.doc b/java/EAC/User Manual.doc
new file mode 100644
index 00000000000..5f17fc98f37
--- /dev/null
+++ b/java/EAC/User Manual.doc
Binary files differ