Skip to content

Commit

Permalink
Migrated Navigator from Routes to NavigationRoutes
Browse files Browse the repository at this point in the history
  • Loading branch information
1ec5 committed Mar 11, 2022
1 parent b0770b7 commit 2bcd189
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 35 deletions.
17 changes: 8 additions & 9 deletions Sources/MapboxCoreNavigation/CoreNavigationNavigator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ class Navigator {
}

private lazy var routeCoordinator: RoutesCoordinator = {
.init(setRoutesHandler: { [weak self] routes, completion in
self?.navigator.setRoutesFor(routes) { result in
.init(setRoutesHandler: { [weak self] routes, legIndex, completion in
self?.navigator.setRoutesFor(routes, legIndex: legIndex) { result in
if result.isValue() {
let routeInfo = result.value as! RouteInfo
os_log("Navigator has been updated",
Expand Down Expand Up @@ -209,13 +209,12 @@ class Navigator {

// MARK: - Navigator Updates

func setRoutes(_ routes: Routes?, uuid: UUID, completion: @escaping (Result<RouteInfo, Error>) -> Void) {
if let routes = routes {
routeCoordinator.beginActiveNavigation(with: routes, uuid: uuid, completion: completion)
}
else {
routeCoordinator.endActiveNavigation(with: uuid, completion: completion)
}
func setRoutes(_ routes: NavigationRoutes, uuid: UUID, legIndex: UInt32, completion: @escaping (Result<RouteInfo, Error>) -> Void) {
routeCoordinator.beginActiveNavigation(with: routes, uuid: uuid, legIndex: legIndex, completion: completion)
}

func unsetRoutes(uuid: UUID, completion: @escaping (Result<RouteInfo, Error>) -> Void) {
routeCoordinator.endActiveNavigation(with: uuid, completion: completion)
}

func updateLocation(_ location: CLLocation, completion: @escaping (Bool) -> Void) {
Expand Down
17 changes: 11 additions & 6 deletions Sources/MapboxCoreNavigation/RouteController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,12 +256,17 @@ open class RouteController: NSObject {
}

let routeRequest = Directions().url(forCalculating: progress.routeOptions).absoluteString
let routes = Routes(routesResponse: routeJSONString,
routeIndex: 0,
legIndex: UInt32(progress.legIndex),
routesRequest: routeRequest)
// Based on MBNNRouteIndex.routeId documentation.
// FIXME: Distinguish onboard routes with “local@” prefix.
let routeResponseIdentifier = indexedRouteResponse.routeResponse.identifier ?? ""
let routeIndices = (indexedRouteResponse.routeResponse.routes ?? []).enumerated().map { index, route in
RouteIndex(routeId: "\(routeResponseIdentifier)#\(index)", indexInResponse: UInt32(index))
}
let navigationRouteResponse = NavigationRouteResponse(routeIndices: routeIndices, directionsResponse: routeJSONString, directionsRequest: routeRequest)
let primaryRouteIdentifier = "\(routeResponseIdentifier)#\(indexedRouteResponse.routeIndex)"
let navigationRoutes = NavigationRoutes(primaryRouteId: primaryRouteIdentifier, routes: [navigationRouteResponse])

sharedNavigator.setRoutes(routes, uuid: sessionUUID) { result in
sharedNavigator.setRoutes(navigationRoutes, uuid: sessionUUID, legIndex: UInt32(progress.legIndex)) { result in
completion?(result)
}
}
Expand Down Expand Up @@ -741,7 +746,7 @@ extension RouteController: Router {
}

private func removeRoutes(completion: ((Error?) -> Void)?) {
sharedNavigator.setRoutes(nil, uuid: sessionUUID) { result in
sharedNavigator.unsetRoutes(uuid: sessionUUID) { result in
switch result {
case .success:
completion?(nil)
Expand Down
11 changes: 7 additions & 4 deletions Sources/MapboxCoreNavigation/RoutesCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ final class RoutesCoordinator {
case activeNavigation(UUID)
}

typealias SetRoutesHandler = (Routes?, _ completion: @escaping (Result<RouteInfo, Error>) -> Void) -> Void
typealias SetRoutesHandler = (NavigationRoutes?, _ legIndex: UInt32, _ completion: @escaping (Result<RouteInfo, Error>) -> Void) -> Void

private struct ActiveNavigationSession {
let uuid: UUID
Expand All @@ -33,8 +33,10 @@ final class RoutesCoordinator {

/// - Parameters:
/// - uuid: The UUID of the current active guidances session. All reroutes should have the same uuid.
func beginActiveNavigation(with routes: Routes,
/// - legIndex: The index of the leg along which to begin navigating.
func beginActiveNavigation(with routes: NavigationRoutes,
uuid: UUID,
legIndex: UInt32,
completion: @escaping (Result<RouteInfo, Error>) -> Void) {
lock.lock()
if case .activeNavigation(let currentUUID) = state, currentUUID != uuid {
Expand All @@ -44,7 +46,7 @@ final class RoutesCoordinator {
state = .activeNavigation(uuid)
lock.unlock()

setRoutes(routes, completion)
setRoutes(routes, legIndex, completion)
}

/// - Parameters:
Expand All @@ -58,7 +60,8 @@ final class RoutesCoordinator {
}
state = .passiveNavigation
lock.unlock()
setRoutes(nil, completion)
// TODO: Is it safe to set the leg index to 0 when unsetting a route?
setRoutes(nil, 0, completion)
}
}

Expand Down
36 changes: 20 additions & 16 deletions Tests/MapboxCoreNavigationTests/RoutesCoordinatorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,57 @@ final class RoutesCoordinatorTests: TestCase {
func testNormalCase() {
let uuid = UUID()
runTestCases([
.init(routes: generateRoutes(), uuid: uuid, expectedResult: .success(())),
.init(routes: nil, uuid: uuid, expectedResult: .success(()))
.init(routes: generateRoutes(), uuid: uuid, routeIndex: 0, expectedResult: .success(())),
.init(routes: nil, uuid: uuid, routeIndex: 0, expectedResult: .success(()))
])
}

func testEndingOverriddenNavigation() {
let uuid1 = UUID()
let uuid2 = UUID()
runTestCases([
.init(routes: generateRoutes(), uuid: uuid1, expectedResult: .success(())),
.init(routes: generateRoutes(), uuid: uuid2, expectedResult: .success(())),
.init(routes: nil, uuid: uuid1, expectedResult: .failure(.endingInvalidActiveNavigation)),
.init(routes: generateRoutes(), uuid: uuid1, routeIndex: 0, expectedResult: .success(())),
.init(routes: generateRoutes(), uuid: uuid2, routeIndex: 0, expectedResult: .success(())),
.init(routes: nil, uuid: uuid1, routeIndex: 0, expectedResult: .failure(.endingInvalidActiveNavigation)),
])
}

func testReroutes() {
let uuid = UUID()
runTestCases([
.init(routes: generateRoutes(), uuid: uuid, expectedResult: .success(())),
.init(routes: generateRoutes(), uuid: uuid, expectedResult: .success(())),
.init(routes: nil, uuid: uuid, expectedResult: .success(())),
.init(routes: generateRoutes(), uuid: uuid, routeIndex: 0, expectedResult: .success(())),
.init(routes: generateRoutes(), uuid: uuid, routeIndex: 0, expectedResult: .success(())),
.init(routes: nil, uuid: uuid, routeIndex: 0, expectedResult: .success(())),
])
}
}

private extension RoutesCoordinatorTests {
func generateRoutes() -> Routes {
.init(routesResponse: UUID().uuidString, routeIndex: 0, legIndex: 0, routesRequest: "")
func generateRoutes() -> NavigationRoutes {
.init(primaryRouteId: UUID().uuidString, routes: [])
}

struct RoutesCoordinatorTestCase {
let routes: Routes?
let routes: NavigationRoutes?
let uuid: UUID
let routeIndex: UInt32
let expectedResult: Result<Void, RoutesCoordinatorError>

}

func runTestCases(_ testCases: [RoutesCoordinatorTestCase]) {
var expectedRoutes: Routes? = generateRoutes()
var expectedRoutes: NavigationRoutes? = generateRoutes()
var expectedRouteIndex = UInt32.max
var expectedResult: Result<RouteInfo, RoutesCoordinatorError>!

let handler: RoutesCoordinator.SetRoutesHandler = { routes, completion in
let handler: RoutesCoordinator.SetRoutesHandler = { routes, routeIndex, completion in
XCTAssertEqual(routes, expectedRoutes)
XCTAssertEqual(routeIndex, expectedRouteIndex)
completion(expectedResult.mapError { $0 as Error })
}

let coordinator = RoutesCoordinator { routes, completion in
handler(routes, completion)
let coordinator = RoutesCoordinator { routes, routeIndex, completion in
handler(routes, routeIndex, completion)
}

for testCase in testCases {
Expand All @@ -64,7 +67,8 @@ private extension RoutesCoordinatorTests {
expectedResult = testCase.expectedResult
.map { .init(alerts: []) }
expectedRoutes = routes
coordinator.beginActiveNavigation(with: routes, uuid: testCase.uuid) { result in
expectedRouteIndex = testCase.routeIndex
coordinator.beginActiveNavigation(with: routes, uuid: testCase.uuid, legIndex: testCase.routeIndex) { result in
switch (result, expectedResult) {
case (.success(let routeInfo), .success(let expectedRouteInfo)):
XCTAssertEqual(routeInfo, expectedRouteInfo)
Expand Down

0 comments on commit 2bcd189

Please sign in to comment.