001 
002 /*
003  *  JScripter Standard 1.0 - To Script In Java
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package jsx;
021 
022 import js.Js;
023 import js.core.JsFunction;
024 import jsx.client.Global;
025 
026 /**
027  * <p>Represents tasks that may be set to run after a specified amount of time.</p>
028  * <p>A task of this class, as a runnable task, can be run by either its function version 
029  * returned from its {@link Task#getFunction()} method or a call to its {@link Interval#run()} 
030  * method. Besides, it can also get its function run after a specified amount of time like 
031  * what {@link Js#setTimeout(JsFunction, Number)} does, by a simple call to its {@link Timeout#set(Number)} 
032  * method, or cancel the pending execution by a call to its {@link Timeout#clear()} method 
033  * like what {@link Js#clearTimeout(Object)} does.</p>
034  * <p>A subclass of this class must make sure that its function version, method {@link Timeout#run()} 
035  * and pending function are all executing the same code.</p>
036  * 
037  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
038  * @see Js#setTimeout(JsFunction)
039  * @see Js#setTimeout(JsFunction, Number)
040  * @see Js#clearTimeout(Object)
041  * @see Interval
042  */
043 public class Timeout extends Task
044 {
045     private Object id;
046 
047     /**
048      * <p>The default constructor.</p>
049      * <p>A subclass must override {@link #run()} to make the task runnable when its 
050      * constructor invokes this one, because this constructor sets the {@link Task#funct} 
051      * field to a function that invokes the {@link #run()} method.</p>
052      * @since 1.0
053      * @see #run()
054      */
055     protected Timeout() {
056         funct = getFunction();
057     }
058 
059     /**
060      * <p>Constructs from an existing runnable object.</p>
061      * <p>This constructor sets the {@link Task#funct} field of this task to the function 
062      * of the argument task. Note that, the {@link #run()} method has been designed to 
063      * simply invoke the {@link Task#funct} function. Override it with caution in a subclass 
064      * where this constructor is invoked.</p> 
065      * @since 1.0
066      * @see #run()
067      */
068     public Timeout(Runnable r) {
069         funct = makeFunction(r);
070     }
071 
072     /**
073      * <p>Simply runs the function version of this task.</p> 
074      * @since 1.0
075      * @see #Timeout()
076      */
077     @Override
078     public void run() {
079         funct.invoke();
080     }
081 
082     /**
083      * <p>Sets this task to run after the specified amount of time.</p>.
084      * @param delay The amount of time, in milliseconds, before the task should be executed.
085      * @since 1.0
086      * @see #set()
087      * @see #clear()
088      * @see #clear(Timeout)
089      */
090     public final void set(Number delay) {
091         clear();
092         id = Global.setTimeout(getFunction(), delay);
093     }
094 
095     /**
096      * <p>Sets this task to run after a minimum delay system allowed.</p>.
097      * @since 1.0
098      * @see #set(Number)
099      * @see #clear()
100      * @see #clear(Timeout)
101      */
102     public final void set() {
103         clear();
104         id = Global.setTimeout(getFunction());
105     }
106 
107     /**
108      * <p>Cancels the pending execution of this task.</p>
109      * @since 1.0
110      * @see #set(Number)
111      * @see #set()
112      * @see #clear(Timeout)
113      */
114     public final void clear() {
115         if (Js.be(id)) {
116             Global.clearTimeout(id);
117             id = 0;
118         }
119     }
120 
121     /**
122      * <p>Cancels the pending execution of the specified task but does nothing when 
123      * <tt>t<tt> is <tt>null</tt> or undefined.</p>
124      * @param t The pending task to cancel.
125      * @since 1.0
126      * @see #set(Number)
127      * @see #set()
128      * @see #clear()
129      */
130     public static final void clear(Timeout t) {
131         if (Js.be(t)) {
132             t.clear();
133         }
134     }
135 }