Merge branch 'features/r2_11_2/JAL-3821_reinstate_patch' into develop
[jalview.git] / unused / javajs / util / JSThread.java
1 package javajs.util;
2
3 import java.awt.Toolkit;
4 import java.awt.event.InvocationEvent;
5
6 //import javajs.J2SRequireImport;
7 import javajs.api.JSFunction;
8
9
10 /**
11  * An abstract class that takes care of simple threading in Java or JavaScript.
12  * 
13  * To use it, subclass it and complete the necessary methods.
14  * 
15  * 
16  * There are three states: INIT, LOOP, and DONE.
17  * 
18  * These states are passed into run1
19  * 
20  * 
21  * @author Bob Hanson
22  * 
23  */
24 //@J2SRequireImport(swingjs.JSToolkit.class)
25 public abstract class JSThread extends Thread {
26
27         public static final int INIT = 0;
28         public static final int LOOP = 1;
29         public static final int DONE = 2;
30         
31         public static int threadCount = 0;
32
33         protected boolean isJS = /** @j2sNative true || */false;
34         
35         public JSThread() {
36                 this(null, "JSThread-" + (++threadCount));
37         }
38         
39         public JSThread(String name) {
40                 this(null, name);
41         }
42         
43         public JSThread(ThreadGroup group, String name) {
44                 super(group, name);
45                 }
46
47         @Override
48         public void run() {
49                 run1(INIT);
50         }
51
52         @Override
53         public synchronized void start() {
54
55                 
56                 /**
57                  * @j2sNative
58                  * 
59                  *                        Clazz.load("swingjs.JSToolkit").dispatch$O$I$I(this, 1, 0);
60                  * 
61                  */
62                 {
63                         super.start();
64                 }
65
66         }
67
68         /**
69          * thread initialization
70          * 
71          * @return false to exit thread before any looping
72          */
73         protected abstract boolean myInit();
74         
75         /**
76          * check for continuing to loop
77          * 
78          * @return true if we are to continue looping
79          */
80         protected abstract boolean isLooping();
81         
82         /**
83          * 
84          * @return false to handle sleepAndReturn yourself
85          */
86         protected abstract boolean myLoop();
87         /**
88          * what to do when the DONE state is reached
89          * 
90          */
91         protected abstract void whenDone();
92         
93         /**
94          * 
95          * @return the sleep time in milliseconds
96          */
97         protected abstract int getDelayMillis();
98         
99         /**
100          * handle an exception -- state will be set to DONE no matter what you do here
101          * 
102          * @param e
103          */
104         protected abstract void onException(Exception e);
105         
106         /**
107          * anything you want done in  try{}catch(}finally().
108          * Note that this method is not fired if we are in JavaScript
109          * mode and the normal return from sleepAndReturn() is taken. 
110          *  
111          */
112         protected abstract void doFinally();
113         
114         /**
115          * a generic method that loops until done, either in Java or JavaScript.
116          * 
117          * In JavaScript it will reenter and continue at the appropriate spot.
118          * 
119          * This method may be overridden if desired.
120          * 
121          * @see org.uwi.SimThread
122          * 
123          * @param state
124          */
125         protected void run1(int state) {
126                 boolean executeFinally = true;
127                 // called by thisThread.run();
128                 try {
129                         while (!interrupted()) {
130                                 switch (state) {
131                                 case INIT:
132                                         if (!myInit())
133                                                 return;
134                                         // initial code here
135                                         state = LOOP;
136                                         continue;
137                                 case LOOP:
138                                         // to stop looping, return false from isLooping()
139                                         if (!isLooping()) {
140                                                 state = DONE;
141                                                 continue;
142                                         }
143                                         // To handle sleepAndReturn yourself, or to skip the
144                                         // sleep when desired, return false from myLoop();
145                                         // Note that doFinally must not be executed in this case.
146                                         // This is because JavaScript will do a return here
147                                         // for every loop, and Java will not.
148                                         if (myLoop() && sleepAndReturn(getDelayMillis(), state)) {
149                                                 executeFinally = false;
150                                                 return;                                         
151                                         }
152                                         continue;
153                                 case DONE:
154                                         whenDone();
155                                         // whatever
156                                         return;
157                                 }
158                         }
159                 } catch (Exception e) {
160                         onException(e);
161                         state = DONE;
162                 } finally {
163                         if (executeFinally)
164                                 doFinally();
165                 }
166                 // normal exit
167         }
168
169         /**
170          * 
171          * @param r2
172          * @param state
173          * @return true if we should interrupt (i.e. JavaScript)
174          * @throws InterruptedException
175          */
176         protected boolean sleepAndReturn(final int delay, final int state)
177                         throws InterruptedException {
178                 if (!isJS) {
179                         sleep(delay);
180                         return false;
181                 }
182
183                 // in JavaScript, we need to do this through the system event queue,
184                 // which in JSToolkit takes care of all the "thread" handling.
185
186                 final JSThread me = this;
187                 Runnable r = new Runnable() {
188                         @Override
189                         public void run() {
190                                 me.run1(state);
191                         }
192                 };
193                 /**
194                  * @j2sNative
195                  * 
196                  *            setTimeout(
197                  *              function() {
198                  *              java.awt.Toolkit.getDefaultToolkit$().getSystemEventQueue$().postEvent$java_awt_AWTEvent(
199                  *              Clazz.new_(java.awt.event.InvocationEvent.c$$O$Runnable,[me, r]))}, 
200                  *              delay);
201                  * 
202                  */
203                 {
204                         Toolkit.getDefaultToolkit().getSystemEventQueue()
205                                         .postEvent(new InvocationEvent(me, r));
206                 }
207                 return true;
208         }
209         
210 }