Crossfire JXClient, Trunk  R20561
FileCacheFaceQueue.java
Go to the documentation of this file.
1 /*
2  * This file is part of JXClient, the Fullscreen Java Crossfire Client.
3  *
4  * JXClient is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * JXClient is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with JXClient; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * Copyright (C) 2005-2008 Yann Chachkoff.
19  * Copyright (C) 2006-2011 Andreas Kirschbaum.
20  */
21 
22 package com.realtime.crossfire.jxclient.faces;
23 
24 import java.util.Collection;
25 import java.util.HashSet;
26 import java.util.concurrent.ExecutorService;
27 import java.util.concurrent.Executors;
28 import javax.swing.ImageIcon;
29 import org.jetbrains.annotations.NotNull;
30 
35 public class FileCacheFaceQueue extends AbstractFaceQueue {
36 
40  @NotNull
41  private final Object sync = new Object();
42 
46  @NotNull
48 
52  @NotNull
54 
58  @NotNull
60 
65  @NotNull
66  private final ExecutorService executorService = Executors.newFixedThreadPool(1);
67 
72  @NotNull
73  private final Collection<Face> pendingLoadFaces = new HashSet<>();
74 
81  private int id;
82 
92  public FileCacheFaceQueue(@NotNull final ImageCache imageCacheOriginal, @NotNull final ImageCache imageCacheScaled, @NotNull final ImageCache imageCacheMagicMap) {
93  this.imageCacheOriginal = imageCacheOriginal;
94  this.imageCacheScaled = imageCacheScaled;
95  this.imageCacheMagicMap = imageCacheMagicMap;
96  }
97 
101  @Override
102  public void reset() {
103  synchronized (sync) {
104  id++;
105  pendingLoadFaces.clear();
106  }
107  }
108 
112  @Override
113  public void loadFace(@NotNull final Face face) {
114  final boolean doAdd;
115  synchronized (sync) {
116  doAdd = pendingLoadFaces.add(face);
117  }
118  if (doAdd) {
119  executorService.submit(new LoadTask(face));
120  }
121  }
122 
129  public void saveFace(@NotNull final Face face, @NotNull final FaceImages faceImages) {
130  executorService.submit(new SaveTask(face, faceImages));
131  }
132 
137  private class LoadTask implements Runnable {
138 
143  private final int taskId = id;
144 
148  @NotNull
149  private final Face face;
150 
155  private LoadTask(@NotNull final Face face) {
156  this.face = face;
157  }
158 
159  @Override
160  public void run() {
161  final Thread thread = Thread.currentThread();
162  final String name = thread.getName();
163  try {
164  thread.setName("JXClient:LoadTask:face="+face.getFaceName());
165  try {
166  if (taskId != id) {
167  return;
168  }
169 
170  final ImageIcon originalImageIcon = imageCacheOriginal.load(face);
171  if (originalImageIcon == null) {
172  fireFaceFailed(face);
173  return;
174  }
175 
176  final ImageIcon scaledImageIcon = imageCacheScaled.load(face);
177  if (scaledImageIcon == null) {
178  fireFaceFailed(face);
179  return;
180  }
181 
182  final ImageIcon magicMapImageIcon = imageCacheMagicMap.load(face);
183  if (magicMapImageIcon == null) {
184  fireFaceFailed(face);
185  return;
186  }
187 
188  fireFaceLoaded(face, new FaceImages(originalImageIcon, scaledImageIcon, magicMapImageIcon));
189  } finally {
190  synchronized (sync) {
191  pendingLoadFaces.remove(face);
192  }
193  }
194  } finally {
195  thread.setName(name);
196  }
197  }
198 
199  }
200 
205  private class SaveTask implements Runnable {
206 
210  @NotNull
211  private final Face face;
212 
216  @NotNull
217  private final FaceImages faceImages;
218 
224  private SaveTask(@NotNull final Face face, @NotNull final FaceImages faceImages) {
225  this.face = face;
226  this.faceImages = faceImages;
227  }
228 
229  @Override
230  public void run() {
231  final Thread thread = Thread.currentThread();
232  final String name = thread.getName();
233  try {
234  thread.setName("JXClient:SaveTask:face="+face.getFaceName());
235  imageCacheOriginal.save(face, faceImages.getOriginalImageIcon());
236  imageCacheScaled.save(face, faceImages.getScaledImageIcon());
237  imageCacheMagicMap.save(face, faceImages.getMagicMapImageIcon());
238  } finally {
239  thread.setName(name);
240  }
241  }
242  }
243 
244 }
void save(@NotNull Face face, @NotNull ImageIcon imageIcon)
Stores an ImageIcon into the cache.
void reset()
Reset the processing: forget about pending faces.This function is called whenever the server socket b...
ImageIcon getScaledImageIcon()
Returns the ImageIcon scaled for the map view.
Definition: FaceImages.java:77
FileCacheFaceQueue(@NotNull final ImageCache imageCacheOriginal, @NotNull final ImageCache imageCacheScaled, @NotNull final ImageCache imageCacheMagicMap)
Creates a new instance.
void saveFace(@NotNull final Face face, @NotNull final FaceImages faceImages)
Saves a face to the caches.
Interface for ImageIcon caching classes.
Definition: ImageCache.java:32
final int taskId
The expected task FileCacheFaceQueue#id.
Consists of three ImageIcons representing a Face.
Definition: FaceImages.java:31
ImageIcon getMagicMapImageIcon()
Returns the ImageIcon scaled for the magic map view.
Definition: FaceImages.java:86
void fireFaceLoaded(@NotNull final Face face, @NotNull final FaceImages faceImages)
Notify all listener with FaceImages).
Abstract base class for classes implementing FaceQueue.
ImageIcon load(@NotNull Face face)
Retrieves an image from the cache.
final Collection< Face > pendingLoadFaces
The faces for which loadFace(Face) has been called but that are not yet processed.
void fireFaceFailed(@NotNull final Face face)
Notify all listener with FaceQueueListener#faceFailed(Face).
final ImageCache imageCacheScaled
The image cache used for loading scaled images.
String getFaceName()
Returns the face name.
Definition: Face.java:124
final ImageCache imageCacheMagicMap
The image cache used for loading magic map images.
final ImageCache imageCacheOriginal
The image cache used for loading original images.
SaveTask(@NotNull final Face face, @NotNull final FaceImages faceImages)
Creates a new instance.
final Object sync
The object used for synchronization.
LoadTask(@NotNull final Face face)
Creates a new instance.
int id
Counts the number of calls to reset().
ImageIcon getOriginalImageIcon()
Returns the ImageIcon as sent by the Crossfire server.
Definition: FaceImages.java:68
final ExecutorService executorService
The ExecutorService used to execute face loading.
void loadFace(@NotNull final Face face)
Request a face.Must eventually call either FaceQueueListener#faceLoaded(Face, FaceImages) or FaceQueu...
A FaceQueue loading faces from ImageCache instances.