Skip to content

Commit

Permalink
Moves out IncrementalMountExtensionInput, and AttachDetachBinder
Browse files Browse the repository at this point in the history
Summary: Moves out IncrementalMountExtensionInput, and AttachDetachBinder. Also fixes nits.

Reviewed By: mihaelao

Differential Revision: D23730237

fbshipit-source-id: 68fa730770b1bb78dcedbf5a0cef1a211a557951
  • Loading branch information
adityasharat authored and facebook-github-bot committed Sep 18, 2020
1 parent 34dc4ae commit b22f029
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 111 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.facebook.litho;

import android.content.Context;
import androidx.annotation.Nullable;
import com.facebook.rendercore.RenderUnit;

public class IncrementalMountBinder implements RenderUnit.Binder<LithoRenderUnit, Object> {

private boolean isUpdating = false;

@Override
public boolean shouldUpdate(
final LithoRenderUnit currentValue,
final LithoRenderUnit newValue,
final @Nullable Object currentLayoutData,
final @Nullable Object nextLayoutData) {
isUpdating = true;
return true;
}

@Override
public void bind(
final Context context,
final Object content,
final LithoRenderUnit lithoRenderUnit,
final @Nullable Object layoutData) {
if (!isUpdating) {
return;
}

isUpdating = false;

final LayoutOutput output = lithoRenderUnit.output;
final Component component = output.getComponent();

IncrementalMountExtension.onItemUpdated(content, component);
}

@Override
public void unbind(
final Context context,
final Object o,
final LithoRenderUnit lithoRenderUnit,
final @Nullable Object layoutData) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import static com.facebook.litho.LayoutOutput.getLayoutOutput;
import static com.facebook.litho.ThreadUtils.assertMainThread;

import android.content.Context;
import android.graphics.Rect;
import android.util.LongSparseArray;
import android.view.View;
Expand All @@ -30,79 +29,26 @@
import com.facebook.litho.stats.LithoStats;
import com.facebook.rendercore.Host;
import com.facebook.rendercore.MountDelegate;
import com.facebook.rendercore.MountDelegate.MountDelegateInput;
import com.facebook.rendercore.RenderTreeNode;
import com.facebook.rendercore.RenderUnit;
import com.facebook.rendercore.extensions.MountExtension;
import com.facebook.rendercore.incrementalmount.IncrementalMountExtensionInput;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/** Extension for performing incremental mount. */
public class IncrementalMountExtension
extends MountExtension<IncrementalMountExtension.IncrementalMountExtensionInput> {

private static final Rect sTempRect = new Rect();
public class IncrementalMountExtension extends MountExtension<IncrementalMountExtensionInput> {

private final Host mLithoView;
private int mPreviousTopsIndex;
private int mPreviousBottomsIndex;
private final Rect mPreviousLocalVisibleRect = new Rect();
private final Set<Long> mComponentIdsMountedInThisFrame = new HashSet<>();
private IncrementalMountExtensionInput mInput;
private final AttachDetachBinder mAttachDetachBinder = new AttachDetachBinder();
private final IncrementalMountBinder mAttachDetachBinder = new IncrementalMountBinder();
private final LongSparseArray<RenderTreeNode> mPendingImmediateRemoval = new LongSparseArray<>();

public RenderUnit.Binder getAttachDetachBinder() {
return mAttachDetachBinder;
}

public interface IncrementalMountExtensionInput extends MountDelegateInput {
int getMountableOutputCount();

List<RenderTreeNode> getMountableOutputTops();

List<RenderTreeNode> getMountableOutputBottoms();

int getLayoutOutputPositionForId(long id);
}

final class AttachDetachBinder implements RenderUnit.Binder<LithoRenderUnit, Object> {

private boolean isUpdating = false;

@Override
public boolean shouldUpdate(
LithoRenderUnit currentValue,
LithoRenderUnit newValue,
@Nullable Object currentLayoutData,
@Nullable Object nextLayoutData) {
isUpdating = true;
return true;
}

@Override
public void bind(
Context context,
Object content,
LithoRenderUnit lithoRenderUnit,
@Nullable Object layoutData) {
if (!isUpdating) {
return;
}

isUpdating = false;

final LayoutOutput output = lithoRenderUnit.output;
final Component component = output.getComponent();

onItemUpdated(content, component);
}

@Override
public void unbind(
Context context, Object o, LithoRenderUnit lithoRenderUnit, @Nullable Object layoutData) {}
}
private IncrementalMountExtensionInput mInput;
private int mPreviousTopsIndex;
private int mPreviousBottomsIndex;

public IncrementalMountExtension(Host lithoView) {
mLithoView = lithoView;
Expand Down Expand Up @@ -161,14 +107,36 @@ public void onVisibleBoundsChanged(Rect localVisibleRect) {
LithoStats.incrementComponentMountCount();
}

private void setVisibleRect(@Nullable Rect localVisibleRect) {
if (localVisibleRect != null) {
mPreviousLocalVisibleRect.set(localVisibleRect);
@Override
public void onUnbind() {}

@Override
protected void acquireMountReference(
final RenderTreeNode renderTreeNode,
final int position,
final MountDelegate.MountDelegateInput input,
final boolean isMounting) {
// Make sure the host is mounted before the child.
final RenderTreeNode hostTreeNode = renderTreeNode.getParent();
if (hostTreeNode != null) {
final long hostId = hostTreeNode.getRenderUnit().getId();
if (!ownsReference(hostId)) {
final int hostIndex = mInput.getLayoutOutputPositionForId(hostId);
acquireMountReference(hostTreeNode, hostIndex, input, isMounting);
}
}

super.acquireMountReference(renderTreeNode, position, input, isMounting);
}

@Override
public void onUnbind() {}
public boolean canPreventMount() {
return true;
}

public RenderUnit.Binder getAttachDetachBinder() {
return mAttachDetachBinder;
}

private void releaseAcquiredReferencesForRemovedItems(IncrementalMountExtensionInput input) {
if (mInput == null) {
Expand Down Expand Up @@ -218,28 +186,9 @@ private void initIncrementalMount(Rect localVisibleRect, boolean isMounting) {
setupPreviousMountableOutputData(localVisibleRect);
}

@Override
protected void acquireMountReference(
RenderTreeNode renderTreeNode,
int position,
MountDelegate.MountDelegateInput input,
boolean isMounting) {
// Make sure the host is mounted before the child.
final RenderTreeNode hostTreeNode = renderTreeNode.getParent();
if (hostTreeNode != null) {
final long hostId = hostTreeNode.getRenderUnit().getId();
if (!ownsReference(hostId)) {
final int hostIndex = mInput.getLayoutOutputPositionForId(hostId);
acquireMountReference(hostTreeNode, hostIndex, input, isMounting);
}
}

super.acquireMountReference(renderTreeNode, position, input, isMounting);
}

private void onItemUpdated(Object content, Component component) {
if (component.hasChildLithoViews()) {
mountItemIncrementally(content, component);
private void setVisibleRect(@Nullable Rect localVisibleRect) {
if (localVisibleRect != null) {
mPreviousLocalVisibleRect.set(localVisibleRect);
}
}

Expand Down Expand Up @@ -365,6 +314,22 @@ private void setupPreviousMountableOutputData(Rect localVisibleRect) {
}
}

@VisibleForTesting
int getPreviousTopsIndex() {
return mPreviousTopsIndex;
}

@VisibleForTesting
int getPreviousBottomsIndex() {
return mPreviousBottomsIndex;
}

static void onItemUpdated(Object content, Component component) {
if (component.hasChildLithoViews()) {
mountItemIncrementally(content, component);
}
}

private static boolean isMountedHostWithChildContent(@Nullable Object content) {
if (!(content instanceof ComponentHost)) {
return false;
Expand Down Expand Up @@ -408,19 +373,4 @@ private static void mountViewIncrementally(View view, boolean mountingAll) {
}
}
}

@Override
public boolean canPreventMount() {
return true;
}

@VisibleForTesting
int getPreviousTopsIndex() {
return mPreviousTopsIndex;
}

@VisibleForTesting
int getPreviousBottomsIndex() {
return mPreviousBottomsIndex;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@
import com.facebook.infer.annotation.ThreadSafe;
import com.facebook.litho.ComponentTree.LayoutStateFuture;
import com.facebook.litho.EndToEndTestingExtension.EndToEndTestingExtensionInput;
import com.facebook.litho.IncrementalMountExtension.IncrementalMountExtensionInput;
import com.facebook.litho.annotations.ImportantForAccessibility;
import com.facebook.litho.config.ComponentsConfiguration;
import com.facebook.litho.drawable.BorderColorDrawable;
import com.facebook.litho.stats.LithoStats;
import com.facebook.rendercore.RenderTree;
import com.facebook.rendercore.RenderTreeNode;
import com.facebook.rendercore.incrementalmount.IncrementalMountExtensionInput;
import com.facebook.rendercore.visibility.VisibilityModuleInput;
import com.facebook.rendercore.visibility.VisibilityOutput;
import com.facebook.rendercore.visibility.VisibilityOutputsExtensionInput;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.facebook.rendercore.MountDelegate;
import com.facebook.rendercore.RenderTreeNode;
import com.facebook.rendercore.RenderUnit;
import com.facebook.rendercore.incrementalmount.IncrementalMountExtensionInput;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
Expand All @@ -43,15 +44,13 @@ public void testDirtyMountWithEmptyRect() {

extension.registerToDelegate(mountDelegate);

final IncrementalMountExtension.IncrementalMountExtensionInput incrementalMountExtensionInput =
new TestInput(10);
final IncrementalMountExtensionInput incrementalMountExtensionInput = new TestInput(10);

extension.beforeMount(incrementalMountExtensionInput, new Rect(0, 0, 10, 50));
assertThat(extension.getPreviousBottomsIndex()).isEqualTo(0);
assertThat(extension.getPreviousTopsIndex()).isEqualTo(5);

final IncrementalMountExtension.IncrementalMountExtensionInput incrementalMountExtensionInput2 =
new TestInput(3);
final IncrementalMountExtensionInput incrementalMountExtensionInput2 = new TestInput(3);
extension.beforeMount(incrementalMountExtensionInput2, new Rect(0, 0, 0, 0));

// extension.onViewOffset();
Expand All @@ -71,15 +70,13 @@ public void testDirtyMountWithEmptyRect_leftRightMatch() {

extension.registerToDelegate(mountDelegate);

final IncrementalMountExtension.IncrementalMountExtensionInput incrementalMountExtensionInput =
new TestInput(10);
final IncrementalMountExtensionInput incrementalMountExtensionInput = new TestInput(10);

extension.beforeMount(incrementalMountExtensionInput, new Rect(0, 0, 10, 50));
assertThat(extension.getPreviousBottomsIndex()).isEqualTo(0);
assertThat(extension.getPreviousTopsIndex()).isEqualTo(5);

final IncrementalMountExtension.IncrementalMountExtensionInput incrementalMountExtensionInput2 =
new TestInput(3);
final IncrementalMountExtensionInput incrementalMountExtensionInput2 = new TestInput(3);
extension.beforeMount(incrementalMountExtensionInput2, new Rect(0, 0, 10, 0));

extension.onVisibleBoundsChanged(new Rect(0, 0, 10, 50));
Expand All @@ -88,7 +85,7 @@ public void testDirtyMountWithEmptyRect_leftRightMatch() {
assertThat(extension.getPreviousTopsIndex()).isEqualTo(3);
}

final class TestInput implements IncrementalMountExtension.IncrementalMountExtensionInput {
final class TestInput implements IncrementalMountExtensionInput {
final List<RenderTreeNode> mountableOutputs = new ArrayList<>();
final List<RenderTreeNode> tops = new ArrayList<>();
final List<RenderTreeNode> bottoms = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.facebook.rendercore.incrementalmount;

import com.facebook.rendercore.MountDelegate;
import com.facebook.rendercore.RenderTreeNode;
import java.util.List;

public interface IncrementalMountExtensionInput extends MountDelegate.MountDelegateInput {

int getMountableOutputCount();

List<RenderTreeNode> getMountableOutputTops();

List<RenderTreeNode> getMountableOutputBottoms();

int getLayoutOutputPositionForId(long id);
}

0 comments on commit b22f029

Please sign in to comment.