001package agent;
002
003import java.util.Observable;
004import java.util.PriorityQueue;
005
006public final class TimeServerQueue extends Observable implements TimeServer {
007        private static final class Node implements Comparable<Node> {
008                final double waketime;
009                final Agent agent;
010                public Node(double waketime, Agent agent) {
011                        this.waketime = waketime;
012                        this.agent = agent;
013                }
014                public int compareTo(Node that) {
015                        return (int) (Math.signum(this.waketime - that.waketime));
016                }
017        }
018        private double currentTime;
019        private PriorityQueue<Node> queue;
020
021        public TimeServerQueue() {
022                queue = new PriorityQueue<Node>();
023        }
024
025        public String toString() {
026                StringBuilder sb = new StringBuilder("[");
027                String sep = "";
028                Node[] nodes = queue.toArray(new Node[0]);
029                java.util.Arrays.sort(nodes);
030                for (Node node : nodes) {
031                        sb.append(sep).append("(").append(node.waketime).append(",")
032                        .append(node.agent).append(")");
033                        sep = ";";
034                }
035                sb.append("]");
036                return (sb.toString());
037        }
038
039        public double currentTime() {
040                return currentTime;
041        }
042
043        public void enqueue(double waketime, Agent agent)
044                        throws IllegalArgumentException
045        {
046                if (waketime < currentTime)
047                        throw new IllegalArgumentException();
048                queue.add(new Node(waketime, agent));
049        }
050
051        Agent dequeue()
052        {
053                return queue.remove().agent;
054        }
055
056        int size() {
057                return queue.size();
058        }
059
060        boolean empty() {
061                return queue.isEmpty();
062        }
063
064        public void run(double duration) {
065                double endtime = currentTime + duration;
066                while ((!empty()) && (queue.peek().waketime <= endtime)) {
067                        if ((currentTime - queue.peek().waketime) < 1e-09) {
068                                super.setChanged();
069                                super.notifyObservers();
070                        }
071                        currentTime = queue.peek().waketime;
072                        dequeue().run();
073                }
074                currentTime = endtime;
075        }
076}