/** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.litho; import java.util.concurrent.atomic.AtomicInteger; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.view.View; import com.facebook.litho.reference.Reference; import com.facebook.yoga.YogaDirection; /** * Additional information passed between {@link LayoutState} and {@link MountState} * used on a {@link View}. */ class ViewNodeInfo { private final AtomicInteger mReferenceCount = new AtomicInteger(0); private Reference<Drawable> mBackground; private Drawable mForeground; private Rect mPadding; private Rect mExpandedTouchBounds; private YogaDirection mLayoutDirection; private String mTransitionKey; void setBackground(Reference<? extends Drawable> background) { mBackground = (Reference<Drawable>) background; } Reference<Drawable> getBackground() { return mBackground; } void setForeground(Drawable foreground) { mForeground = foreground; } Drawable getForeground() { return mForeground; } int getPaddingLeft() { return (mPadding != null) ? mPadding.left : 0; } int getPaddingTop() { return (mPadding != null) ? mPadding.top : 0; } int getPaddingRight() { return (mPadding != null) ? mPadding.right : 0; } int getPaddingBottom() { return (mPadding != null) ? mPadding.bottom : 0; } void setPadding(int l, int t, int r, int b) { if (l == 0 && t == 0 && r == 0 && b == 0) { return; } if (mPadding != null) { throw new IllegalStateException("Padding already initialized for this " + "ViewNodeInfo."); } mPadding = ComponentsPools.acquireRect(); mPadding.set(l, t, r, b); } boolean hasPadding() { return (mPadding != null); } void setLayoutDirection(YogaDirection layoutDirection) { mLayoutDirection = layoutDirection; } YogaDirection getLayoutDirection() { return mLayoutDirection; } void setExpandedTouchBounds(InternalNode node, int l, int t, int r, int b) { if (!node.hasTouchExpansion()) { return; } final int touchExpansionLeft = node.getTouchExpansionLeft(); final int touchExpansionTop = node.getTouchExpansionTop(); final int touchExpansionRight = node.getTouchExpansionRight(); final int touchExpansionBottom = node.getTouchExpansionBottom(); if (touchExpansionLeft == 0 && touchExpansionTop == 0 && touchExpansionRight == 0 && touchExpansionBottom == 0) { return; } if (mExpandedTouchBounds != null) { throw new IllegalStateException("ExpandedTouchBounds already initialized for this " + "ViewNodeInfo."); } mExpandedTouchBounds = ComponentsPools.acquireRect(); mExpandedTouchBounds.set( l - touchExpansionLeft, t - touchExpansionTop, r + touchExpansionRight, b + touchExpansionBottom); } Rect getExpandedTouchBounds() { if (mExpandedTouchBounds == null || mExpandedTouchBounds.isEmpty()) { return null; } return mExpandedTouchBounds; } void setTransitionKey(String key) { mTransitionKey = key; } String getTransitionKey() { return mTransitionKey; } static ViewNodeInfo acquire() { final ViewNodeInfo viewNodeInfo = ComponentsPools.acquireViewNodeInfo(); if (viewNodeInfo.mReferenceCount.getAndSet(1) != 0) { throw new IllegalStateException("The ViewNodeInfo reference acquired from the pool " + " wasn't correctly released."); } return viewNodeInfo; } ViewNodeInfo acquireRef() { if (mReferenceCount.getAndIncrement() < 1) { throw new IllegalStateException("The ViewNodeInfo being acquired" + " wasn't correctly initialized."); } return this; } void release() { final int count = mReferenceCount.decrementAndGet(); if (count < 0) { throw new IllegalStateException("Trying to release a recycled ViewNodeInfo."); } else if (count > 0) { return; } mBackground = null; mForeground = null; mLayoutDirection = YogaDirection.INHERIT; mTransitionKey = null; if (mPadding != null) { ComponentsPools.release(mPadding); mPadding = null; } if (mExpandedTouchBounds != null) { ComponentsPools.release(mExpandedTouchBounds); mExpandedTouchBounds = null; } ComponentsPools.release(this); } }