00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 package com.realtime.crossfire.jxclient.faces;
00023
00024 import java.util.Collection;
00025 import java.util.HashSet;
00026 import java.util.concurrent.ExecutorService;
00027 import java.util.concurrent.Executors;
00028 import javax.swing.ImageIcon;
00029 import org.jetbrains.annotations.NotNull;
00030
00035 public class FileCacheFaceQueue extends AbstractFaceQueue {
00036
00040 @NotNull
00041 private final Object sync = new Object();
00042
00046 @NotNull
00047 private final ImageCache imageCacheOriginal;
00048
00052 @NotNull
00053 private final ImageCache imageCacheScaled;
00054
00058 @NotNull
00059 private final ImageCache imageCacheMagicMap;
00060
00065 @NotNull
00066 private final ExecutorService executorService = Executors.newFixedThreadPool(1);
00067
00072 @NotNull
00073 private final Collection<Face> pendingLoadFaces = new HashSet<Face>();
00074
00081 private int id = 0;
00082
00092 public FileCacheFaceQueue(@NotNull final ImageCache imageCacheOriginal, @NotNull final ImageCache imageCacheScaled, @NotNull final ImageCache imageCacheMagicMap) {
00093 this.imageCacheOriginal = imageCacheOriginal;
00094 this.imageCacheScaled = imageCacheScaled;
00095 this.imageCacheMagicMap = imageCacheMagicMap;
00096 }
00097
00101 @Override
00102 public void reset() {
00103 synchronized (sync) {
00104 id++;
00105 pendingLoadFaces.clear();
00106 }
00107 }
00108
00112 @Override
00113 public void loadFace(@NotNull final Face face) {
00114 final boolean doAdd;
00115 synchronized (sync) {
00116 doAdd = pendingLoadFaces.add(face);
00117 }
00118 if (doAdd) {
00119 executorService.submit(new LoadTask(face));
00120 }
00121 }
00122
00129 public void saveFace(@NotNull final Face face, @NotNull final FaceImages faceImages) {
00130 executorService.submit(new SaveTask(face, faceImages));
00131 }
00132
00137 private class LoadTask implements Runnable {
00138
00143 private final int taskId = id;
00144
00148 @NotNull
00149 private final Face face;
00150
00155 private LoadTask(@NotNull final Face face) {
00156 this.face = face;
00157 }
00158
00159 @Override
00160 public void run() {
00161 final Thread thread = Thread.currentThread();
00162 final String name = thread.getName();
00163 try {
00164 thread.setName("JXClient:LoadTask:face="+face.getFaceName());
00165 try {
00166 if (taskId != id) {
00167 return;
00168 }
00169
00170 final ImageIcon originalImageIcon = imageCacheOriginal.load(face);
00171 if (originalImageIcon == null) {
00172 fireFaceFailed(face);
00173 return;
00174 }
00175
00176 final ImageIcon scaledImageIcon = imageCacheScaled.load(face);
00177 if (scaledImageIcon == null) {
00178 fireFaceFailed(face);
00179 return;
00180 }
00181
00182 final ImageIcon magicMapImageIcon = imageCacheMagicMap.load(face);
00183 if (magicMapImageIcon == null) {
00184 fireFaceFailed(face);
00185 return;
00186 }
00187
00188 fireFaceLoaded(face, new FaceImages(originalImageIcon, scaledImageIcon, magicMapImageIcon));
00189 } finally {
00190 synchronized (sync) {
00191 pendingLoadFaces.remove(face);
00192 }
00193 }
00194 } finally {
00195 thread.setName(name);
00196 }
00197 }
00198
00199 }
00200
00205 private class SaveTask implements Runnable {
00206
00210 @NotNull
00211 private final Face face;
00212
00216 @NotNull
00217 private final FaceImages faceImages;
00218
00224 private SaveTask(@NotNull final Face face, @NotNull final FaceImages faceImages) {
00225 this.face = face;
00226 this.faceImages = faceImages;
00227 }
00228
00229 @Override
00230 public void run() {
00231 final Thread thread = Thread.currentThread();
00232 final String name = thread.getName();
00233 try {
00234 thread.setName("JXClient:SaveTask:face="+face.getFaceName());
00235 imageCacheOriginal.save(face, faceImages.getOriginalImageIcon());
00236 imageCacheScaled.save(face, faceImages.getScaledImageIcon());
00237 imageCacheMagicMap.save(face, faceImages.getMagicMapImageIcon());
00238 } finally {
00239 thread.setName(name);
00240 }
00241 }
00242 }
00243
00244 }