Skip to content

Commit

Permalink
Created GreedyContents to clean up merge path handling (airbnb#362)
Browse files Browse the repository at this point in the history
  • Loading branch information
gpeal authored Jun 30, 2017
1 parent 811993f commit 9e8e9bb
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 24 deletions.
26 changes: 6 additions & 20 deletions lottie/src/main/java/com/airbnb/lottie/ContentGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import android.support.annotation.Nullable;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

class ContentGroup implements DrawingContent, PathContent,
Expand Down Expand Up @@ -38,32 +37,19 @@ class ContentGroup implements DrawingContent, PathContent,
transformAnimation.addListener(this);
}

List<GreedyContent> greedyContents = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {
Content content = items.get(i).toContent(lottieDrawable, layer);
if (content != null) {
contents.add(content);
if (content instanceof GreedyContent) {
greedyContents.add((GreedyContent) content);
}
}
}

List<Content> contentsToRemove = new ArrayList<>();
MergePathsContent currentMergePathsContent = null;
for (int i = contents.size() - 1; i >= 0; i--) {
Content content = contents.get(i);
if (content instanceof MergePathsContent) {
currentMergePathsContent = (MergePathsContent) content;
}
if (currentMergePathsContent != null && content != currentMergePathsContent) {
currentMergePathsContent.addContentIfNeeded(content);
contentsToRemove.add(content);
}
}

Iterator<Content> it = contents.iterator();
while (it.hasNext()) {
Content content = it.next();
if (contentsToRemove.contains(content)) {
it.remove();
}
for (int i = greedyContents.size() - 1; i >= 0; i--) {
greedyContents.get(i).absorbContent(contents.listIterator(contents.size()));
}
}

Expand Down
19 changes: 19 additions & 0 deletions lottie/src/main/java/com/airbnb/lottie/GreedyContent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.airbnb.lottie;

import java.util.ListIterator;

/**
* Content that may want to absorb and take ownership of the content around it.
* For example, merge paths will absorb the shapes above it and repeaters will absorb the content
* above it.
*/
interface GreedyContent {
/**
* An iterator of contents that can be used to take ownership of contents. If ownership is taken,
* the content should be removed from the iterator.
*
* The contents should be iterated by calling hasPrevious() and previous() so that the list of
* contents is traversed from bottom to top which is the correct order for handling AE logic.
*/
void absorbContent(ListIterator<Content> contents);
}
16 changes: 12 additions & 4 deletions lottie/src/main/java/com/airbnb/lottie/MergePathsContent.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

@TargetApi(Build.VERSION_CODES.KITKAT)
class MergePathsContent implements PathContent {
class MergePathsContent implements PathContent, GreedyContent {
private final Path firstPath = new Path();
private final Path remainderPath = new Path();
private final Path path = new Path();
Expand All @@ -25,9 +26,16 @@ class MergePathsContent implements PathContent {
this.mergePaths = mergePaths;
}

void addContentIfNeeded(Content content) {
if (content instanceof PathContent) {
pathContents.add((PathContent) content);
@Override public void absorbContent(ListIterator<Content> contents) {
// Fast forward the iterator until after this content.
//noinspection StatementWithEmptyBody
while (contents.hasPrevious() && contents.previous() != this) {}
while (contents.hasPrevious()) {
Content content = contents.previous();
if (content instanceof PathContent) {
pathContents.add((PathContent) content);
contents.remove();
}
}
}

Expand Down

0 comments on commit 9e8e9bb

Please sign in to comment.