1 /* Copyright (C) 2005-2011 Fabio Riccardi */
2 
3 package com.lightcrafts.ui.browser.model;
4 
5 import java.util.LinkedList;
6 import java.awt.*;
7 
8 public class ImageTaskQueue implements Runnable {
9 
10     private LinkedList<ImageTask> queue;
11 
12     private Thread thread;
13     private boolean pause;
14     private boolean stop;
15 
16     private LinkedList<ImageTaskQueueListener> listeners;
17 
ImageTaskQueue()18     public ImageTaskQueue() {
19         thread = new Thread(this, "Image Task Queue");
20         thread.setPriority(Thread.MIN_PRIORITY);
21         queue = new LinkedList<ImageTask>();
22         listeners = new LinkedList<ImageTaskQueueListener>();
23     }
24 
addTask(ImageTask task)25     void addTask(ImageTask task) {
26         synchronized(queue) {
27             queue.add(task);
28             queue.notifyAll();
29         }
30     }
31 
removeTask(ImageTask task)32     void removeTask(ImageTask task) {
33         synchronized(queue) {
34             queue.remove(task);
35         }
36     }
37 
removeAllTasks()38     void removeAllTasks() {
39         synchronized(queue) {
40             queue.clear();
41         }
42     }
43 
start()44     public void start() {
45         if (! thread.isAlive()) {
46             pause = false;
47             stop = false;
48             thread.start();
49         }
50     }
51 
stop()52     public void stop() {
53         pause = false;
54         stop = true;
55         synchronized(queue) {
56             queue.notifyAll();
57         }
58         synchronized(thread) {
59             thread.notifyAll();
60         }
61     }
62 
pause()63     public void pause() {
64         synchronized(thread) {
65             pause = true;
66         }
67     }
68 
resume()69     public void resume() {
70         synchronized(thread) {
71             if (pause) {
72                 pause = false;
73                 thread.notifyAll();
74             }
75         }
76     }
77 
raiseTask(ImageTask task)78     public void raiseTask(ImageTask task) {
79         synchronized(queue) {
80             if (queue.contains(task)) {
81                 queue.remove(task);
82                 queue.addFirst(task);
83             }
84         }
85     }
86 
lowerTask(ImageTask task)87     public void lowerTask(ImageTask task) {
88         synchronized(queue) {
89             if (queue.contains(task)) {
90                 queue.remove(task);
91                 queue.addLast(task);
92             }
93         }
94     }
95 
run()96     public void run() {
97         while (! stop) {
98             Runnable task;
99             synchronized(queue) {
100                 while (queue.isEmpty() && (! stop)) {
101                     waitForNotify(queue);
102                     if (stop) {
103                         return;
104                     }
105                 }
106                 task = queue.removeFirst();
107                 logQueueSize();
108             }
109             try {
110                 task.run();
111             }
112             catch (Throwable t) {
113                 logTaskError(t);
114             }
115             synchronized(thread) {
116                 while (pause && (! stop)) {
117                     waitForNotify(thread);
118                 }
119             }
120         }
121     }
122 
addListener(ImageTaskQueueListener listener)123     void addListener(ImageTaskQueueListener listener) {
124         listeners.add(listener);
125     }
126 
removeListener(ImageTaskQueueListener listener)127     void removeListener(ImageTaskQueueListener listener) {
128         listeners.remove(listener);
129     }
130 
waitForNotify(Object monitor)131     private static void waitForNotify(Object monitor) {
132         synchronized(monitor) {
133             boolean interrupted;
134             do {
135                 try {
136                     interrupted = false;
137                     monitor.wait();
138                 }
139                 catch (InterruptedException e) {
140                     interrupted = true;
141                 }
142             } while (interrupted);
143         }
144     }
145 
logQueueSize()146     private void logQueueSize() {
147         final int depth = queue.size();
148         EventQueue.invokeLater(
149             new Runnable() {
150                 public void run() {
151                     for (ImageTaskQueueListener listener : listeners) {
152                         listener.queueDepthChanged(depth);
153                     }
154                 }
155             }
156         );
157     }
158 
logTaskError(Throwable t)159     private void logTaskError(Throwable t) {
160         StringBuffer buffer = new StringBuffer();
161         buffer.append("Abort ImageTask--");
162         buffer.append(t.getClass().getName());
163         if (t.getMessage() != null) {
164             buffer.append(": ");
165             buffer.append(t.getMessage());
166         }
167         System.err.println(buffer);
168         t.printStackTrace();
169     }
170 }
171