Skip to content

Commit 68218ae

Browse files
adityasharatfacebook-github-bot
authored andcommitted
Wraps visibility event handlers with width and height ratios
Summary: Wraps visibility events handler with width and height ratio. No behaviour or logic change. Reviewed By: astreet Differential Revision: D78268044 fbshipit-source-id: 203e040580882adcdbb8df83a50ff43701048d4a
1 parent 615b3c5 commit 68218ae

File tree

6 files changed

+170
-115
lines changed

6 files changed

+170
-115
lines changed

litho-core/src/main/java/com/facebook/litho/BaseMountingView.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -606,23 +606,23 @@ constructor(context: ComponentContext, attrs: AttributeSet? = null) :
606606
else null
607607
if (visibilityEventType == VisibleEvent::class.java) {
608608
if (visibilityOutput.onVisible != null) {
609-
dispatchOnVisible(requireNotNull(visibilityOutput.onVisible), content)
609+
dispatchOnVisible(requireNotNull(visibilityOutput.onVisible).callback, content)
610610
}
611611
} else if (visibilityEventType == InvisibleEvent::class.java) {
612612
if (visibilityOutput.onInvisible != null) {
613-
dispatchOnInvisible(requireNotNull(visibilityOutput.onInvisible))
613+
dispatchOnInvisible(requireNotNull(visibilityOutput.onInvisible).callback)
614614
}
615615
} else if (visibilityEventType == FocusedVisibleEvent::class.java) {
616616
if (visibilityOutput.onFocusedVisible != null) {
617-
dispatchOnFocused(requireNotNull(visibilityOutput.onFocusedVisible))
617+
dispatchOnFocused(requireNotNull(visibilityOutput.onFocusedVisible).callback)
618618
}
619619
} else if (visibilityEventType == UnfocusedVisibleEvent::class.java) {
620620
if (visibilityOutput.onUnfocusedVisible != null) {
621-
dispatchOnUnfocused(requireNotNull(visibilityOutput.onUnfocusedVisible))
621+
dispatchOnUnfocused(requireNotNull(visibilityOutput.onUnfocusedVisible).callback)
622622
}
623623
} else if (visibilityEventType == FullImpressionVisibleEvent::class.java) {
624624
if (visibilityOutput.onFullImpression != null) {
625-
dispatchOnFullImpression(requireNotNull(visibilityOutput.onFullImpression))
625+
dispatchOnFullImpression(requireNotNull(visibilityOutput.onFullImpression).callback)
626626
}
627627
}
628628
}

litho-core/src/main/java/com/facebook/litho/LithoReducer.kt

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import com.facebook.rendercore.RenderTreeNode
2929
import com.facebook.rendercore.incrementalmount.ExcludeFromIncrementalMountBinder
3030
import com.facebook.rendercore.incrementalmount.IncrementalMountOutput
3131
import com.facebook.rendercore.incrementalmount.IncrementalMountRenderCoreExtension
32+
import com.facebook.rendercore.visibility.VisibilityEventCallbackData
3233
import com.facebook.rendercore.visibility.VisibilityOutput
3334
import kotlin.math.max
3435
import kotlin.math.min
@@ -308,32 +309,74 @@ internal object LithoReducer {
308309
renderTreeNode: RenderTreeNode?
309310
): VisibilityOutput {
310311

311-
val visibleHandler: EventHandler<VisibleEvent>? = node.visibleHandler
312-
val focusedHandler: EventHandler<FocusedVisibleEvent>? = node.focusedHandler
313-
val unfocusedHandler: EventHandler<UnfocusedVisibleEvent>? = node.unfocusedHandler
314-
val fullImpressionHandler: EventHandler<FullImpressionVisibleEvent>? =
315-
node.fullImpressionHandler
316-
val invisibleHandler: EventHandler<InvisibleEvent>? = node.invisibleHandler
317-
val visibleRectChangedEventHandler: EventHandler<VisibilityChangedEvent>? =
318-
node.visibilityChangedHandler
312+
val onVisible =
313+
node.visibleHandler?.let {
314+
VisibilityEventCallbackData(
315+
widthRatio = node.visibleWidthRatio,
316+
heightRatio = node.visibleHeightRatio,
317+
callback = it,
318+
)
319+
}
320+
321+
val onFocusedVisible =
322+
node.focusedHandler?.let {
323+
VisibilityEventCallbackData(
324+
widthRatio = node.visibleWidthRatio,
325+
heightRatio = node.visibleHeightRatio,
326+
callback = it,
327+
)
328+
}
329+
val onUnfocusedVisible =
330+
node.unfocusedHandler?.let {
331+
VisibilityEventCallbackData(
332+
widthRatio = node.visibleWidthRatio,
333+
heightRatio = node.visibleHeightRatio,
334+
callback = it,
335+
)
336+
}
337+
val onFullImpression =
338+
node.fullImpressionHandler?.let {
339+
VisibilityEventCallbackData(
340+
widthRatio = node.visibleWidthRatio,
341+
heightRatio = node.visibleHeightRatio,
342+
callback = it,
343+
)
344+
}
345+
val onInvisible =
346+
node.invisibleHandler?.let {
347+
VisibilityEventCallbackData(
348+
widthRatio = node.visibleWidthRatio,
349+
heightRatio = node.visibleHeightRatio,
350+
callback = it,
351+
)
352+
}
353+
val onVisibilityChange =
354+
node.visibilityChangedHandler?.let {
355+
VisibilityEventCallbackData(
356+
widthRatio = node.visibleWidthRatio,
357+
heightRatio = node.visibleHeightRatio,
358+
callback = it,
359+
)
360+
}
319361
val component: Component = node.tailComponent
320362
val componentGlobalKey: String = node.tailComponentKey
321363

322364
return VisibilityOutput(
323-
componentGlobalKey,
324-
component.simpleName,
325-
Rect(bounds),
326-
renderTreeNode != null,
327-
renderTreeNode?.renderUnit?.id ?: 0,
328-
node.visibleHeightRatio,
329-
node.visibleWidthRatio,
330-
node.visibilityOutputTag,
331-
visibleHandler,
332-
invisibleHandler,
333-
focusedHandler,
334-
unfocusedHandler,
335-
fullImpressionHandler,
336-
visibleRectChangedEventHandler)
365+
id = componentGlobalKey,
366+
key = component.simpleName,
367+
bounds = Rect(bounds),
368+
hasMountableContent = renderTreeNode != null,
369+
renderUnitId = renderTreeNode?.renderUnit?.id ?: 0,
370+
visibleWidthRatio = node.visibleWidthRatio,
371+
visibleHeightRatio = node.visibleHeightRatio,
372+
tag = node.visibilityOutputTag,
373+
onVisible = onVisible,
374+
onInvisible = onInvisible,
375+
onFocusedVisible = onFocusedVisible,
376+
onUnfocusedVisible = onUnfocusedVisible,
377+
onFullImpression = onFullImpression,
378+
onVisibilityChange = onVisibilityChange,
379+
)
337380
}
338381

339382
private fun createTestOutput(

litho-rendercore-visibility/src/main/java/com/facebook/rendercore/visibility/VisibilityItem.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.facebook.rendercore.visibility
1818

1919
import android.graphics.Rect
20-
import com.facebook.rendercore.Function
2120

2221
/**
2322
* Holds information about a VisibilityOutput (that is, about an item for which a visibility event
@@ -28,9 +27,9 @@ class VisibilityItem(
2827
val key: String,
2928
// The invisible event and unfocused event handlers are required to make it possible to dispatch
3029
// the corresponding event when unbind is called or when the MountState is reset.
31-
var invisibleHandler: Function<Void>?,
32-
var unfocusedHandler: Function<Void>?,
33-
val visibilityChangedHandler: Function<Void>?,
30+
var invisibleHandler: VisibilityEventCallbackData?,
31+
var unfocusedHandler: VisibilityEventCallbackData?,
32+
val visibilityChangedHandler: VisibilityEventCallbackData?,
3433
val componentName: String,
3534
val renderUnitId: Long,
3635
val bounds: Rect

litho-rendercore-visibility/src/main/java/com/facebook/rendercore/visibility/VisibilityMountExtension.java

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import androidx.annotation.UiThread;
3232
import androidx.annotation.VisibleForTesting;
3333
import com.facebook.infer.annotation.Nullsafe;
34-
import com.facebook.rendercore.Function;
3534
import com.facebook.rendercore.Host;
3635
import com.facebook.rendercore.MountDelegate;
3736
import com.facebook.rendercore.RenderCoreSystrace;
@@ -334,12 +333,16 @@ private static void processVisibilityOutputsNonInc(
334333
continue;
335334
}
336335

337-
final Function<Void> visibleHandler = visibilityOutput.getOnVisible();
338-
final Function<Void> focusedHandler = visibilityOutput.getOnFocusedVisible();
339-
final Function<Void> unfocusedHandler = visibilityOutput.getOnUnfocusedVisible();
340-
final Function<Void> fullImpressionHandler = visibilityOutput.getOnFullImpression();
341-
final Function<Void> invisibleHandler = visibilityOutput.getOnInvisible();
342-
final Function<Void> visibilityChangedHandler = visibilityOutput.getOnVisibilityChange();
336+
final @Nullable VisibilityEventCallbackData onVisible = visibilityOutput.getOnVisible();
337+
final @Nullable VisibilityEventCallbackData onFocusedVisible =
338+
visibilityOutput.getOnFocusedVisible();
339+
final @Nullable VisibilityEventCallbackData onUnfocusedVisible =
340+
visibilityOutput.getOnUnfocusedVisible();
341+
final @Nullable VisibilityEventCallbackData onFullImpression =
342+
visibilityOutput.getOnFullImpression();
343+
final @Nullable VisibilityEventCallbackData onInvisible = visibilityOutput.getOnInvisible();
344+
final @Nullable VisibilityEventCallbackData onVisibilityChange =
345+
visibilityOutput.getOnVisibilityChange();
343346

344347
final boolean isCurrentlyVisible =
345348
boundsIntersect
@@ -349,24 +352,25 @@ private static void processVisibilityOutputsNonInc(
349352

350353
// If we did a relayout due to e.g. a state update then the handlers will have changed,
351354
// so we should keep them up to date.
352-
visibilityItem.setUnfocusedHandler(unfocusedHandler);
353-
visibilityItem.setInvisibleHandler(invisibleHandler);
355+
visibilityItem.setUnfocusedHandler(onUnfocusedVisible);
356+
visibilityItem.setInvisibleHandler(onInvisible);
354357

355358
if (!isCurrentlyVisible) {
356359
// Either the component is invisible now, but used to be visible, or the key on the
357360
// component has changed so we should generate new visibility events for the new
358361
// component.
359362
maybeDispatchOnInvisible(extensionState.getRenderStateId(), visibilityItem);
360363

361-
if (visibilityChangedHandler != null) {
364+
if (onVisibilityChange != null) {
362365
VisibilityUtils.dispatchOnVisibilityChanged(
363-
visibilityChangedHandler, 0, 0, 0, 0, 0, 0, 0f, 0f);
366+
onVisibilityChange.getCallback(), 0, 0, 0, 0, 0, 0, 0f, 0f);
364367
}
365368

366369
if (visibilityItem.isInFocusedRange()) {
367370
visibilityItem.setFocusedRange(false);
368371
if (visibilityItem.getUnfocusedHandler() != null) {
369-
VisibilityUtils.dispatchOnUnfocused(visibilityItem.getUnfocusedHandler());
372+
VisibilityUtils.dispatchOnUnfocused(
373+
visibilityItem.getUnfocusedHandler().getCallback());
370374
}
371375
}
372376

@@ -385,9 +389,9 @@ private static void processVisibilityOutputsNonInc(
385389
visibilityItem =
386390
new VisibilityItem(
387391
globalKey,
388-
invisibleHandler,
389-
unfocusedHandler,
390-
visibilityChangedHandler,
392+
onInvisible,
393+
onUnfocusedVisible,
394+
onVisibilityChange,
391395
visibilityOutput.getKey(),
392396
visibilityOutput.renderUnitId,
393397
visibilityOutput.getBounds());
@@ -396,7 +400,7 @@ private static void processVisibilityOutputsNonInc(
396400
visibilityItem.setWasFullyVisible(isFullyVisible);
397401
state.mVisibilityIdToItemMap.put(visibilityOutputId, visibilityItem);
398402

399-
if (visibleHandler != null) {
403+
if (onVisible != null) {
400404
final Object content =
401405
visibilityOutput.hasMountableContent
402406
? getContentById(extensionState, visibilityOutput.renderUnitId)
@@ -413,7 +417,7 @@ private static void processVisibilityOutputsNonInc(
413417
createVisibilityDebugAttributes(visibilityItem));
414418
}
415419

416-
VisibilityUtils.dispatchOnVisible(visibleHandler, content);
420+
VisibilityUtils.dispatchOnVisible(onVisible.getCallback(), content);
417421

418422
if (traceIdentifier != null) {
419423
DebugEventDispatcher.endTrace(traceIdentifier);
@@ -422,9 +426,9 @@ private static void processVisibilityOutputsNonInc(
422426
}
423427

424428
Rect transformedViewportRect = null;
425-
if (focusedHandler != null
426-
|| unfocusedHandler != null
427-
|| visibilityChangedHandler != null) {
429+
if (onFocusedVisible != null
430+
|| onUnfocusedVisible != null
431+
|| onVisibilityChange != null) {
428432
if (shouldUseTransformedVisibleRect && transformer != null) {
429433
final Host host = getRootHost(extensionState);
430434
if (host != null && (host.getParent() instanceof View)) {
@@ -435,7 +439,7 @@ private static void processVisibilityOutputsNonInc(
435439
}
436440

437441
// Check if the component has entered or exited the focused range.
438-
if (focusedHandler != null || unfocusedHandler != null) {
442+
if (onFocusedVisible != null || onUnfocusedVisible != null) {
439443
if (isInFocusedRange(
440444
extensionState,
441445
visibilityOutputBounds,
@@ -444,30 +448,30 @@ private static void processVisibilityOutputsNonInc(
444448
transformedViewportRect)) {
445449
if (!visibilityItem.isInFocusedRange()) {
446450
visibilityItem.setFocusedRange(true);
447-
if (focusedHandler != null) {
448-
VisibilityUtils.dispatchOnFocused(focusedHandler);
451+
if (onFocusedVisible != null) {
452+
VisibilityUtils.dispatchOnFocused(onFocusedVisible.getCallback());
449453
}
450454
}
451455
} else {
452456
if (visibilityItem.isInFocusedRange()) {
453457
visibilityItem.setFocusedRange(false);
454-
if (unfocusedHandler != null) {
455-
VisibilityUtils.dispatchOnUnfocused(unfocusedHandler);
458+
if (onUnfocusedVisible != null) {
459+
VisibilityUtils.dispatchOnUnfocused(onUnfocusedVisible.getCallback());
456460
}
457461
}
458462
}
459463
}
460464
// If the component has not entered the full impression range yet, make sure to update the
461465
// information about the visible edges.
462-
if (fullImpressionHandler != null && !visibilityItem.isInFullImpressionRange()) {
466+
if (onFullImpression != null && !visibilityItem.isInFullImpressionRange()) {
463467
visibilityItem.setVisibleEdges(visibilityOutputBounds, intersection);
464468

465469
if (visibilityItem.isInFullImpressionRange()) {
466-
VisibilityUtils.dispatchOnFullImpression(fullImpressionHandler);
470+
VisibilityUtils.dispatchOnFullImpression(onFullImpression.getCallback());
467471
}
468472
}
469473

470-
if (visibilityChangedHandler != null) {
474+
if (onVisibilityChange != null) {
471475
final int visibleWidth = getVisibleWidth(intersection);
472476
final int visibleHeight = getVisibleHeight(intersection);
473477
int rootHostViewWidth = getRootHostViewWidth(extensionState);
@@ -478,7 +482,7 @@ private static void processVisibilityOutputsNonInc(
478482
}
479483

480484
VisibilityUtils.dispatchOnVisibilityChanged(
481-
visibilityChangedHandler,
485+
onVisibilityChange.getCallback(),
482486
getVisibleTop(visibilityOutputBounds, intersection),
483487
getVisibleLeft(visibilityOutputBounds, intersection),
484488
visibleWidth,
@@ -539,7 +543,7 @@ private static void maybeDispatchOnInvisible(int renderStateId, VisibilityItem v
539543
createVisibilityDebugAttributes(visibilityItem));
540544
}
541545

542-
VisibilityUtils.dispatchOnInvisible(visibilityItem.getInvisibleHandler());
546+
VisibilityUtils.dispatchOnInvisible(visibilityItem.getInvisibleHandler().getCallback());
543547

544548
if (traceIdentifier != null) {
545549
DebugEventDispatcher.endTrace(traceIdentifier);
@@ -619,22 +623,23 @@ private static void clearVisibilityItemsNonincremental(
619623
final VisibilityItem visibilityItem = state.mVisibilityIdToItemMap.get(key);
620624

621625
if (visibilityItem != null) {
622-
final Function<Void> unfocusedHandler = visibilityItem.getUnfocusedHandler();
623-
final Function<Void> visibilityChangedHandler =
626+
final @Nullable VisibilityEventCallbackData onUnfocused =
627+
visibilityItem.getUnfocusedHandler();
628+
final @Nullable VisibilityEventCallbackData onVisibilityChanged =
624629
visibilityItem.getVisibilityChangedHandler();
625630

626631
maybeDispatchOnInvisible(renderStateId, visibilityItem);
627632

628633
if (visibilityItem.isInFocusedRange()) {
629634
visibilityItem.setFocusedRange(false);
630-
if (unfocusedHandler != null) {
631-
VisibilityUtils.dispatchOnUnfocused(unfocusedHandler);
635+
if (onUnfocused != null) {
636+
VisibilityUtils.dispatchOnUnfocused(onUnfocused.getCallback());
632637
}
633638
}
634639

635-
if (visibilityChangedHandler != null) {
640+
if (onVisibilityChanged != null) {
636641
VisibilityUtils.dispatchOnVisibilityChanged(
637-
visibilityChangedHandler, 0, 0, 0, 0, 0, 0, 0f, 0f);
642+
onVisibilityChanged.getCallback(), 0, 0, 0, 0, 0, 0, 0f, 0f);
638643
}
639644

640645
visibilityItem.setWasFullyVisible(false);

0 commit comments

Comments
 (0)