Source code: Freenet/support/Ticker.java
1 package Freenet.support;
2 /*
3 This code is part of the Java Adaptive Network Client by Ian Clarke.
4 It is distributed under the GNU General Public Licence (GPL)
5 version 2. See http://www.gnu.org/ for further details of the GPL.
6 */
7
8 /**
9 * This class allows a callback to be called after a specified
10 * amount of time.
11 *
12 * @author <A HREF="mailto:I.Clarke@strs.co.uk">Ian Clarke</A>
13 **/
14
15 public class Ticker extends Thread
16 {
17 public static void main(String[] args)
18 {
19 Ticker t = new Ticker();
20 t.start();
21 for (int x=0; x<10; x++)
22 {
23 t.add((long) x, (long) (x*1000+100), new testCB(x+" seconds"));
24 }
25 }
26
27 // Protected/Private Fields
28 TLL tll = null;
29 long ticker;
30
31 // Constructors
32 public Ticker()
33 {
34 this((long) 100);
35 }
36
37 /**
38 * @param ticker The time to wait (in milliseconds) between
39 * testing whether a callback should be called.
40 **/
41 public Ticker(long ticker)
42 {
43 super();
44 this.ticker = ticker;
45 }
46
47 // Public Methods
48
49 /**
50 * Adds a callback
51 * @param id The ID to use if we want to cancel this callback
52 * @param time The time to wait (in milliseconds) before calling
53 * this callback
54 * @param cb The callback to call
55 **/
56
57 public synchronized void add(long id, long time, Callback cb)
58 {
59 if (!isAlive()) this.start();
60
61 time += System.currentTimeMillis();
62
63 if (tll == null)
64 {
65 tll = new TLL(null, id, cb, time);
66 }
67 else if (tll.time > time)
68 {
69 tll = new TLL(tll, id, cb, time);
70 }
71 else
72 {
73 TLL t = tll;
74 while(true)
75 {
76 if ((t.next == null) || (t.next.time > time))
77 {
78 TLL tmp = t.next;
79 t.next = new TLL(tmp, id, cb, time);
80 return;
81 } else {
82 if (t.id == id)
83 Logger.log("support/Ticker.java","Duplicate timeouts for id:"+Long.toHexString(id),Logger.ERROR);
84 t = t.next;
85 }
86 }
87 }
88 }
89
90 /**
91 * Cancels a callback
92 * @param id The id of the callback to be cancelled
93 * @return Returns the callback if a callback with the specified
94 * id was still pending, else null.
95 **/
96 public synchronized Callback cancel(long id)
97 {
98 if (tll == null) return null;
99 if (tll.id == id)
100 {
101 Callback cb = tll.cb;
102 tll = tll.next;
103 return cb;
104 }
105 else
106 {
107 TLL t = tll;
108 while (t.next != null)
109 {
110 if (t.next.id == id)
111 {
112 Callback cb = t.next.cb;
113 t.next = t.next.next;
114 return cb;
115 }
116 else {
117 t = t.next;
118 }
119 }
120 return null;
121 }
122 }
123
124 public void run()
125 {
126 Logger.log("support/Ticker.java","Thread started",Logger.NORMAL);
127 while(true)
128 {
129 while (tll != null && tll.time < System.currentTimeMillis())
130 {
131 Callback cb = tll.cb;
132 tll = tll.next;
133 cb.callback();
134 }
135 try
136 {
137 sleep(ticker);
138 }
139 catch (InterruptedException e)
140 {
141 }
142 }
143 }
144
145 // Protected/Private Methods
146 }
147
148 class testCB implements Callback
149 {
150 String p;
151 public testCB(String print)
152 {
153 p = print;
154 }
155
156 public void callback()
157 {
158 System.out.println(p);
159 }
160 }
161
162 class TLL
163 {
164 public TLL next;
165 public long id;
166 public Callback cb;
167 public long time;
168 public TLL(TLL next, long id, Callback cb, long time)
169 {
170 this.next = next;
171 this.id = id;
172 this.cb = cb;
173 this.time = time;
174 }
175 }