<commit_before>//
//  ViewRenderer.swift
//  AsyncImageView
//
//  Created by <NAME> on 02/24/17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import UIKit
import CoreGraphics

/// `SynchronousRendererType` which generates a `UIImage` from a UIView.
@available(iOS 10.0, tvOSApplicationExtension 10.0,  *)
public final class ViewRenderer<Data: RenderDataType>: SynchronousRendererType {
    public typealias Block = (_ data: Data) -> UIView
    
    private let format: UIGraphicsImageRendererFormat
    private let viewCreationBlock: Block
    
    /// - opaque: A Boolean flag indicating whether the bitmap is opaque.
    /// If you know the bitmap is fully opaque, specify YES to ignore the
    /// alpha channel and optimize the bitmap’s storage.
    public init(opaque: Bool, viewCreationBlock: @escaping Block) {
        self.format = UIGraphicsImageRendererFormat()
        self.format.opaque = opaque
        self.viewCreationBlock = viewCreationBlock
    }
    
    public func renderImageWithData(_ data: Data) -> UIImage {
        let view = self.viewCreationBlock(data)
        view.frame.origin = .zero
        view.bounds.size = data.size
        view.layoutIfNeeded()
        
        let renderer = UIGraphicsImageRenderer(
            size: data.size,
            format: self.format
        )
        
        return renderer.image { context in
            precondition(
                view.drawHierarchy(in: view.bounds, afterScreenUpdates: true),
                "Error generating snapshot"
            )
        }
    }
}

/// `SynchronousRendererType` which generates a `UIImage` from a UIView.
public final class OldViewRenderer<Data: RenderDataType>: SynchronousRendererType {
    public typealias Block = (_ data: Data) -> UIView
    
    private let opaque: Bool
    private let viewCreationBlock: Block
    
    /// - opaque: A Boolean flag indicating whether the bitmap is opaque.
    /// If you know the bitmap is fully opaque, specify YES to ignore the
    /// alpha channel and optimize the bitmap’s storage.
    public init(opaque: Bool, viewCreationBlock: @escaping Block) {
        self.opaque = opaque
        self.viewCreationBlock = viewCreationBlock
    }
    
    public func renderImageWithData(_ data: Data) -> UIImage {
        let view = self.viewCreationBlock(data)
        view.frame.origin = .zero
        view.bounds.size = data.size
        view.layoutIfNeeded()
        
        UIGraphicsBeginImageContextWithOptions(data.size, self.opaque, 0)
        defer { UIGraphicsEndImageContext() }
        
        precondition(
            view.drawHierarchy(in: view.bounds, afterScreenUpdates: true),
            "Error generating snapshot"
        )
        
        return UIGraphicsGetImageFromCurrentImageContext()!
    }
}<commit_msg>AsyncImageView: fixed flickering issue with ViewRenderer and views that aren't in the view hierarchy<commit_after>//
//  ViewRenderer.swift
//  AsyncImageView
//
//  Created by <NAME> on 02/24/17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import UIKit
import CoreGraphics

import ReactiveSwift
import Result

/// `RendererType` which generates a `UIImage` from a UIView.
@available(iOS 10.0, tvOSApplicationExtension 10.0,  *)
public final class ViewRenderer<Data: RenderDataType>: RendererType {
    public typealias Block = (_ data: Data) -> UIView
    
    private let format: UIGraphicsImageRendererFormat
    private let viewCreationBlock: Block
    
    /// - opaque: A Boolean flag indicating whether the bitmap is opaque.
    /// If you know the bitmap is fully opaque, specify YES to ignore the
    /// alpha channel and optimize the bitmap’s storage.
    public init(opaque: Bool, viewCreationBlock: @escaping Block) {
        self.format = UIGraphicsImageRendererFormat()
        self.format.opaque = opaque
        self.viewCreationBlock = viewCreationBlock
    }
    
    public func renderImageWithData(_ data: Data) -> SignalProducer<UIImage, NoError> {
        return createProducer(
            data,
            viewCreationBlock: self.viewCreationBlock,
            renderBlock: { view in
                let renderer = UIGraphicsImageRenderer(
                    size: data.size,
                    format: self.format
                )
                
                return renderer.image { context in
                    draw(view: view, inContext: context.cgContext)
                }
            }
        )
    }
}

/// `RendererType` which generates a `UIImage` from a UIView.
public final class OldViewRenderer<Data: RenderDataType>: RendererType {
    public typealias Block = (_ data: Data) -> UIView
    
    private let opaque: Bool
    private let viewCreationBlock: Block
    
    /// - opaque: A Boolean flag indicating whether the bitmap is opaque.
    /// If you know the bitmap is fully opaque, specify YES to ignore the
    /// alpha channel and optimize the bitmap’s storage.
    public init(opaque: Bool, viewCreationBlock: @escaping Block) {
        self.opaque = opaque
        self.viewCreationBlock = viewCreationBlock
    }
    
    public func renderImageWithData(_ data: Data) -> SignalProducer<UIImage, NoError> {
        return createProducer(
            data,
            viewCreationBlock: self.viewCreationBlock,
            renderBlock: { view in
                
                UIGraphicsBeginImageContextWithOptions(data.size, self.opaque, 0)
                defer { UIGraphicsEndImageContext() }
                
                draw(view: view, inContext: UIGraphicsGetCurrentContext()!)
                
                return UIGraphicsGetImageFromCurrentImageContext()!
            }
        )
    }
}

fileprivate func createProducer<Data: RenderDataType>(
    _ data: Data,
    viewCreationBlock: @escaping (_ data: Data) -> UIView,
    renderBlock: @escaping (UIView) -> UIImage
) -> SignalProducer<UIImage, NoError> {
    return SignalProducer { observer, disposable in
        let view = viewCreationBlock(data)
        view.frame.origin = .zero
        view.bounds.size = data.size
        view.layoutIfNeeded()
        
        // Make the CA renderer wait "until all the post-commit triggers fire".
        // We can't take a snapshot right away because the view has not been commited to the render server yet.
        DispatchQueue.main.async {
            if !disposable.isDisposed {
                observer.send(value: renderBlock(view))
                observer.sendCompleted()
            }
        }
    }
        .start(on: UIScheduler())
}

fileprivate func draw(view: UIView, inContext context: CGContext) {
    view.layer.render(in: context)
}
{'fraction_non_alphanumeric': 0.08109737714802533, 'fraction_numerical': 0.0051251130539644255, 'mean_word_length': 2.3191595797898947, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5925744', 'n_tokens_mistral': 1830, 'n_tokens_neox': 1739, 'n_words': 534}