Last active
April 18, 2021 01:25
-
-
Save rlaguilar/ca6840d3ea85dad733d0901b18e1be20 to your computer and use it in GitHub Desktop.
RxSwift bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// MazeViewController.swift | |
// | |
import UIKit | |
import Foundation | |
import RxSwift | |
class MazeViewController: UIViewController { | |
var currentDisposable: Disposable? = nil | |
var maze: ReactiveMaze! | |
var currentIteration: Int = 0 | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
// Do any additional setup after loading the view, typically from a nib | |
} | |
@IBAction func generate(_ sender: Any) { | |
// cancel the current operation | |
self.currentDisposable?.dispose() | |
maze.cancel() | |
self.currentIteration += 1 | |
self.currentDisposable = self.maze.generate(iteration: self.currentIteration) | |
.concatMap({ | |
Observable.empty() | |
.delay(0.02, scheduler: MainScheduler.instance) | |
.startWith($0) | |
}) | |
.observeOn(MainScheduler.instance) | |
.subscribe({ (event) in | |
switch event { | |
case .completed: | |
break | |
case .error(let err): | |
print(error) | |
case .next(let mazePayload): | |
// draw the new room | |
guard self.currentIteration == mazePayload.iteration else { | |
fatalError() | |
} | |
// do something expensive with the payload in the Main thread | |
} | |
}) | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ReactiveMaze.swift | |
// | |
import Foundation | |
import RxSwift | |
/// Represents the state of a maze | |
class ReactiveMaze { | |
/// Maze explorer used to retreive the maze pieces | |
private let mazeExplorer: ReactiveMazeExplorer | |
/// Object used to downlaod the images for the rooms | |
private let imageDownloader: ReactiveImageDownloader | |
var currentIteration: Int = 0 | |
init(imageDownloader: ReactiveImageDownloader, mazeExplorer: ReactiveMazeExplorer) { | |
self.mazeExplorer = mazeExplorer | |
self.imageDownloader = imageDownloader | |
} | |
/// Cancel the current exploration | |
func cancel() { | |
self.currentIteration = -1 | |
self.mazeExplorer.cancel() | |
} | |
/// Starts exploring a new maze and retrieves its pieces. | |
/// | |
/// - Warning: If there's some explorarion in progress it will be canceled | |
/// - Returns: The pieces of the new maze | |
func generate(iteration: Int) -> Observable<MazePayload> { | |
self.cancel() | |
self.currentIteration = iteration | |
let retrievedRoomsObservable = self.mazeExplorer.explore() // some observable with rooms | |
.concatMap { (room) -> Observable<RoomViewModel> in | |
// Retrieve the image for the received room | |
self.imageDownloader.retrieveImageData(fromUrl: room.tileUrl) | |
.map({ (data) -> RoomViewModel in | |
return RoomViewModel(room: room, withImageData: data) | |
}) | |
}.observeOn(MainScheduler.instance) | |
return retrievedRoomsObservable | |
.filter { _ in self.currentIteration == iteration } | |
.map { room in | |
return MazePayload(room: room, iteration: iteration) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment