KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > activity > Activity


1 package prefuse.activity;
2
3 import prefuse.util.collections.CopyOnWriteArrayList;
4
5
6 /**
7  * Represents an activity that can be scheduled and run. This could include
8  * data processing, animation, and time-sensitive operations.
9  *
10  * @author <a HREF="http://jheer.org">jeffrey heer</a>
11  * @see prefuse.activity.ActivityManager
12  * @see prefuse.action.Action
13  */

14 public abstract class Activity {
15
16     public static final long INFINITY = -1L; // specifies infinite duration
17
public static final long DEFAULT_STEP_TIME = 15L;
18     
19     private boolean m_enabled = true;
20     private Pacer m_pacer;
21     
22     private long m_startTime = -1L;
23     private long m_duration = -1L;
24     private long m_stepTime = -1L;
25     private long m_nextTime = -1L;
26     private boolean m_isRunning = false;
27     private boolean m_isScheduled = false;
28     
29     private CopyOnWriteArrayList m_listeners;
30     
31     /**
32      * Creates a new Activity.
33      * @param duration the length of this activity.
34      * A value of {@link #INFINITY} indicates an infinite running time.
35      * @see prefuse.activity.Activity#Activity(long, long, long)
36      */

37     public Activity(long duration) {
38         this(duration, DEFAULT_STEP_TIME);
39     }
40     
41     /**
42      * Creates a new Activity.
43      * @param duration the length of this activity.
44      * A value of {@link #INFINITY} indicates an infinite running time.
45      * @param stepTime the delay time between steps of this activity
46      * @see prefuse.activity.Activity#Activity(long, long, long)
47      */

48     public Activity(long duration, long stepTime) {
49         this(duration, stepTime, System.currentTimeMillis());
50     }
51     
52     /**
53      * Creates a new Activity.
54      * @param duration the length of this activity.
55      * A value of {@link #INFINITY} indicates an infinite running time.
56      * @param stepTime the delay time between steps of this activity
57      * @param startTime the time at which this activity should begin
58      */

59     public Activity(long duration, long stepTime, long startTime) {
60         m_startTime = startTime;
61         m_nextTime = startTime;
62         m_duration = duration;
63         m_stepTime = stepTime;
64     }
65        
66     /**
67      * Schedules this Activity to start immediately.
68      */

69     public void run() {
70         ActivityManager.scheduleNow(this);
71     }
72     
73     /**
74      * Schedules this Activity for the specified startTime, overwriting the
75      * Activity's currently set startTime.
76      * @param startTime the time at which the activity should run
77      */

78     public void runAt(long startTime) {
79         ActivityManager.scheduleAt(this,startTime);
80     }
81     
82     /**
83      * Schedules this Activity to start immediately after another Activity.
84      * This Activity will be scheduled to start immediately after the
85      * first one finishes, overwriting any previously set startTime. If the
86      * first Activity is cancelled, this one will not run.
87      *
88      * This functionality is provided by using an ActivityListener to monitor
89      * the first Activity. The listener is removed upon completion or
90      * cancellation of the first Activity.
91      *
92      * This method does not in any way affect the scheduling of the first
93      * Activity. If the first Activity is never scheduled, this Activity
94      * will correspondingly never be run unless scheduled by a separate
95      * scheduling call.
96      * @param before the Activity that must finish before this one starts
97      */

98     public void runAfter(Activity before) {
99         ActivityManager.scheduleAfter(before, this);
100     }
101     
102     /**
103      * Schedules this Activity to start immediately after another Activity.
104      * This Activity will be scheduled to start immediately after the
105      * first one finishes, overwriting any previously set startTime. If the
106      * first Activity is cancelled, this one will not run.
107      *
108      * This functionality is provided by using an ActivityListener to monitor
109      * the first Activity. The listener will persist across mulitple runs,
110      * meaning the second Activity will always be evoked upon a successful
111      * finish of the first.
112      *
113      * This method does not in any way affect the scheduling of the first
114      * Activity. If the first Activity is never scheduled, this Activity
115      * will correspondingly never be run unless scheduled by a separate
116      * scheduling call.
117      * @param before the Activity that must finish before this one starts
118      */

119     public void alwaysRunAfter(Activity before) {
120         ActivityManager.alwaysScheduleAfter(before, this);
121     }
122     
123     /**
124      * Run this activity one step. Subclasses should override this method to
125      * specify the actions this activity should perform.
126      * @param elapsedTime the time elapsed since the start of the activity.
127      */

128     protected abstract void run(long elapsedTime);
129     
130     /**
131      * Run this activity for a single step. This method is called by the
132      * ActivityManager -- outside code should have no need to call or
133      * override this method. To implement custom activities, override the
134      * run() method instead.
135      * @param currentTime the time at which this step is being run.
136      * @return the time (in milliseconds) when this activity should be
137      * run again. A return value of -1 indicates this activity is finished.
138      */

139     long runActivity(long currentTime) {
140         if (currentTime < m_startTime) {
141             return m_startTime - currentTime;
142         }
143         
144         long elapsedTime = currentTime - m_startTime;
145         
146         if ( m_duration == 0 || currentTime >= getStopTime() )
147         {
148             if ( !setRunning(true) ) {
149                 fireActivityStarted();
150             }
151             if ( m_enabled ) {
152                 run(elapsedTime);
153                 fireActivityStepped();
154             }
155             setRunning(false);
156             
157             fireActivityFinished();
158             return -1;
159         }
160         else if ( currentTime >= m_nextTime )
161         {
162             if ( !setRunning(true) )
163                 fireActivityStarted();
164             if ( m_enabled ) {
165                 run(elapsedTime);
166                 fireActivityStepped();
167             }
168             m_nextTime = currentTime + m_stepTime;
169         }
170         
171         return (m_nextTime-currentTime);
172     }
173     
174     /**
175      * Cancels this activity, if scheduled. This will stop a
176      * running activity, and will remove the activity from
177      * the ActivityManager's schedule.
178      */

179     public void cancel() {
180         boolean fire = false;
181         synchronized ( this ) {
182             if ( isScheduled() ) {
183                 // attempt to remove this activity, if the remove fails,
184
// this activity is not currently scheduled with the manager
185
ActivityManager.removeActivity(this);
186                 fire = true;
187             }
188             setRunning(false);
189         }
190         if ( fire )
191             fireActivityCancelled();
192     }
193     
194     /**
195      * Indicates if this activity is currently scheduled
196      * with the ActivityManager
197      * @return true if scheduled, false otherwise
198      */

199     public synchronized boolean isScheduled() {
200         return m_isScheduled;
201     }
202     
203     /**
204      * Sets whether or not this Activity has been scheduled. This method should
205      * only be called by the ActivityManager.
206      * @param s the scheduling state of this Activity
207      */

208     void setScheduled(boolean s) {
209         boolean fire;
210         synchronized ( this ) {
211             fire = (s && !m_isScheduled);
212             m_isScheduled = s;
213         }
214         if ( fire )
215             fireActivityScheduled();
216     }
217     
218     /**
219      * Sets a flag indicating whether or not this activity is currently running
220      * @param s the new running state of this activity
221      */

222     synchronized boolean setRunning(boolean s) {
223         boolean b = m_isRunning;
224         m_isRunning = s;
225         return b;
226     }
227     
228     /**
229      * Indicates if this activity is currently running.
230      * @return true if running, false otherwise
231      */

232     public synchronized boolean isRunning() {
233         return m_isRunning;
234     }
235     
236     // ------------------------------------------------------------------------
237
// Activity Listeners
238

239     /**
240      * Add an ActivityListener to monitor this activity's events.
241      * @param l the ActivityListener to add
242      */

243     public void addActivityListener(ActivityListener l) {
244         if ( m_listeners == null )
245             m_listeners = new CopyOnWriteArrayList();
246         if ( !m_listeners.contains(l) )
247             m_listeners.add(l);
248     }
249     
250     /**
251      * Remove a registered ActivityListener
252      * @param l the ActivityListener to remove
253      */

254     public void removeActivityListener(ActivityListener l) {
255         if ( m_listeners == null )
256             return;
257         m_listeners.remove(l);
258         if ( m_listeners.size() == 0 )
259             m_listeners = null;
260     }
261
262     protected void fireActivityScheduled() {
263         if ( m_listeners == null ) return;
264         Object JavaDoc[] a = m_listeners.getArray();
265         for ( int i=0; i<a.length; ++i ) {
266             ((ActivityListener)a[i]).activityScheduled(this);
267         }
268     }
269     
270     protected void fireActivityStarted() {
271         if ( m_listeners == null ) return;
272         Object JavaDoc[] a = m_listeners.getArray();
273         for ( int i=0; i<a.length; ++i ) {
274             ((ActivityListener)a[i]).activityStarted(this);
275         }
276     }
277     
278     protected void fireActivityStepped() {
279         if ( m_listeners == null ) return;
280         Object JavaDoc[] a = m_listeners.getArray();
281         for ( int i=0; i<a.length; ++i ) {
282             ((ActivityListener)a[i]).activityStepped(this);
283         }
284     }
285     
286     protected void fireActivityFinished() {
287         if ( m_listeners == null ) return;
288         Object JavaDoc[] a = m_listeners.getArray();
289         for ( int i=0; i<a.length; ++i ) {
290             ((ActivityListener)a[i]).activityFinished(this);
291         }
292     }
293     
294     protected void fireActivityCancelled() {
295         if ( m_listeners == null ) return;
296         Object JavaDoc[] a = m_listeners.getArray();
297         for ( int i=0; i<a.length; ++i ) {
298             ((ActivityListener)a[i]).activityCancelled(this);
299         }
300     }
301     
302     // ------------------------------------------------------------------------
303
// Accessor / Mutator Methods
304

305     /**
306      * Returns a value between 0 and 1 inclusive, indicating the current
307      * position in an animation or other similarly parameterized activity.
308      * The returned value is determined by consulting this Activity's
309      * pacing function.
310      * @param elapsedTime the time in milliseconds since the start of this
311      * Activity.
312      * @return a value between 0 and 1 indicating the current position in
313      * an animation.
314      * @see prefuse.activity.Activity#getPacingFunction()
315      */

316     public double getPace(long elapsedTime) {
317         long duration = getDuration();
318         double frac = (duration == 0L ? 0.0 : ((double)elapsedTime)/duration);
319         frac = Math.min(1, Math.max(0, frac));
320         return m_pacer!=null ? m_pacer.pace(frac) : frac;
321     }
322     
323     /**
324      * Returns the pacing function associated with this Activity. Pacing
325      * functions are used to control the pace of animations.
326      * @return this Activity's pacing function. A value of null indicates a
327      * basic, linear pace is used, moving from 0 to 1 uniformly over time.
328      */

329     public synchronized Pacer getPacingFunction() {
330         return m_pacer;
331     }
332     
333     /**
334      * Sets the pacing function associated with this Activity. Pacing
335      * functions are used to control the pace of animations.
336      * @param pfunc this Activity's new pacing function, or null to
337      * indicate a basic, linear pace moving from 0 to 1 uniformly
338      * over time.
339      */

340     public synchronized void setPacingFunction(Pacer pfunc) {
341         m_pacer = pfunc;
342     }
343     
344     /**
345      * Get the time at which this activity should complete.
346      * @return the stopping time for this activity, or Long.MAX_VALUE
347      * if this activity should run indefinitely.
348      */

349     public long getStopTime() {
350         if (m_duration == -1) {
351             return Long.MAX_VALUE;
352         }
353         return m_startTime + m_duration;
354     }
355     
356     /**
357      * Get the time at which this activity should be run next.
358      * @return the time this activity should run next
359      */

360     public long getNextTime() {
361         return m_nextTime;
362     }
363     
364     /**
365      * Returns the duration of this activity
366      * @return the duration of this activity, in milliseconds
367      */

368     public long getDuration() {
369         return m_duration;
370     }
371
372     /**
373      * Set the duration of this activity
374      * @param duration The new duration, in milliseconds, for this activity.
375      * A value of {@link #INFINITY} indicates that this activity should run
376      * indefinitely.
377      */

378     public void setDuration(long duration) {
379         this.m_duration = duration;
380     }
381
382     /**
383      * Returns this activity's start time
384      * @return the starting time for this activity
385      */

386     public long getStartTime() {
387         return m_startTime;
388     }
389
390     /**
391      * Sets this activity's start time
392      * @param time the new starting time for this activity
393      */

394     public void setStartTime(long time) {
395         m_startTime = time;
396     }
397
398     /**
399      * Returns the delay between runs for this activity
400      * @return the step time between runs of this activity
401      */

402     public long getStepTime() {
403         return m_stepTime;
404     }
405
406     /**
407      * Sets the delay between runs for this activity
408      * @param time the new step time between runs of this activity
409      */

410     public void setStepTime(long time) {
411         m_stepTime = time;
412     }
413     
414     /**
415      * Indicates whether or not this activity is currently enabled.
416      * @return true if enabled, false otherwise
417      */

418     public boolean isEnabled() {
419         return m_enabled;
420     }
421     
422     /**
423      * Sets whether this component is enabled.
424      * @param s true to enable component, false to disable it
425      */

426     public void setEnabled(boolean s) {
427         m_enabled = s;
428     }
429     
430 } // end of class Activity
431
Popular Tags