package greenfoot.core;
import greenfoot.GreenfootImage;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
| An image cache, which uses soft references to avoid holding images when heap space becomes exhausted.
|
| @author Davin McCall
|
public class ImageCache
{
private static ImageCache instance = new ImageCache();
| A soft reference to a cached image
|
private class CachedImageRef extends SoftReference<GreenfootImage>
{
String imgName;
public CachedImageRef(String imgName, GreenfootImage image, ReferenceQueue<GreenfootImage> queue)
{
super(image, queue);
this.imgName = imgName;
}
}
private Map<String,CachedImageRef> imageCache = new HashMap<String,CachedImageRef>();
private ReferenceQueue<GreenfootImage> imgCacheRefQueue = new ReferenceQueue<GreenfootImage>();
| Retrieve the image cache instance.
|
public static ImageCache getInstance()
{
return instance;
}
| Requests that an image with associated name be added into the cache. The image may be null,
| in which case the null response will be cached. Thread-safe.
|
| @return whether the image was cached.
|
public boolean addCachedImage(String fileName, GreenfootImage image)
{
synchronized (imageCache) {
if (image != null) {
CachedImageRef cr = new CachedImageRef(fileName, image, imgCacheRefQueue);
imageCache.put(fileName, cr);
}
else {
imageCache.put(fileName, null);
}
}
return true;
}
| Gets the cached image of the requested fileName. Thread-safe.
|
| @param name name of the image file
| @return The cached image (should not be modified), or null if the image
| is not cached.
|
public GreenfootImage getCachedImage(String fileName)
{
synchronized (imageCache) {
flushImgCacheRefQueue();
CachedImageRef sr = imageCache.get(fileName);
if (sr != null) {
return sr.get();
}
return null;
}
}
| Remove the cached version of an image for a particular class. This should be
| called when the image for the class is changed. Thread-safe.
|
public void removeCachedImage(String fileName)
{
synchronized (imageCache) {
CachedImageRef cr = imageCache.remove(fileName);
if (cr != null) {
cr.clear();
}
}
}
| Returns true if the fileName exists in the map and the image is cached as being null;
| returns false if it exists and is not null or if it does not exist in the map
|
public boolean isNullCachedImage(String fileName)
{
synchronized (imageCache) {
return imageCache.containsKey(fileName) && imageCache.get(fileName) == null;
}
}
| Clear the image cache.
|
public void clearImageCache()
{
synchronized (imageCache) {
imageCache.clear();
imgCacheRefQueue = new ReferenceQueue<GreenfootImage>();
}
}
| Flush the image cache reference queue.
|
| Because the images are cached via soft references, the references may be cleared, but the
| key will still map to the (cleared) reference. Calling this method occasionally removes such
| dead keys.
|
private void flushImgCacheRefQueue()
{
Reference<? extends GreenfootImage> ref = imgCacheRefQueue.poll();
while (ref != null){
if (ref instanceof CachedImageRef) {
CachedImageRef cr = (CachedImageRef) ref;
imageCache.remove(cr.imgName);
}
ref = imgCacheRefQueue.poll();
}
}
}
top,
use,
map,
class ImageCache
. CachedImageRef
. getInstance
. addCachedImage
. getCachedImage
. removeCachedImage
. isNullCachedImage
. clearImageCache
. flushImgCacheRefQueue
139 neLoCode
+ 21 LoComm