private void applyNewChangeSet()

in litho-sections-core/src/main/java/com/facebook/litho/sections/SectionTree.java [1154:1337]


  private void applyNewChangeSet(
      @ApplyNewChangeSet int source,
      @Nullable String attribution,
      @Nullable ThreadTracingRunnable prevTracingRunnable,
      @Nullable ChangesetDebugInfo changesetDebugInfo) {
    if (attribution == null) {
      attribution = mTag;
    }

    final boolean isTracing = ComponentsSystrace.isTracing();
    if (isTracing) {
      if (attribution != null) {
        ComponentsSystrace.beginSection("extra:" + attribution);
      }
      final String name;
      synchronized (this) {
        name = mNextSection != null ? mNextSection.getSimpleName() : "<null>";
      }
      ComponentsSystrace.beginSection(
          name
              + "_applyNewChangeSet_"
              + SectionsLogEventUtils.applyNewChangeSetSourceToString(source));
    }

    if (SectionsDebug.ENABLED) {
      final String name;
      synchronized (this) {
        name = mNextSection != null ? mNextSection.getSimpleName() : "<null>";
      }
      Log.d(
          SectionsDebug.TAG,
          "=== NEW CHANGE SET ("
              + SectionsLogEventUtils.applyNewChangeSetSourceToString(source)
              + ", S: "
              + name
              + ", Tree: "
              + hashCode()
              + ") ====");
    }

    try {
      Section currentRoot;
      Section nextRoot;
      StateUpdatesHolder pendingStateUpdates;

      final ComponentsLogger logger;

      synchronized (this) {
        if (mReleased) {
          return;
        }

        currentRoot = copy(mCurrentSection, true);
        nextRoot = copy(mNextSection, false);
        logger = mContext.getLogger();
        pendingStateUpdates = mPendingStateUpdates.copy();
        mIsChangeSetCalculationInProgress = true;
      }

      final PerfEvent logEvent =
          SectionsLogEventUtils.getSectionsPerformanceEvent(
              mContext, EVENT_SECTIONS_SET_ROOT, currentRoot, nextRoot);
      final boolean enableStats = logger != null && logEvent != null && logger.isTracing(logEvent);
      if (logEvent != null) {
        logEvent.markerAnnotate(PARAM_ATTRIBUTION, attribution);
        logEvent.markerAnnotate(
            PARAM_SECTION_SET_ROOT_SOURCE,
            SectionsLogEventUtils.applyNewChangeSetSourceToString(source));
        logEvent.markerAnnotate(PARAM_SET_ROOT_ON_BG_THREAD, !ThreadUtils.isMainThread());
      }

      clearUnusedTriggerHandlers();

      // Checking nextRoot is enough here since whenever we enqueue a new state update we also
      // re-assign nextRoot.
      while (nextRoot != null) {
        if (isTracing) {
          ComponentsSystrace.beginSection("calculateNewChangeSet");
        }
        final ChangeSetState changeSetState =
            calculateNewChangeSet(
                mContext,
                currentRoot,
                nextRoot,
                pendingStateUpdates.mAllStateUpdates,
                mSectionsDebugLogger,
                mTag,
                enableStats);
        if (isTracing) {
          ComponentsSystrace.endSection();
        }

        final boolean changeSetIsValid;
        Section oldRoot = null;
        Section newRoot = null;

        synchronized (this) {
          boolean currentNotNull = currentRoot != null;
          boolean instanceCurrentNotNull = mCurrentSection != null;
          boolean currentIsSame =
              (currentNotNull
                      && instanceCurrentNotNull
                      && currentRoot.getId() == mCurrentSection.getId())
                  || (!currentNotNull && !instanceCurrentNotNull);
          boolean nextIsSame = (mNextSection != null && nextRoot.getId() == mNextSection.getId());

          changeSetIsValid =
              currentIsSame && nextIsSame && isStateUpdateCompleted(pendingStateUpdates);

          if (changeSetIsValid) {
            oldRoot = mCurrentSection;
            newRoot = nextRoot;

            mCurrentSection = newRoot;
            mNextSection = null;
            resetStateUpdatesCount();
            mPendingStateUpdates.removeCompletedStateUpdates(pendingStateUpdates);
            mPendingChangeSets.add(changeSetState.getChangeSet());

            if (oldRoot != null) {
              unbindOldComponent(oldRoot);
            }

            bindTriggerHandler(newRoot);
          }
        }

        if (changeSetIsValid) {
          if (newRoot != null) {
            bindNewComponent(newRoot);
          }

          final List<Section> removedComponents = changeSetState.getRemovedComponents();
          for (int i = 0, size = removedComponents.size(); i < size; i++) {
            final Section removedComponent = removedComponents.get(i);
            releaseRange(mLastRanges.remove(removedComponent.getGlobalKey()));
          }

          mEventHandlersController.clearUnusedEventHandlers();
          postNewChangeSets(prevTracingRunnable, changesetDebugInfo);
        }

        synchronized (this) {
          pendingStateUpdates.release();

          if (mReleased) {
            return;
          }

          currentRoot = copy(mCurrentSection, true);
          nextRoot = copy(mNextSection, false);
          if (nextRoot != null) {
            pendingStateUpdates = mPendingStateUpdates.copy();
            mIsChangeSetCalculationInProgress = true;
          } else {
            resetStateUpdatesCount();
          }
        }
      }

      final LithoStartupLogger startupLogger =
          mContext.getTreeProps() == null
              ? null
              : mContext.getTreeProps().get(LithoStartupLogger.class);
      if (LithoStartupLogger.isEnabled(startupLogger)) {
        startupLogger.markPoint(LithoStartupLogger.CHANGESET_CALCULATION, LithoStartupLogger.END);
      }

      if (logger != null && logEvent != null) {
        logger.logPerfEvent(logEvent);
      }
    } finally {
      if (isTracing) {
        ComponentsSystrace.endSection();
        if (attribution != null) {
          ComponentsSystrace.endSection();
        }
      }
      LithoStats.incrementSectionCalculateNewChangesetCount();
      if (ThreadUtils.isMainThread()) {
        LithoStats.incrementSectionCalculateNewChangesetOnUICount();
      }
    }
  }