001package agent;
002
003import java.util.Observable;
004
005public final class TimeServerLinked extends Observable implements TimeServer {
006        private static final class Node {
007                final double waketime;
008                final Agent agent;
009                Node next;
010
011                public Node(double waketime, Agent agent, Node next) {
012                        this.waketime = waketime;
013                        this.agent = agent;
014                        this.next = next;
015                }
016        }
017        private double currentTime;
018        private int size;
019        private Node head;
020
021        /*
022         * Invariant: head != null
023         * Invariant: head.agent == null
024         * Invariant: (size == 0) iff (head.next == null)
025         */
026        public TimeServerLinked() {
027                size = 0;
028                head = new Node(0, null, null);
029        }
030
031        public String toString() {
032                StringBuilder sb = new StringBuilder("[");
033                Node node = head.next;
034                String sep = "";
035                while (node != null) {
036                        sb.append(sep).append("(").append(node.waketime).append(",")
037                        .append(node.agent).append(")");
038                        node = node.next;
039                        sep = ";";
040                }
041                sb.append("]");
042                return (sb.toString());
043        }
044
045        public double currentTime() {
046                return currentTime;
047        }
048
049        public void enqueue(double waketime, Agent agent)
050                        throws IllegalArgumentException
051        {
052                if (waketime < currentTime)
053                        throw new IllegalArgumentException();
054                Node prevElement = head;
055                while ((prevElement.next != null) &&
056                                (prevElement.next.waketime <= waketime)) {
057                        prevElement = prevElement.next;
058                }
059                Node newElement = new Node(waketime, agent, prevElement.next);
060                prevElement.next = newElement;
061                size++;
062        }
063
064        Agent dequeue()
065        {
066                if (size < 1)
067                        throw new java.util.NoSuchElementException();
068                Agent rval = head.next.agent;
069                head.next = head.next.next;
070                size--;
071                return rval;
072        }
073
074        int size() {
075                return size;
076        }
077
078        boolean empty() {
079                return size() == 0;
080        }
081
082        public void run(double duration) {
083                double endtime = currentTime + duration;
084                while ((!empty()) && (head.next.waketime <= endtime)) {
085                        if ((currentTime - head.next.waketime) < 1e-09) {
086                                super.setChanged();
087                                super.notifyObservers();
088                        }
089                        currentTime = head.next.waketime;
090                        dequeue().run();
091                }
092                currentTime = endtime;
093        }
094}