Skip to content

Commit

Permalink
BREAKING: Changed LithoHandler interface introducing DefaultLithoHandler
Browse files Browse the repository at this point in the history
Summary: As per title, the interface of LithoHandler is being simplified and generalized DefaultLithoHandler to extends Android Handler and implements LithoHandler.

Reviewed By: pasqualeanatriello

Differential Revision: D14479897

fbshipit-source-id: 0088341348ae5f087a474dab99fd52ec3f1efca2
  • Loading branch information
marco-cova authored and facebook-github-bot committed Apr 8, 2019
1 parent 69cba50 commit 0d0bb0b
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 51 deletions.
59 changes: 22 additions & 37 deletions litho-core/src/main/java/com/facebook/litho/ComponentTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import com.facebook.infer.annotation.ReturnsOwnership;
import com.facebook.infer.annotation.ThreadConfined;
import com.facebook.infer.annotation.ThreadSafe;
import com.facebook.litho.LithoHandler.DefaultLithoHandler;
import com.facebook.litho.animation.AnimatedProperties;
import com.facebook.litho.animation.AnimatedProperty;
import com.facebook.litho.annotations.MountSpec;
Expand Down Expand Up @@ -121,7 +122,7 @@ public interface NewLayoutStateReadyListener {
@GuardedBy("ComponentTree.class")
private static volatile Looper sDefaultPreallocateMountContentThreadLooper;

private static final ThreadLocal<WeakReference<Handler>> sSyncStateUpdatesHandler =
private static final ThreadLocal<WeakReference<LithoHandler>> sSyncStateUpdatesHandler =
new ThreadLocal<>();

@Nullable private final IncrementalMountHelper mIncrementalMountHelper;
Expand Down Expand Up @@ -286,8 +287,7 @@ protected ComponentTree(Builder builder) {

if (mPreAllocateMountContentHandler == null && builder.canPreallocateOnDefaultHandler) {
mPreAllocateMountContentHandler =
new DefaultPreallocateMountContentHandler(
getDefaultPreallocateMountContentThreadLooper());
new DefaultLithoHandler(getDefaultPreallocateMountContentThreadLooper());
}

final StateHandler builderStateHandler = builder.stateHandler;
Expand Down Expand Up @@ -413,12 +413,12 @@ public void setNewLayoutStateReadyListener(NewLayoutStateReadyListener listener)
public void updateLayoutThreadHandler(@Nullable LithoHandler layoutThreadHandler) {
synchronized (mUpdateStateSyncRunnableLock) {
if (mUpdateStateSyncRunnable != null) {
mLayoutThreadHandler.removeCallbacks(mUpdateStateSyncRunnable);
mLayoutThreadHandler.remove(mUpdateStateSyncRunnable);
}
}
synchronized (mCurrentCalculateLayoutRunnableLock) {
if (mCurrentCalculateLayoutRunnable != null) {
mLayoutThreadHandler.removeCallbacks(mCurrentCalculateLayoutRunnable);
mLayoutThreadHandler.remove(mCurrentCalculateLayoutRunnable);
}
}
mLayoutThreadHandler = layoutThreadHandler;
Expand Down Expand Up @@ -1123,28 +1123,28 @@ void updateStateSync(String componentKey, StateUpdate stateUpdate, String attrib
"using the default background layout thread instead");
synchronized (mUpdateStateSyncRunnableLock) {
if (mUpdateStateSyncRunnable != null) {
mLayoutThreadHandler.removeCallbacks(mUpdateStateSyncRunnable);
mLayoutThreadHandler.remove(mUpdateStateSyncRunnable);
}
mUpdateStateSyncRunnable = new UpdateStateSyncRunnable(attribution);
mLayoutThreadHandler.post(mUpdateStateSyncRunnable);
mLayoutThreadHandler.post(mUpdateStateSyncRunnable, "updateStateSync " + attribution);
}
return;
}

final WeakReference<Handler> handlerWr = sSyncStateUpdatesHandler.get();
Handler handler = handlerWr != null ? handlerWr.get() : null;
final WeakReference<LithoHandler> handlerWr = sSyncStateUpdatesHandler.get();
LithoHandler handler = handlerWr != null ? handlerWr.get() : null;

if (handler == null) {
handler = new Handler(looper);
handler = new DefaultLithoHandler(looper);
sSyncStateUpdatesHandler.set(new WeakReference<>(handler));
}

synchronized (mUpdateStateSyncRunnableLock) {
if (mUpdateStateSyncRunnable != null) {
handler.removeCallbacks(mUpdateStateSyncRunnable);
handler.remove(mUpdateStateSyncRunnable);
}
mUpdateStateSyncRunnable = new UpdateStateSyncRunnable(attribution);
handler.post(mUpdateStateSyncRunnable);
handler.post(mUpdateStateSyncRunnable, attribution);
}
}

Expand Down Expand Up @@ -1621,11 +1621,12 @@ private void setRootAndSizeSpecInternal(
if (isAsync) {
synchronized (mCurrentCalculateLayoutRunnableLock) {
if (mCurrentCalculateLayoutRunnable != null) {
mLayoutThreadHandler.removeCallbacks(mCurrentCalculateLayoutRunnable);
mLayoutThreadHandler.remove(mCurrentCalculateLayoutRunnable);
}
mCurrentCalculateLayoutRunnable =
new CalculateLayoutRunnable(source, treeProps, extraAttribution, layoutStateFuture);
mLayoutThreadHandler.post(mCurrentCalculateLayoutRunnable);
mLayoutThreadHandler.post(
mCurrentCalculateLayoutRunnable, source + " - " + extraAttribution);
}
} else {
calculateLayout(output, source, extraAttribution, treeProps, layoutStateFuture);
Expand Down Expand Up @@ -1653,7 +1654,7 @@ private void calculateLayout(
// since we are starting a new layout computation.
synchronized (mCurrentCalculateLayoutRunnableLock) {
if (mCurrentCalculateLayoutRunnable != null) {
mLayoutThreadHandler.removeCallbacks(mCurrentCalculateLayoutRunnable);
mLayoutThreadHandler.remove(mCurrentCalculateLayoutRunnable);
mCurrentCalculateLayoutRunnable = null;
}
}
Expand Down Expand Up @@ -1768,8 +1769,9 @@ private void calculateLayout(
}

if (mPreAllocateMountContentHandler != null) {
mPreAllocateMountContentHandler.removeCallbacks(mPreAllocateMountContentRunnable);
mPreAllocateMountContentHandler.post(mPreAllocateMountContentRunnable);
mPreAllocateMountContentHandler.remove(mPreAllocateMountContentRunnable);
mPreAllocateMountContentHandler.post(
mPreAllocateMountContentRunnable, source + " - " + extraAttribution);
}

if (layoutEvent != null) {
Expand Down Expand Up @@ -1823,13 +1825,13 @@ public void release() {

synchronized (mCurrentCalculateLayoutRunnableLock) {
if (mCurrentCalculateLayoutRunnable != null) {
mLayoutThreadHandler.removeCallbacks(mCurrentCalculateLayoutRunnable);
mLayoutThreadHandler.remove(mCurrentCalculateLayoutRunnable);
mCurrentCalculateLayoutRunnable = null;
}
}
synchronized (mUpdateStateSyncRunnableLock) {
if (mUpdateStateSyncRunnable != null) {
mLayoutThreadHandler.removeCallbacks(mUpdateStateSyncRunnable);
mLayoutThreadHandler.remove(mUpdateStateSyncRunnable);
mUpdateStateSyncRunnable = null;
}
}
Expand All @@ -1843,7 +1845,7 @@ public void release() {
}

if (mPreAllocateMountContentHandler != null) {
mPreAllocateMountContentHandler.removeCallbacks(mPreAllocateMountContentRunnable);
mPreAllocateMountContentHandler.remove(mPreAllocateMountContentRunnable);
}

mReleased = true;
Expand Down Expand Up @@ -2429,23 +2431,6 @@ public int hashCode() {
}
}

/**
* A default {@link LithoHandler} that will use a {@link Handler} with a {@link Thread}'s {@link
* Looper}.
*/
private static class DefaultLithoHandler extends Handler implements LithoHandler {
private DefaultLithoHandler(Looper threadLooper) {
super(threadLooper);
}
}

private static class DefaultPreallocateMountContentHandler extends Handler
implements LithoHandler {
private DefaultPreallocateMountContentHandler(Looper threadLooper) {
super(threadLooper);
}
}

public static int generateComponentTreeId() {
return sIdGenerator.getAndIncrement();
}
Expand Down
31 changes: 26 additions & 5 deletions litho-core/src/main/java/com/facebook/litho/LithoHandler.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-present Facebook, Inc.
* Copyright 2019-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,15 +13,36 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.facebook.litho;

import android.os.Handler;
import android.os.Looper;

/**
* The Litho handler is responsible for scheduling computations on a {@link ComponentTree}. The
* default implementation uses a {@link android.os.Handler} with a {@link android.os.Looper}.
*/
public interface LithoHandler {
boolean post(Runnable runnable);
void removeCallbacks(Runnable runnable);
void removeCallbacksAndMessages(Object token);

void post(Runnable runnable, String tag);

void remove(Runnable runnable);

/** Default implementation of the LithoHandler which simply wraps an {@link Handler}. */
class DefaultLithoHandler extends Handler implements LithoHandler {

public DefaultLithoHandler(Looper looper) {
super(looper);
}

@Override
public void post(Runnable runnable, String tag) {
post(runnable);
}

@Override
public void remove(Runnable runnable) {
removeCallbacks(runnable);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,16 @@ public ThreadPoolLayoutHandler(LayoutThreadPoolConfiguration configuration) {
}

@Override
public boolean post(Runnable runnable) {
public void post(Runnable runnable, String tag) {
try {
sLayoutThreadPoolExecutor.execute(runnable);
return true;
} catch (RejectedExecutionException e) {
throw new RuntimeException("Cannot execute layout calculation task; " + e);
}
}

@Override
public void removeCallbacks(Runnable runnable) {
public void remove(Runnable runnable) {
sLayoutThreadPoolExecutor.remove(runnable);
}

@Override
public void removeCallbacksAndMessages(Object token) {
throw new RuntimeException("Operation not supported");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,8 @@ public void run() {
assertEquals(0, layoutStateFuture.getWaitingCount());
assertEquals(0, componentTree.getLayoutStateFutures().size());
}
});
},
"tag");
}

@Test
Expand Down

0 comments on commit 0d0bb0b

Please sign in to comment.