Skip to content

Commit

Permalink
format
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Usbergo committed Oct 7, 2019
1 parent b0ea5a1 commit f713382
Show file tree
Hide file tree
Showing 11 changed files with 627 additions and 507 deletions.
2 changes: 1 addition & 1 deletion samples/BufferDemo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
/// The key window.
var window: UIWindow?

/// Tells the delegate that the launch process is almost done and the app is almost ready to run.
func application(
_ application: UIApplication,
Expand All @@ -14,4 +15,3 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

}

55 changes: 45 additions & 10 deletions samples/BufferDemo/Lorem.swift

Large diffs are not rendered by default.

14 changes: 6 additions & 8 deletions samples/BufferDemo/ViewController.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import UIKit
import Buffer
import UIKit

func ==(lhs: FooModel, rhs: FooModel) -> Bool {
func == (lhs: FooModel, rhs: FooModel) -> Bool {
return lhs.text == rhs.text
}

struct FooModel: Diffable {
/// The identifier used from the diffing algorithm.
var diffIdentifier: String { return text }

/// Simple text property.
let text: String
}
Expand All @@ -19,14 +20,16 @@ class ViewController: UIViewController, UITableViewDelegate {
tableView.delegate = self
return tableView
}()

/// Some dummy elements.
lazy var elements: [ListItem<FooModel>] = {
var elements = [ListItem<FooModel>]()
for i in 0...100 {
let item = ListItem(
type: UITableViewCell.self,
container: self.tableView,
model: FooModel(text: ("\(i)"))) { cell, model in cell.textLabel?.text = model.text }
model: FooModel(text: ("\(i)"))
) { cell, model in cell.textLabel?.text = model.text }
elements.append(item)
}
return elements
Expand All @@ -53,8 +56,3 @@ class ViewController: UIViewController, UITableViewDelegate {
tableView.elements = newElements
}
}





4 changes: 4 additions & 0 deletions src/AdapterType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ public protocol AdapterType {

/// Returns the element currently on the front buffer at the given index path.
func displayedElement(at index: Int) -> Type

/// The total number of elements currently displayed.
func countDisplayedElements() -> Int

/// Replace the elements buffer and compute the diffs.
/// - parameter newValues: The new values.
/// - parameter synchronous: Wether the filter, sorting and diff should be executed
/// synchronously or not.
/// - parameter completion: Code that will be executed once the buffer is updated.
func update(with values: [Type]?, synchronous: Bool, completion: (() -> Void)?)

/// The section index associated with this adapter.
var sectionIndex: Int { get set }

/// The target view.
var view: ViewType? { get }

Expand Down
61 changes: 35 additions & 26 deletions src/AnyListItem.swift
Original file line number Diff line number Diff line change
@@ -1,64 +1,73 @@
import Foundation

public protocol ListContainerView: class { }
public protocol ListViewCell: class { }
public protocol ListContainerView: class {}
public protocol ListViewCell: class {}

#if os(iOS)
import UIKit
extension UITableView: ListContainerView { }
extension UICollectionView: ListContainerView { }
extension UITableViewCell: ListViewCell { }
extension UICollectionViewCell: ListViewCell { }
extension UITableView: ListContainerView {}
extension UICollectionView: ListContainerView {}
extension UITableViewCell: ListViewCell {}
extension UICollectionViewCell: ListViewCell {}
#endif

public protocol ListItemType: Diffable {
/// The reuse identifier for the cell passed as argument.
var reuseIdentifier: String { get set }

/// The TableView, or the CollectionView that will own this element.
var referenceView: ListContainerView? { get }

/// A opaque pointer to the model associated to this row.
var modelRef: Any? { get }

/// Configure the cell with the current item.
func configure(cell: ListViewCell)
}

public class ListItem<T: Diffable>: ListItemType, CustomDebugStringConvertible {
/// The cell reuse identifier.
public var reuseIdentifier: String

/// The unique identifier (used for the diffing algorithm).
public var diffIdentifier: String { return "\(reuseIdentifier)_\(model.diffIdentifier)" }

/// The *UICollectionView/UITableView* associated to this item.
public weak var referenceView: ListContainerView?

/// The actual model object.
public var model: T

/// A opaque pointer to the model associated to this row.
public var modelRef: Any? { return self.model }

/// A textual representation of this instance, suitable for debugging.
public var debugDescription: String { return self.diffIdentifier }

/// The configuration block applied to the target cell.
public var cellConfiguration: ((ListViewCell, T) -> Void)?

#if os(iOS)
public init<V: PrototypeViewCell>(
type: V.Type,
container: ListContainerView,
reuseIdentifer: String = String(describing: V.self),
model: T,
configurationClosure: ((V, T) -> Void)? = nil
) {
// Registers the prototype cell if necessary.
if !Prototypes.isPrototypeCellRegistered(reuseIdentifer) {
let cell = V(reuseIdentifier: reuseIdentifer)
Prototypes.registerPrototypeCell(reuseIdentifer, cell: cell)
}
self.reuseIdentifier = reuseIdentifer
if let closure = configurationClosure {
self.cellConfiguration = { cell, type in return closure(cell as! V, type) }
public init<V: PrototypeViewCell>(
type: V.Type,
container: ListContainerView,
reuseIdentifer: String = String(describing: V.self),
model: T,
configurationClosure: ((V, T) -> Void)? = nil
) {
// Registers the prototype cell if necessary.
if !Prototypes.isPrototypeCellRegistered(reuseIdentifer) {
let cell = V(reuseIdentifier: reuseIdentifer)
Prototypes.registerPrototypeCell(reuseIdentifer, cell: cell)
}
self.reuseIdentifier = reuseIdentifer
if let closure = configurationClosure {
self.cellConfiguration = { cell, type in return closure(cell as! V, type) }
}
self.referenceView = container
self.model = model
self.registerReferenceView(with: type)
}
self.referenceView = container
self.model = model
self.registerReferenceView(with: type)
}
#endif

public init<V: ListViewCell>(
Expand Down Expand Up @@ -91,6 +100,6 @@ public class ListItem<T: Diffable>: ListItemType, CustomDebugStringConvertible {

/// Bind the cell passed as argument to this data item.
public func configure(cell: ListViewCell) {
self.cellConfiguration?(cell, self.model)
self.cellConfiguration?(cell, self.model)
}
}
41 changes: 28 additions & 13 deletions src/Buffer.swift
Original file line number Diff line number Diff line change
@@ -1,60 +1,76 @@
import Foundation

public protocol BufferType { }
public protocol BufferType {}

public protocol BufferDelegate: class {
/// Notifies the receiver that the content is about to change.
func buffer(willChangeContent buffer: BufferType)

/// Notifies the receiver that rows were deleted.
func buffer(didDeleteElementAtIndices buffer: BufferType, indices: [UInt])

/// Notifies the receiver that rows were inserted.
func buffer(didInsertElementsAtIndices buffer: BufferType, indices: [UInt])

/// Notifies the receiver that an element has been moved to a different position.
func buffer(didMoveElement buffer: BufferType, from: UInt, to: UInt)

/// Notifies the receiver that the content updates has ended.
func buffer(didChangeContent buffer: BufferType)

/// Notifies the receiver that the content updates has ended.
/// This callback method is called when the number of changes are too many to be
/// handled for the UI thread - it's recommendable to just reload the whole data in this case.
/// - Note: The 'diffThreshold' property in 'Buffer' defines what is the maximum number
/// of changes
/// that you want the receiver to be notified for.
func buffer(didChangeAllContent buffer: BufferType)

/// Called when one of the observed properties for this object changed.
func buffer(didChangeElementAtIndex buffer: BufferType, index: UInt)
}

public class Buffer<E: Diffable>: NSObject, BufferType {
/// The object that will get notified every time chavbcnges occures to the array.
public weak var delegate: BufferDelegate?

/// The elements in the array observer's buffer.
public var currentElements: [E] {
return self.frontBuffer
}

/// Defines what is the maximum number of changes that you want the receiver to be notified for.
/// - note: If the number of changes exceeds this number, *buffer(didChangeAllContent:)* is going
/// to be invoked instead.
public var diffThreshold = 100

/// If set to 'true' the LCS algorithm is run synchronously on the main thread.
private var synchronous: Bool = false

/// The exposed array.
private var frontBuffer = [E]()

/// The internal array.
private var backBuffer = [E]()

/// Sort closure.
private var sort: ((E, E) -> Bool)?

/// Filter closure.
private var filter: ((E) -> Bool)?

/// The serial operation queue for this controller.
private let serialOperationQueue: OperationQueue = {
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 1
return operationQueue
}()

/// Internal state flags.
private var flags = (
isRefreshing: false,
shouldRefresh: false)
shouldRefresh: false
)

/// Constructs a new buffer instance.
public init(
Expand All @@ -72,7 +88,7 @@ public class Buffer<E: Diffable>: NSObject, BufferType {
with values: [E]? = nil,
synchronous: Bool = false,
completion: (() -> Void)? = nil
) -> Void {
) {
// Should be called on the main thread.
assert(Thread.isMainThread)
let new = values ?? self.frontBuffer
Expand All @@ -97,8 +113,9 @@ public class Buffer<E: Diffable>: NSObject, BufferType {
}
// Compute the diffing.
let diff = Diff.diffing(
oldArray: self.frontBuffer.map { $0.diffIdentifier},
newArray: backBuffer.map { $0.diffIdentifier }) {
oldArray: self.frontBuffer.map { $0.diffIdentifier },
newArray: backBuffer.map { $0.diffIdentifier }
) {
return $0 == $1
}
// Update the front buffer on the main thread.
Expand Down Expand Up @@ -137,14 +154,14 @@ public class Buffer<E: Diffable>: NSObject, BufferType {

//MARK: Dispatch Helpers

private extension Buffer {
extension Buffer {
/// Dispatches the block passed as argument on the main thread.
/// - parameter synchronous: If true the block is going to be called on the current call stack.
/// - parameter block: The block that is going to be executed.
func dispatchOnMainThread(
fileprivate func dispatchOnMainThread(
synchronous: Bool = false,
block: @escaping () -> Void
) -> Void {
) {
if synchronous {
assert(Thread.isMainThread)
block()
Expand All @@ -156,13 +173,14 @@ private extension Buffer {
DispatchQueue.main.async(execute: block)
}
}

/// Dispatches the block passed as argument on the ad-hoc serial queue (if necesary).
/// - parameter synchronous: If true the block is going to be called on the current call stack.
/// - parameter block: The block that is going to be executed.
func dispatchOnSerialQueue(
fileprivate func dispatchOnSerialQueue(
synchronous: Bool = false,
block: @escaping () -> Void
) -> Void {
) {
if synchronous {
block()
return
Expand All @@ -172,6 +190,3 @@ private extension Buffer {
}
}
}



Loading

0 comments on commit f713382

Please sign in to comment.