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 run periodically when set intervals.</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 in an interval periodic like what {@link Js#setInterval(JsFunction, Number)} 
031  * does with a simple call to its {@link Interval#set(Number)} method, or cancel the periodic 
032  * execution with a call to its {@link Interval#clear()} method like what {@link Js#clearInterval(Object)} 
033  * does.</p>
034  * <p>A subclass of this class must make sure that its function version, method {@link Interval#run()} 
035  * and function being periodically run 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#setInterval(JsFunction)
039  * @see Js#setInterval(JsFunction, Number)
040  * @see Js#clearInterval(Object)
041  * @see Timeout
042  */
043 public class Interval 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 Interval() {
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 Interval(Runnable r) {
069         funct = makeFunction(r);
070     }
071 
072     /**
073      * <p>Checks if the current task is running periodically.</p>
074      * @return <tt>true</tt> if the current task has been set to run periodically; <tt>false</tt> otherwise.
075      * @since 1.0
076      */
077     public final synchronized boolean isRunning() {
078         return Js.be(id);
079     }
080 
081     /**
082      * <p>Simply runs the function version of this task.</p> 
083      * @since 1.0
084      * @see #Interval()
085      */
086     @Override
087     public void run() {
088         funct.invoke();
089     };
090 
091     /**
092      * <p>Sets this interval task to run periodically.</p>.
093      * @param interval The interval, in milliseconds, between running of this task.
094      * @since 1.0
095      * @see #set()
096      * @see #clear()
097      * @see #clear(Interval)
098      */
099     public final synchronized void set(Number interval) {
100         clear();
101         id = Global.setInterval(getFunction(), interval);
102     }
103 
104     /**
105      * <p>Sets this task to run periodically in the minimum interval system allowed.</p>.
106      * @since 1.0
107      * @see #set(Number)
108      * @see #clear()
109      * @see #clear(Interval)
110      */
111     public final synchronized void set() {
112         clear();
113         id = Global.setInterval(getFunction());
114     }
115 
116     /**
117      * <p>Cancels the periodic execution of this task.</p>
118      * @since 1.0
119      * @see #set(Number)
120      * @see #set()
121      * @see #clear(Interval)
122      */
123     public final synchronized void clear() {
124         if (Js.be(id)) {
125             Global.clearInterval(id);
126             id = 0;
127         }
128     }
129 
130     /**
131      * <p>Cancels the periodic execution of the specified task but does nothing when 
132      * <tt>t<tt> is <tt>null</tt> or undefined.</p>
133      * @param t The interval task to stop.
134      * @since 1.0
135      * @see #set(Number)
136      * @see #set()
137      * @see #clear()
138      */
139     public static final void clear(Interval t) {
140         if (Js.be(t)) {
141             t.clear();
142         }
143     }
144 }