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}