1    /*
2    Copyright 2002 by Ralph Hartley
3    This software is licenced under the terms of the
4    Gnu Public Licence
5    */
6    import java.io.*;
7    import java.util.*;
8    import java.awt.*;
9    import java.awt.geom.*;
10   import java.awt.image.*;
11   import javax.swing.*;
12   import java.lang.ref.*;
13   
14   public class ImageThread extends Thread {
15   
16     static LinkedList newjobs = new LinkedList();
17     static HashMap jobset = new HashMap();
18     static ImageThread thread = null;
19   
20     ImageJob currentjob = null;
21   
22     public static HashSet users = new HashSet();
23     public static int paintcnt = 0;
24     public static int paintinterval = 0;
25   
26     public boolean kill = false;
27   
28     ImageThread() {}
29   
30   //  public static void startLoad(Segment seg, int index, double size, Component user) {
31   //    startLoad(new ImageJob(seg,size,user));
32   //  }
33   
34   //  public static boolean isPending(ImageJob job) {
35   //    synchronized(newjobs) {
36   //      return(newjobs.contains(job));
37   //    }
38   //  }
39   
40     public static void showState() {
41       if (thread!=null)
42         System.out.println("current = "+thread.currentjob);
43       System.out.println("set = "+jobset);
44   //    System.out.println("queue = "+newjobs);
45     }
46   
47     public static void stopLoading() {
48       synchronized(newjobs) {
49         newjobs = new LinkedList();
50         jobset = new HashMap();
51         synchronized(users) {
52           users = new HashSet();
53         }
54         if (thread!=null) {
55           ImageThread temp = thread;
56           thread = null;
57           temp.kill = true;
58           temp.interrupt();
59         }
60       }
61     }
62   
63     public static ImageJob startLoad(ImageJob job,Component user) {
64       if (user!=null) job.addUser(user);
65       synchronized(newjobs) {
66         if (job.isReady()) {
67           if (user!=null) addUser(user);
68           return(job);
69         }
70   
71   //      showState();
72   //      if (job.pending) return;
73         if (jobset.containsKey(job)) return((ImageJob)jobset.get(job));
74   
75   //      System.out.println("new job = "+job+" isready = "+job.isReady());
76   
77         if (job.getTrans()==null) return(job);
78   //      job.pending = true;
79   //      System.out.println("add job ="+job);
80         newjobs.addLast(job);
81         jobset.put(job,job);
82   //      System.out.println("Q = "+newjobs.size());
83   
84   //      job = null;
85         if (thread==null) {
86           thread = new ImageThread();
87           thread.setPriority(thread.getPriority()-1);
88           thread.start();
89         }
90         if (thread.currentjob==null) newjobs.notify();
91         return(job);
92       }
93     }
94   
95     public static void paintUsers() {
96       synchronized (users) {
97         for (Iterator it = users.iterator();it.hasNext();) {
98           Object item = ((WeakReference)it.next()).get();
99           Component user = null;
100          if (item instanceof Component)
101            user = (Component)item;
102          if (user!=null) user.repaint();
103        }
104        users.clear();
105        paintcnt = 0;
106      }
107    }
108  
109    public static void addUsers(HashSet newusers) {
110      synchronized (users) {
111        users.addAll(newusers);
112        if (paintcnt++ >= paintinterval)
113          paintUsers();
114      }
115    }
116  
117    public static void addUser(Object user) {
118      synchronized (users) {
119        users.add(user);
120        if (paintcnt++ >= paintinterval)
121          paintUsers();
122      }
123    }
124  
125    public static ImageJob loadNow(ImageJob job) {
126      synchronized(newjobs) {
127        if (thread!=null && job.equals(thread.currentjob))
128          synchronized(thread.currentjob) {
129            if (thread.currentjob.lock(true)) return(thread.currentjob);
130            try {
131              thread.currentjob.wait();
132              return(thread.currentjob);
133            } catch (InterruptedException ex) {}
134          }
135        else {
136          if (jobset.containsKey(job)) {
137            newjobs.remove(job);
138            jobset.remove(job);
139  //          job.pending = false;
140          }
141          
142          job.load();
143        }
144        if (job.lock(true)) return(job);
145        else return(null);
146      }
147    }
148  
149    public void run() {
150  //    System.out.println("Imagethread start");
151  
152      while (kill==false) {
153  
154        try {
155          // Get the next fragment to build. Wait if none.
156          synchronized(newjobs) {
157            if (currentjob!=null) {
158              jobset.remove(currentjob);
159  //            currentjob.pending = false;
160              currentjob = null;
161            }
162            
163            while (newjobs.size()==0) {
164  //          System.out.println("Waiting for jobs");
165              paintUsers();
166              try {
167                newjobs.wait();
168              } catch (InterruptedException ex) {
169                if (kill) return;
170              }
171            }
172            currentjob = (ImageJob)newjobs.getFirst();
173            newjobs.remove(0);
174  //        System.out.println("doing job "+currentjob+" Q after = "+newjobs.size());
175          }
176          
177          yield();
178          
179          synchronized(currentjob) {
180            currentjob.load();
181            currentjob.notify();
182          }
183        } catch (RuntimeException ex) {
184          ErrorLog.exception(ex,"Error int Image thread");
185        }
186        
187  //      System.out.println("all jobs done");
188  //      yeald();
189      }
190    }
191  }
192