Skip to content

Commit

Permalink
Implement a new optional model interface Model. (#2353)
Browse files Browse the repository at this point in the history
This allows models to handle equity for internal states that can be different from the target image result that is handled with equals()/hashCode()
For example to allow restart of image download from a new source but still using the same cache in Glide.
  • Loading branch information
Tolriq authored and sjudd committed Sep 11, 2017
1 parent 648c58e commit b667cab
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 8 deletions.
10 changes: 3 additions & 7 deletions library/src/main/java/com/bumptech/glide/RequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -359,15 +359,11 @@ public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) {
Request request = buildRequest(target);

Request previous = target.getRequest();
// When request was failed or cancelled, be sure to use the updated model as it can contains
// unexposed data that could help the request to succeed on restart.
// See https://github.com/bumptech/glide/issues/2270
if (request.isEquivalentTo(previous)
&& (Preconditions.checkNotNull(previous).isComplete()
|| Preconditions.checkNotNull(previous).isRunning())) {
if (request.isEquivalentTo(previous)) {
request.recycle();
// If the request is completed, beginning again will ensure the result is re-delivered,
// triggering RequestListeners and Targets. If the request is already
// triggering RequestListeners and Targets. If the request is failed, beginning again will
// restart the request, giving it another chance to complete. If the request is already
// running, we can let it continue running without interruption.
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
Expand Down
28 changes: 28 additions & 0 deletions library/src/main/java/com/bumptech/glide/load/model/Model.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.bumptech.glide.load.model;

/**
* An optional interface that models can implement to enhance control over Glide behaviors.
*/
public interface Model {

/**
* Returns {@code true} if this model produces the same image using the same mechanism
* (server, authentication, source etc) as the given model.
* <p>
* Models must also implement {@link #equals(Object other)} and {@link #hashCode()}
* to ensure that caching functions correctly.
* If this object returns {@code true} from this method for a given Model,
* it must also be equal to and have the same hash code as the given model.
* <p>
* However, this model may be equal to and have the same hash code as a given model
* but still return {@code false} from this method.
* This method optionally allows you to differentiate between Models that load the same image
* via multiple different means.
* For example one Model might load the image from server A and another model might load
* the same image from server B.
* The models must be equal to each other with the same hash code because they load
* the same image. However two requests made with the different models are not exactly the
* same because the way the image is loaded will differ.
*/
boolean isEquivalentTo(Object other);
}
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ public boolean isEquivalentTo(Request o) {
SingleRequest that = (SingleRequest) o;
return overrideWidth == that.overrideWidth
&& overrideHeight == that.overrideHeight
&& Util.bothNullOrEqual(model, that.model)
&& Util.bothModelsNullEquivalentOrEquals(model, that.model)
&& transcodeClass.equals(that.transcodeClass)
&& requestOptions.equals(that.requestOptions)
&& priority == that.priority;
Expand Down
12 changes: 12 additions & 0 deletions library/src/main/java/com/bumptech/glide/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Looper;

import com.bumptech.glide.load.model.Model;
import com.bumptech.glide.request.target.Target;
import java.util.ArrayDeque;
import java.util.ArrayList;
Expand Down Expand Up @@ -190,6 +192,16 @@ public static boolean bothNullOrEqual(Object a, Object b) {
return a == null ? b == null : a.equals(b);
}

public static boolean bothModelsNullEquivalentOrEquals(Object a, Object b) {
if (a == null) {
return b == null;
}
if (a instanceof Model) {
return ((Model) a).isEquivalentTo(b);
}
return a.equals(b);
}

public static int hashCode(int value) {
return hashCode(value, HASH_ACCUMULATOR);
}
Expand Down

0 comments on commit b667cab

Please sign in to comment.