Repository: airbnb/lottie-ios
File: Sources/Private/CoreAnimation/CoreAnimationLayer.swift (Swift)

Code before:
    /// The animation is statically displaying a specific frame
    case paused(frame: AnimationFrameTime)
  }

  /// Configuration used by the `playAnimation` method
  struct AnimationConfiguration: Equatable {
    var animationContext: AnimationContext
    var timingConfiguration: CAMediaTimingConfiguration
    var logHierarchyKeypaths = false
  }

  /// A closure that is called after this layer sets up its animation.
  /// If the animation setup was unsuccessful and encountered compatibility issues,
  /// those issues are included in this call.
  var didSetUpAnimation: (([CompatibilityIssue]) -> Void)?

  /// The `AnimationImageProvider` that `ImageLayer`s use to retrieve images,
  /// referenced by name in the animation json.
  var imageProvider: AnimationImageProvider {
    didSet { reloadImages() }
  }

  /// The `AnimationTextProvider` that `TextLayer`'s use to retrieve texts,
  /// that they should use to render their text context
  var textProvider: AnimationTextProvider {
    didSet { reloadTexts() }
  }

  /// The `FontProvider` that `TextLayer`s use to retrieve the `CTFont`
  /// that they should use to render their text content
  var fontProvider: AnimationFontProvider {
    didSet { reloadTexts() }
  }

  /// Queues the animation with the given timing configuration
  /// to begin playing at the next `display()` call.
  ///   - This batches together animations so that even if `playAnimation`
  ///     is called multiple times in the same run loop cycle, the animation
  ///     will only be set up a single time.
  func playAnimation(
    configuration: AnimationConfiguration,
    playbackState: PlaybackState = .playing)
  {
    pendingAnimationConfiguration = (
      animationConfiguration: configuration,
      playbackState: playbackState)

    setNeedsDisplay()
  }

  override func layoutSublayers() {

Review comment (suggestion):
`reloadFonts()` / `reloadTexts()` doesn't cause `setupAnimations(context:)` to be called again. Instead I think we need to call `rebuildCurrentAnimation()`, like we do in `setValueProvider(_:keypath:)` below.

Code after:
    /// The animation is statically displaying a specific frame
    case paused(frame: AnimationFrameTime)
  }

  /// Configuration used by the `playAnimation` method
  struct AnimationConfiguration: Equatable {
    var animationContext: AnimationContext
    var timingConfiguration: CAMediaTimingConfiguration
    var logHierarchyKeypaths = false
  }

  /// A closure that is called after this layer sets up its animation.
  /// If the animation setup was unsuccessful and encountered compatibility issues,
  /// those issues are included in this call.
  var didSetUpAnimation: (([CompatibilityIssue]) -> Void)?

  /// The `AnimationImageProvider` that `ImageLayer`s use to retrieve images,
  /// referenced by name in the animation json.
  var imageProvider: AnimationImageProvider {
    didSet { reloadImages() }
  }

  /// The `AnimationTextProvider` that `TextLayer`'s use to retrieve texts,
  /// that they should use to render their text context
  var textProvider: AnimationTextProvider {
    didSet {
      // We need to rebuild the current animation after updating the text provider,
      // since this is used in `TextLayer.setupAnimations(context:)`
      rebuildCurrentAnimation()
    }
  }

  /// The `FontProvider` that `TextLayer`s use to retrieve the `CTFont`
  /// that they should use to render their text content
  var fontProvider: AnimationFontProvider {
    didSet { reloadFonts() }
  }

  /// Queues the animation with the given timing configuration
  /// to begin playing at the next `display()` call.
  ///   - This batches together animations so that even if `playAnimation`
  ///     is called multiple times in the same run loop cycle, the animation
  ///     will only be set up a single time.
  func playAnimation(
    configuration: AnimationConfiguration,
    playbackState: PlaybackState = .playing)
  {
    pendingAnimationConfiguration = (
      animationConfiguration: configuration,
      playbackState: playbackState)