KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thoughtriver > open > vectorvisuals > task > TaskManager


1 /*
2  * TaskManager.java
3  *
4  * Created on 2 June 2003, 11:56
5  */

6
7 package com.thoughtriver.open.vectorvisuals.task;
8
9 import java.util.*;
10
11 import com.thoughtriver.open.vectorvisuals.*;
12
13 /**
14  * An instance of <CODE>TaskManager</CODE> is maintained by every <CODE>VVDisplay</CODE>
15  * instance, and is used for the handling of multiple <CODE>AnimationTask</CODE>
16  * objects. New tasks are added to the manager, and will be executed in a
17  * round-robin manner. The manager is also responsible for recording listeners
18  * that have registered to receive <CODE>TaskEvent</CODE>s, and for
19  * distributing those events to the listeners when they occur.
20  *
21  * @author Brandon Franklin
22  * @version $Date: 2006/11/25 09:15:42 $
23  */

24 public class TaskManager implements Runnable JavaDoc {
25
26     /** The <CODE>VVDisplay</CODE> that this manager is linked to */
27     private final VVDisplay vvDisplay;
28
29     /** The tasks that have been added to this manager */
30     private final List<AnimationTask> tasks;
31
32     /** The <CODE>List</CODE> of listeners to be notified of selection changes */
33     private final List<TaskListener> listeners;
34
35     /**
36      * The amount of time in milliseconds that will be allocated for a single
37      * task cycle
38      */

39     private int cycleLength = 10;
40
41     /** The execution state of this manager */
42     private ExecutionState executionState = ExecutionState.stopped;
43
44     /**
45      * Creates a new instance of <CODE>TaskManager</CODE> and links it to the
46      * supplied <CODE>VVDisplay</CODE>.
47      *
48      * @param display the <CODE>VVDisplay</CODE> instance that this manager is
49      * handling tasks for
50      */

51     public TaskManager(final VVDisplay display) {
52         vvDisplay = display;
53         tasks = Collections.synchronizedList(new LinkedList<AnimationTask>());
54         listeners = new LinkedList<TaskListener>();
55     }
56
57     /**
58      * Returns the amount of time in milliseconds that will be allocated for a
59      * single task cycle. The default value is 10 milliseconds.
60      *
61      * @return the amount of time in milliseconds that will be allocated for a
62      * single task cycle
63      */

64     public int getCycleLength() {
65         return cycleLength;
66     }
67
68     /**
69      * Sets the amount of time in milliseconds that will be allocated for a
70      * single task cycle. Any given cycle of task execution (meaning an update
71      * call on every running <CODE>AnimationTask</CODE>) will take no less
72      * than this amount of time, but could take more. The default value is 10
73      * milliseconds.
74      *
75      * @param cycleLength the amount of time in milliseconds that will be
76      * allocated for a single task cycle
77      */

78     public void setCycleLength(final int cycleLength) {
79         this.cycleLength = cycleLength;
80     }
81
82     /**
83      * Adds a new <CODE>AnimationTask</CODE> to the list of currently
84      * executing tasks. The task will be added to the end of the list, and will
85      * immediately begin receiving update calls.
86      *
87      * @param task the new task to be added for execution
88      */

89     public void addTask(final AnimationTask task) {
90
91         task.setManager(this);
92         tasks.add(task);
93
94         // Start the thread when the first task is added
95
if (tasks.size() == 1) {
96             new Thread JavaDoc(this, "TaskManager Thread").start();
97         }
98
99     }
100
101     /**
102      * Adds a <CODE>TaskListener</CODE> to receive notification when <CODE>AnimationTask</CODE>s
103      * change execution state.
104      *
105      * @param listener the new listener to add
106      */

107     public void addTaskListener(final TaskListener listener) {
108         listeners.add(listener);
109     }
110
111     /**
112      * Removes a <CODE>TaskListener</CODE> from receiving notification when
113      * <CODE>AnimationTask</CODE>s change execution state.
114      *
115      * @param listener the listener to remove
116      */

117     public void removeTaskListener(final TaskListener listener) {
118         listeners.remove(listener);
119     }
120
121     /**
122      * Returns a copy of the list of <CODE>TaskListener</CODE>s that have
123      * been registered to listen to changes in execution state of <CODE>AnimationTask</CODE>s.
124      *
125      * @return a copy of the list of <CODE>TaskListener</CODE>s that have
126      * been registered to listen to changes in execution state of <CODE>AnimationTask</CODE>s
127      */

128     public List<TaskListener> getListeners() {
129         return new LinkedList<TaskListener>(listeners);
130     }
131
132     /**
133      * Informs the task handling thread (if any) to exit at its next opportunity
134      * to do so smoothly. This is achieved by clearning the list of tasks.
135      */

136     public void signalExit() {
137         tasks.clear();
138     }
139
140     /**
141      * Returns the current <CODE>ExecutionState</CODE> of this manager.
142      *
143      * @return the current <CODE>ExecutionState</CODE> of this manager
144      */

145     public ExecutionState getExecutionState() {
146         return executionState;
147     }
148
149     /**
150      * Executes all of the currently running <CODE>AnimationTask</CODE>s in a
151      * round-robin scheme. When and if the set of tasks becomes empty, allows
152      * the thread to exit. Additionally, if the "end execution" flag becomes
153      * set, allows the thread to exit. The minimum amount of time any given
154      * cycle of task executions will take is governed by the current value of
155      * the "cycle length" property.
156      */

157     public void run() {
158
159         // Record that execution has begun
160
executionState = ExecutionState.running;
161
162         while (!tasks.isEmpty()) {
163
164             long startTime = System.nanoTime();
165
166             synchronized (tasks) {
167
168                 for (Iterator<AnimationTask> iter = tasks.iterator(); iter.hasNext();) {
169                     AnimationTask task = iter.next();
170                     boolean taskStillRunning = task.update();
171                     if (!taskStillRunning) {
172                         iter.remove();
173
174                         // Notify listeners
175
TaskEvent event = new TaskEvent(task, ExecutionState.stopped);
176                         for (TaskListener listener : listeners) {
177                             listener.taskStateChanged(event);
178                         }
179                     }
180                 }
181             }
182
183             // Update the view for the current cycle
184
vvDisplay.getViewPane().repaint();
185
186             // Sleep for the remaining time to share the system
187
long elapsed = (System.nanoTime() - startTime) / 1000000;
188             long remaining = getCycleLength() - elapsed;
189             if (remaining > 0) {
190                 try {
191                     Thread.sleep(remaining);
192                 }
193                 catch (InterruptedException JavaDoc ie) {
194                     // nothing to do in this case
195
}
196             }
197         }
198
199         // Record that execution has ended
200
executionState = ExecutionState.stopped;
201     }
202
203 }
204
Popular Tags