1b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Juddpackage com.bumptech.glide.load.engine;
2e52ac307639fca7a22cd5bc3e05ea423b2e60264Sam Judd
359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Juddimport android.os.Looper;
4e743a1f03f24e33270f38de883b508d4312a7f69Sam Juddimport com.bumptech.glide.load.Key;
5e52ac307639fca7a22cd5bc3e05ea423b2e60264Sam Judd
659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd/**
759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd * A generic resource that handles reference counting so resources can safely be reused.
859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd * <p>
959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd *     Public methods are non final only to allow for mocking, subclasses must only override abstract methods.
1059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd * </p>
1159dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd *
12785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd * @param <Z> The type of resource wrapped by this class.
1359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd */
14785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Juddpublic abstract class Resource<Z> {
1559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    private volatile int acquired;
1659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    private volatile boolean isRecycled;
17e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd    private ResourceListener listener;
18e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd    private Key key;
19e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd    private boolean isCacheable;
20e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd
21b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Judd    interface ResourceListener {
22e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd        public void onResourceReleased(Key key, Resource resource);
23e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd    }
240e605e6c38a673ba792606ce559db054a776f5cdSam Judd
25785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd    public abstract Z get();
26faacbfc1109f255836b4091f6459976295bba7baSam Judd
2759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    public abstract int getSize();
2859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd
2959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    protected abstract void recycleInternal();
3059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd
31b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Judd    void setResourceListener(Key key, ResourceListener listener) {
32e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd        this.key = key;
33e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd        this.listener = listener;
34e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd    }
35e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd
36b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Judd    void setCacheable(boolean isCacheable) {
37e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd        this.isCacheable = isCacheable;
38e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd    }
39e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd
40b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Judd    boolean isCacheable() {
41e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd        return isCacheable;
42e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd    }
43e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd
4459dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    public void recycle() {
4559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        if (acquired > 0) {
4659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd            throw new IllegalStateException("Cannot recycle a resource while it is still acquired");
4759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        }
4859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        if (isRecycled) {
4959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd            throw new IllegalStateException("Cannot recycle a resource that has already been recycled");
5059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        }
5159dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        isRecycled = true;
5259dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        recycleInternal();
5359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    }
5459dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd
5559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    public void acquire(int times) {
5659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        if (isRecycled) {
5759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd            throw new IllegalStateException("Cannot acquire a recycled resource");
5859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        }
5959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        if (times <= 0) {
6059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd            throw new IllegalArgumentException("Must acquire a number of times >= 0");
6159dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        }
62e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd        if (!Looper.getMainLooper().equals(Looper.myLooper())) {
6359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd            throw new IllegalThreadStateException("Must call acquire on the main thread");
6459dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        }
6559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        acquired += times;
6659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    }
6759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd
6859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    public void release() {
6959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        if (acquired <= 0) {
7059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd            throw new IllegalStateException("Cannot release a recycled or not yet acquired resource");
7159dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        }
72e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd        if (!Looper.getMainLooper().equals(Looper.myLooper())) {
7359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd            throw new IllegalThreadStateException("Must call release on the main thread");
7459dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        }
7559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        if (--acquired == 0) {
76e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd            listener.onResourceReleased(key, this);
7759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd        }
7859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd    }
79e52ac307639fca7a22cd5bc3e05ea423b2e60264Sam Judd}
80