Skip to content

Instantly share code, notes, and snippets.

@natecook1000
Forked from mzaks/SwiftCoRoutine.swift
Created March 15, 2017 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save natecook1000/570c5c7bf3490e593e8db1b5674eb9f0 to your computer and use it in GitHub Desktop.
Save natecook1000/570c5c7bf3490e593e8db1b5674eb9f0 to your computer and use it in GitHub Desktop.
A simple coroutine for swift
import Foundation
public class CoRoutine<T> {
private var index = 0
private var sequence : [T]
private var routine : (T)->()
private let step : Int?
private let deltaTime : TimeInterval?
private(set) public var isCanceled : Bool = false
private(set) public var isDone : Bool = false
public var operationQueue = OperationQueue.main
fileprivate init(sequence: [T], step : Int, routine : @escaping (T)->()) {
self.sequence = sequence
self.step = step
self.routine = routine
self.deltaTime = nil
}
fileprivate init(sequence: [T], deltaTime : TimeInterval, routine : @escaping (T)->()) {
self.sequence = sequence
self.step = nil
self.routine = routine
self.deltaTime = deltaTime
}
public func cancel(){
isCanceled = true
}
public func run(){
if isCanceled || isDone {
return
}
if let step = step {
let end = min(index + step, sequence.count)
for i in index..<end{
routine(sequence[i])
}
if end == sequence.count {
isDone = true
return
}
index = end
operationQueue.addOperation{
self.run()
}
} else if let deltaTime = deltaTime {
let now = CFAbsoluteTimeGetCurrent()
for i in index..<sequence.count {
routine(sequence[i])
index = i
if CFAbsoluteTimeGetCurrent() - now >= deltaTime {
operationQueue.addOperation{
self.run()
}
break
}
}
isDone = true
}
}
}
extension Array {
public func coRoutine(withStep step: Int, _ routine: @escaping (Iterator.Element) -> ()) -> CoRoutine<Iterator.Element>{
return CoRoutine(sequence: self, step: step, routine: routine)
}
public func coRoutine(withDeltaTime deltaTime: TimeInterval, _ routine: @escaping (Iterator.Element) -> ()) -> CoRoutine<Iterator.Element>{
return CoRoutine(sequence: self, deltaTime: deltaTime, routine: routine)
}
}
let coroutine = [1, 2, 3, 4].coRoutine(withStep: 3){
print($0)
}
coroutine.run()
let coroutine2 = ["a", "b", "c"].coRoutine(withDeltaTime: 0.00001){
print($0)
}
coroutine2.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment