Skip to content

Commit

Permalink
Stub out more of the core for Android
Browse files Browse the repository at this point in the history
  • Loading branch information
ianthetechie committed Nov 12, 2023
1 parent 821c032 commit 28cd284
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,27 @@ import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import uniffi.ferrostar.GeographicCoordinates
import uniffi.ferrostar.NavigationController
import uniffi.ferrostar.NavigationControllerConfig
import uniffi.ferrostar.Route
import uniffi.ferrostar.RouteAdapter
import uniffi.ferrostar.RouteRequest
import uniffi.ferrostar.StepAdvanceMode
import uniffi.ferrostar.UserLocation
import java.net.URL
import java.util.concurrent.Executor
import java.util.concurrent.Executors

class FerrostarCore(
class FerrostarCoreException : Exception {
constructor(message: String) : super(message)
constructor(message: String, cause: Throwable) : super(message, cause)
constructor(cause: Throwable) : super(cause)
}

public class FerrostarCore(
val routeAdapter: RouteAdapter,
val locationProvider: LocationProvider,
val httpClient: OkHttpClient
) {
) : LocationUpdateListener {
private var navigationController: NavigationController? = null

constructor(
Expand Down Expand Up @@ -49,13 +59,42 @@ class FerrostarCore(
val res = httpClient.newCall(httpRequest).await()
val bodyBytes = res.body?.bytes()
if (!res.isSuccessful) {
TODO("Throw a useful exception")
throw FerrostarCoreException("Route request failed with status code ${res.code}")
} else if (bodyBytes == null) {
TODO("Throw a useful exception")
throw FerrostarCoreException("Route request was successful but had no body bytes")
}

return routeAdapter.parseResponse(bodyBytes)
}
}
}

fun startNavigation(route: Route, stepAdvance: StepAdvanceMode, startingLocation: UserLocation) {
// TODO: Is this the best executor?
locationProvider.addListener(this, Executors.newSingleThreadExecutor())

// TODO: Init view model
navigationController = NavigationController(
lastUserLocation = startingLocation,
route = route,
config = NavigationControllerConfig(stepAdvance = stepAdvance)
)
}

fun stopNavigation() {
navigationController = null
// TODO: Clear ViewModel
// TODO: Is this the best executor?
locationProvider.removeListener(this)
}

override fun onLocationUpdated(location: Location) {
// TODO: Update view model and navigation controller
TODO("Not yet implemented")
}

override fun onHeadingUpdated(heading: Float) {
// TODO: Update view model
TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,56 @@ package com.stadiamaps.ferrostar.core

import uniffi.ferrostar.CourseOverGround
import uniffi.ferrostar.GeographicCoordinates
import uniffi.ferrostar.UserLocation
import java.time.Instant
import java.util.concurrent.Executor

interface Location {
val coordinates: GeographicCoordinates
val horizontalAccuracy: Float
val horizontalAccuracy: Double
val courseOverGround: CourseOverGround?
val timestamp: Instant

fun userLocation(): UserLocation = UserLocation(
coordinates = coordinates,
horizontalAccuracy = horizontalAccuracy,
courseOverGround,
timestamp = timestamp
)
}

data class SimulatedLocation(
override val coordinates: GeographicCoordinates,
override val horizontalAccuracy: Float,
override val courseOverGround: CourseOverGround?
override val horizontalAccuracy: Double,
override val courseOverGround: CourseOverGround?,
override val timestamp: Instant
) : Location

// TODO: Decide if we want to have a compile-time dependency on Android
data class AndroidLocation(
override val coordinates: GeographicCoordinates,
override val horizontalAccuracy: Float,
override val courseOverGround: CourseOverGround?
override val horizontalAccuracy: Double,
override val courseOverGround: CourseOverGround?,
override val timestamp: Instant
) : Location {
constructor(location: android.location.Location) : this(
GeographicCoordinates(location.latitude, location.longitude),
location.accuracy,
location.accuracy.toDouble(),
if (location.hasBearing() && location.hasBearingAccuracy()) {
CourseOverGround(
location.bearing.toInt().toUShort(),
location.bearingAccuracyDegrees.toInt().toUShort()
)
} else {
null
}
},
Instant.ofEpochMilli(location.time)
)
}

interface LocationProvider {
val lastLocation: Location?

// TODO: Decide how to handle this on Android
val lastHeading: Float?

Expand Down

0 comments on commit 28cd284

Please sign in to comment.