Engine.java revision b46fae747f6bf04b849442f851a1c9da51434ec1
1package com.bumptech.glide.load.engine;
2
3import com.bumptech.glide.Priority;
4import com.bumptech.glide.Resource;
5import com.bumptech.glide.load.Key;
6import com.bumptech.glide.load.ResourceDecoder;
7import com.bumptech.glide.load.ResourceEncoder;
8import com.bumptech.glide.load.Transformation;
9import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
10import com.bumptech.glide.load.engine.cache.MemoryCache;
11import com.bumptech.glide.load.data.DataFetcher;
12import com.bumptech.glide.request.ResourceCallback;
13
14import java.io.InputStream;
15import java.util.HashMap;
16import java.util.Map;
17
18public class Engine implements EngineJobListener, MemoryCache.ResourceRemovedListener {
19
20    private final Map<Key, ResourceRunner> runners;
21    private final ResourceRunnerFactory factory;
22    private final KeyFactory keyFactory;
23    private final MemoryCache cache;
24
25    public static class LoadStatus {
26        private final EngineJob engineJob;
27        private final ResourceCallback cb;
28
29        public LoadStatus(ResourceCallback cb, EngineJob engineJob) {
30            this.cb = cb;
31            this.engineJob = engineJob;
32        }
33
34        public void cancel() {
35            engineJob.removeCallback(cb);
36        }
37    }
38
39    public Engine(EngineBuilder builder) {
40        this(builder.factory, builder.memoryCache, new HashMap<Key, ResourceRunner>(), builder.keyFactory);
41    }
42
43    Engine(ResourceRunnerFactory factory, MemoryCache cache, Map<Key, ResourceRunner> runners, KeyFactory keyFactory) {
44        this.factory = factory;
45        this.cache = cache;
46        this.runners = runners;
47        this.keyFactory = keyFactory;
48
49        cache.setResourceRemovedListener(this);
50    }
51
52    /**
53     *
54     * @param id A unique id for the model, dimensions, cache decoder, decoder, and encoder
55     * @param cacheDecoder
56     * @param fetcher
57     * @param decoder
58     * @param encoder
59     * @param transcoder
60     * @param priority
61     * @param <T> The type of data the resource will be decoded from.
62     * @param <Z> The type of the resource that will be decoded.
63     * @param <R> The type of the resource that will be transcoded from the decoded resource.
64     */
65    public <T, Z, R> LoadStatus load(String id, int width, int height, ResourceDecoder<InputStream, Z> cacheDecoder,
66            DataFetcher<T> fetcher, ResourceDecoder<T, Z> decoder,  Transformation<Z> transformation,
67            ResourceEncoder<Z> encoder, ResourceTranscoder<Z, R> transcoder, Priority priority,
68            boolean isMemoryCacheable, ResourceCallback cb) {
69
70        Key key = keyFactory.buildKey(id, width, height, cacheDecoder, decoder, transformation, encoder, transcoder);
71
72        Resource cached = cache.get(key);
73        if (cached != null) {
74            cached.acquire(1);
75            cb.onResourceReady(cached);
76            return null;
77        }
78
79        ResourceRunner current = runners.get(key);
80        if (current != null) {
81            EngineJob job = current.getJob();
82            job.addCallback(cb);
83            return new LoadStatus(cb, job);
84        }
85
86        ResourceRunner<Z, R> runner = factory.build(key, width, height, cacheDecoder, fetcher, decoder, transformation,
87                encoder, transcoder, priority, isMemoryCacheable, this);
88        runner.getJob().addCallback(cb);
89        runners.put(key, runner);
90        runner.queue();
91        return new LoadStatus(cb, runner.getJob());
92    }
93
94    @Override
95    public void onEngineJobComplete(Key key) {
96        runners.remove(key);
97    }
98
99    @Override
100    public void onEngineJobCancelled(Key key) {
101        ResourceRunner runner = runners.remove(key);
102        runner.cancel();
103    }
104
105    @Override
106    public void onResourceRemoved(Resource resource) {
107        resource.release();
108    }
109}
110