public static void calculateLayoutState( ComponentContext c, Component component, int widthSizeSpec, int heightSizeSpec) { LayoutState.calculate( c, component, -1, widthSizeSpec, heightSizeSpec, LayoutState.CalculateLayoutSource.TEST); }
private static void assertOutputsState( LayoutState layoutState, @LayoutOutput.UpdateState int state) { assertThat(STATE_DIRTY).isEqualTo(layoutState.getMountableOutputAt(0).getUpdateState()); for (int i = 1; i < layoutState.getMountableOutputCount(); i++) { LayoutOutput output = layoutState.getMountableOutputAt(i); assertThat(state).isEqualTo(output.getUpdateState()); } }
@Nullable LayoutState previousLayoutState, @Nullable TreeProps treeProps, @CalculateLayoutSource int source, @Nullable String extraAttribution) { final ComponentContext contextWithStateHandler; return LayoutState.calculate( contextWithStateHandler, root,
/** @return a {@link LayoutOutput} for a given {@param layoutOutputId} */ @Nullable LayoutOutput getLayoutOutput(long layoutOutputId) { final int position = getLayoutOutputPositionForId(layoutOutputId); return position < 0 ? null : getMountableOutputAt(position); }
static LayoutState acquireLayoutState(ComponentContext context) { LayoutState state = ComponentsConfiguration.disablePools ? null : sLayoutStatePool.acquire(); if (state == null) { state = new LayoutState(); } state.init(context); return state; }
private int findLastDescendantIndex(LayoutState layoutState, int index) { final LayoutOutput host = layoutState.getMountableOutputAt(index); final long hostId = host.getId(); for (int i = index + 1, size = layoutState.getMountableOutputCount(); i < size; i++) { final LayoutOutput layoutOutput = layoutState.getMountableOutputAt(i); // Walk up the parents looking for the host's id: if we find it, it's a descendant. If we // reach the root, then it's not a descendant and we can stop. long curentHostId = layoutOutput.getHostMarker(); while (curentHostId != hostId) { if (curentHostId == ROOT_HOST_ID) { return i - 1; } final int parentIndex = layoutState.getLayoutOutputPositionForId(curentHostId); final LayoutOutput parent = layoutState.getMountableOutputAt(parentIndex); curentHostId = parent.getHostMarker(); } } return layoutState.getMountableOutputCount() - 1; }
resolveNestedTree( parentContext.isNestedTreeResolutionExperimentEnabled() ? parentContext collectResults(parentContext, nestedTree, layoutState, parentDiffNode); diffNode = createDiffNode(node, parentDiffNode); if (isTracing) { ComponentsSystrace.endSection(); final boolean needsHostView = needsHostView(node, layoutState); final boolean needsPhantomLayoutOutput = !needsHostView && needsHostViewForTransition(node); final boolean shouldAddHostLayoutOutput = needsHostView || needsPhantomLayoutOutput; layoutState.mCurrentTransitionId = getTransitionIdForNode(node); layoutState.mCurrentLayoutOutputAffinityGroup = layoutState.mCurrentTransitionId != null addHostLayoutOutput(node, layoutState, diffNode, needsPhantomLayoutOutput); addCurrentAffinityGroupToTransitionMapping(layoutState); createGenericLayoutOutput(node, layoutState, shouldAddHostLayoutOutput); if (layoutOutput != null) { final long previousId = shouldUseCachedOutputs ? currentDiffNode.getContent().getId() : -1; layoutState.calculateAndSetLayoutOutputIdAndUpdateState( layoutOutput, layoutState.mCurrentLevel, addDrawableComponent(
@CalculateLayoutSource int source, @Nullable String extraAttribution, @Nullable TreeProps treeProps) { final LayoutState mostRecentLayoutState = mBackgroundLayoutState != null ? mBackgroundLayoutState : mMainThreadLayoutState; output.width = mostRecentLayoutState.getWidth(); output.height = mostRecentLayoutState.getHeight(); previousLayoutState = mMainThreadLayoutState.acquireRef(); output.width = localLayoutState.getWidth(); output.height = localLayoutState.getHeight(); previousLayoutState.releaseRef(); previousLayoutState = null; localLayoutState.consumeStateHandler(); if (layoutStateStateHandler != null) { if (mStateHandler != null) { // we could have been released rootWidth = localLayoutState.getWidth(); rootHeight = localLayoutState.getHeight(); components = new ArrayList<>(localLayoutState.getComponents()); localLayoutState.clearComponents(); localLayoutState.releaseRef(); localLayoutState = null;
calculate( new ComponentContext(application), component, LayoutState.CalculateLayoutSource.TEST); assertThat(layoutState.getMountableOutputCount()).isEqualTo(12); isDuplicateParentState(layoutState.getMountableOutputAt(0).getFlags())); isDuplicateParentState(layoutState.getMountableOutputAt(1).getFlags())); isDuplicateParentState(layoutState.getMountableOutputAt(2).getFlags())); isDuplicateParentState(layoutState.getMountableOutputAt(4).getFlags())); isDuplicateParentState(layoutState.getMountableOutputAt(6).getFlags())); isDuplicateParentState(layoutState.getMountableOutputAt(8).getFlags())); assertTrue( "Foreground should duplicate clickable node state", isDuplicateParentState(layoutState.getMountableOutputAt(9).getFlags())); isDuplicateParentState(layoutState.getMountableOutputAt(10).getFlags())); assertFalse( "Foreground should duplicate non-clickable node state", isDuplicateParentState(layoutState.getMountableOutputAt(11).getFlags()));
private BitSet calculateSkipMounting(LayoutState layoutState) { if (!ComponentsConfiguration.createPhantomLayoutOutputsForTransitions) { return sEmptyBitSet; } final BitSet skipMounting = new BitSet(); for (int index = layoutState.getMountableOutputCount() - 1; index >= 0; index--) { if (shouldSkipMounting(layoutState, index)) { skipMounting.set(index); } } return skipMounting; }
@Override public float getCurrentState(PropertyHandle propertyHandle) { final LayoutOutput root = mLayoutState.getMountableOutputAt(0); return mAnimatedProperty.get(root); }
private void setupPreviousMountableOutputData(LayoutState layoutState, Rect localVisibleRect) { if (localVisibleRect.isEmpty()) { return; } final ArrayList<LayoutOutput> layoutOutputTops = layoutState.getMountableOutputTops(); final ArrayList<LayoutOutput> layoutOutputBottoms = layoutState.getMountableOutputBottoms(); final int mountableOutputCount = layoutState.getMountableOutputCount(); mPreviousTopsIndex = layoutState.getMountableOutputCount(); for (int i = 0; i < mountableOutputCount; i++) { if (localVisibleRect.bottom <= layoutOutputTops.get(i).getBounds().top) { mPreviousTopsIndex = i; break; } } mPreviousBottomsIndex = layoutState.getMountableOutputCount(); for (int i = 0; i < mountableOutputCount; i++) { if (localVisibleRect.top < layoutOutputBottoms.get(i).getBounds().bottom) { mPreviousBottomsIndex = i; break; } } }
|| !hasCompatibleSizeSpec( nestedTree.getLastWidthSpec(), nestedTree.getLastHeightSpec(), consumeCachedLayout(component, holder, widthSpec, heightSpec); remeasureTree(nestedTree, widthSpec, heightSpec); resolvedLayout = nestedTree; } else { releaseNodeTree(nestedTree, true /* isNestedTree */); createAndMeasureTreeForComponent( context, component,
@Test public void testGetTransitionKeyMapping() { ComponentContext c = new ComponentContext(application); LayoutState layoutState = LayoutState.calculate( c, mHasUniqueTransitionKeys, ComponentTree.generateComponentTreeId(), View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY), LayoutState.CalculateLayoutSource.TEST); layoutState.getTransitionIdMapping(); }
@Test public void testCachedMeasures() { final Component component1 = new TestLayoutSpec(false); final Component component2 = new TestLayoutSpec(false); LayoutState prevLayoutState = calculateLayoutStateWithDiffing( mContext, component1, SizeSpec.makeSizeSpec(350, SizeSpec.EXACTLY), SizeSpec.makeSizeSpec(200, SizeSpec.EXACTLY), null); // Check diff tree is consistent. DiffNode node = prevLayoutState.getDiffTree(); InternalNode layoutTreeRoot = LayoutState.createTree( component2, mContext); LayoutState.applyDiffNodeToUnchangedNodes(layoutTreeRoot, node); checkAllComponentsHaveMeasureCache(layoutTreeRoot); }
.append(component.getSimpleName()) .append("_") .append(sourceToString(source)) .toString()) .arg("treeId", componentTreeId) if (logLayoutState != null) { logLayoutState.markerAnnotate(PARAM_COMPONENT, component.getSimpleName()); logLayoutState.markerAnnotate(PARAM_LAYOUT_STATE_SOURCE, sourceToString(source)); final InternalNode root = layoutCreatedInWillRender == null ? createAndMeasureTreeForComponent( c, component, layoutState.clearLayoutStateOutputIdCalculator(); layoutState.mRootTransitionId = getTransitionIdForNode(root); : null; collectResults(c, root, layoutState, null); InternalNode node = layoutState.mLayoutRoot; layoutState.mLayoutRoot = null; releaseNodeTree(node, false /* isNestedTree */);
LayoutState.createAndMeasureTreeForComponent(c, this, widthSpec, heightSpec);
c.setHeightSpec(heightSpec); final InternalNode root = createTree( component, c); diffTreeRoot = nestedTreeHolder.getDiffNode(); } else if (root.getStyleDirection() == com.facebook.yoga.YogaDirection.INHERIT && LayoutState.isLayoutDirectionRTL(c.getAndroidContext())) { root.layoutDirection(YogaDirection.RTL); measureTree( root, widthSpec,
when(LayoutState.resolveNestedTree(mContext, holder, 100, 100)).thenCallRealMethod(); when(LayoutState.createAndMeasureTreeForComponent(mContext, component, holder, 100, 100, null)) .thenReturn(resolved); InternalNode result = LayoutState.resolveNestedTree(mContext, holder, 100, 100); LayoutState.createAndMeasureTreeForComponent(mContext, component, holder, 100, 100, null); LayoutState.resolveNestedTree(mContext, holder, 100, 100); LayoutState.createAndMeasureTreeForComponent(mContext, component, holder, 100, 100, null); LayoutState.remeasureTree(resolved, 100, 100);
private void regenerateAnimationLockedIndices(LayoutState newLayoutState) { final Map<TransitionId, OutputUnitsAffinityGroup<LayoutOutput>> transitionMapping = newLayoutState.getTransitionIdMapping(); if (transitionMapping != null) { for (TransitionId transitionId : transitionMapping.keySet()) { if (!mAnimatingTransitionIds.contains(transitionId)) { continue; } if (mAnimationLockedIndices == null) { mAnimationLockedIndices = new int[newLayoutState.getMountableOutputCount()]; } final OutputUnitsAffinityGroup<LayoutOutput> group = transitionMapping.get(transitionId); for (int j = 0, sz = group.size(); j < sz; j++) { final LayoutOutput layoutOutput = group.getAt(j); final int position = newLayoutState.getLayoutOutputPositionForId(layoutOutput.getId()); updateAnimationLockCount(newLayoutState, position, true); } } } else { mAnimationLockedIndices = null; } if (AnimationsDebug.ENABLED) { AnimationsDebug.debugPrintAnimationLockedIndices(newLayoutState, mAnimationLockedIndices); } }