1/*
2 * Copyright (c) 2009-2010 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33package com.jme3.asset;
34
35import java.lang.ref.WeakReference;
36import java.util.HashMap;
37import java.util.WeakHashMap;
38
39/**
40 * An <code>AssetCache</code> allows storage of loaded resources in order
41 * to improve their access time if they are requested again in a short period
42 * of time. The AssetCache stores weak references to the resources, allowing
43 * Java's garbage collector to request deletion of rarely used resources
44 * when heap memory is low.
45 */
46public class AssetCache {
47
48    public static final class SmartAssetInfo {
49        public WeakReference<AssetKey> smartKey;
50        public Asset asset;
51    }
52
53    private final WeakHashMap<AssetKey, SmartAssetInfo> smartCache
54            = new WeakHashMap<AssetKey, SmartAssetInfo>();
55    private final HashMap<AssetKey, Object> regularCache = new HashMap<AssetKey, Object>();
56
57    /**
58     * Adds a resource to the cache.
59     * <br/><br/>
60     * <font color="red">Thread-safe.</font>
61     * @see #getFromCache(java.lang.String)
62     */
63    public void addToCache(AssetKey key, Object obj){
64        synchronized (regularCache){
65            if (obj instanceof Asset && key.useSmartCache()){
66                // put in smart cache
67                Asset asset = (Asset) obj;
68                asset.setKey(null); // no circular references
69                SmartAssetInfo smartInfo = new SmartAssetInfo();
70                smartInfo.asset = asset;
71                // use the original key as smart key
72                smartInfo.smartKey = new WeakReference<AssetKey>(key);
73                smartCache.put(key, smartInfo);
74            }else{
75                // put in regular cache
76                regularCache.put(key, obj);
77            }
78        }
79    }
80
81    /**
82     * Delete an asset from the cache, returns true if it was deleted successfuly.
83     * <br/><br/>
84     * <font color="red">Thread-safe.</font>
85     */
86    public boolean deleteFromCache(AssetKey key){
87        synchronized (regularCache){
88            if (key.useSmartCache()){
89                return smartCache.remove(key) != null;
90            }else{
91                return regularCache.remove(key) != null;
92            }
93        }
94    }
95
96    /**
97     * Gets an object from the cache given an asset key.
98     * <br/><br/>
99     * <font color="red">Thread-safe.</font>
100     * @param key
101     * @return
102     */
103    public Object getFromCache(AssetKey key){
104        synchronized (regularCache){
105            if (key.useSmartCache()) {
106                return smartCache.get(key).asset;
107            } else {
108                return regularCache.get(key);
109            }
110        }
111    }
112
113    /**
114     * Retrieves smart asset info from the cache.
115     * @param key
116     * @return
117     */
118    public SmartAssetInfo getFromSmartCache(AssetKey key){
119        return smartCache.get(key);
120    }
121
122    /**
123     * Deletes all the assets in the regular cache.
124     */
125    public void deleteAllAssets(){
126        synchronized (regularCache){
127            regularCache.clear();
128            smartCache.clear();
129        }
130    }
131}
132