diff --git a/app/src/main/java/eu/ztsh/garmin/Garmin.kt b/app/src/main/java/eu/ztsh/garmin/Garmin.kt index d6b3113..e9836d5 100644 --- a/app/src/main/java/eu/ztsh/garmin/Garmin.kt +++ b/app/src/main/java/eu/ztsh/garmin/Garmin.kt @@ -6,17 +6,13 @@ import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothSocket import android.util.Log import com.mapbox.navigation.ui.maneuver.model.Maneuver -import eu.ztsh.garmin.data.Direction +import eu.ztsh.garmin.data.DataCache import eu.ztsh.garmin.data.GarminMapper import eu.ztsh.garmin.data.ManeuverMapper -import eu.ztsh.garmin.data.OutAngle -import eu.ztsh.garmin.data.OutType -import eu.ztsh.garmin.data.State import java.io.IOException import java.util.* import java.util.concurrent.SynchronousQueue - @SuppressLint("MissingPermission") class Garmin( val context: MainActivity, @@ -26,7 +22,7 @@ class Garmin( private lateinit var connection: ConnectThread private lateinit var processing: ProcessingThread - private var stateCache: State = State() + private val cache = DataCache() fun start() { connection = ConnectThread() @@ -46,22 +42,24 @@ class Garmin( private inner class ProcessingThread(val maneuver: Maneuver) : Thread() { + override fun run() { - // TODO: check for equality before mapping! - send(ManeuverMapper.apply(maneuver)) + if (cache.hasChanged(maneuver)) { + cache.update(maneuver) + send(ManeuverMapper.apply(maneuver)) + } } fun send(incoming: eu.ztsh.garmin.data.State) { - if (stateCache.distance != incoming.distance) { + if (cache.hasChanged(incoming.distance)) { setDistance(incoming) } - if (stateCache.direction != incoming.direction) { - setDirection(stateCache) + if (cache.hasChanged(incoming.direction)) { + setDirection(incoming) } - stateCache = incoming + cache.update(incoming) } - private fun setLines(state: eu.ztsh.garmin.data.State) { } @@ -94,10 +92,13 @@ class Garmin( sleep(3000) readAll() while (true) { - val newCurrent = Optional.ofNullable(queue.poll()).orElse(current) - current = newCurrent + val newCurrent = queue.poll() + if (newCurrent == null) { + sleep(500) + } else { + current = newCurrent + } send(current) - sleep(900) } } @@ -138,6 +139,7 @@ class Garmin( } companion object { + fun prepareData(input: IntArray): IntArray { val n = input.size var crc = (0xeb + n + n).toUInt() diff --git a/app/src/main/java/eu/ztsh/garmin/MapboxToolbox.kt b/app/src/main/java/eu/ztsh/garmin/MapboxToolbox.kt index 7afeffe..8711206 100644 --- a/app/src/main/java/eu/ztsh/garmin/MapboxToolbox.kt +++ b/app/src/main/java/eu/ztsh/garmin/MapboxToolbox.kt @@ -1,6 +1,8 @@ package eu.ztsh.garmin import android.annotation.SuppressLint +import android.location.Location +import android.util.Log import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner @@ -8,6 +10,8 @@ import com.mapbox.navigation.base.formatter.DistanceFormatterOptions import com.mapbox.navigation.base.options.NavigationOptions import com.mapbox.navigation.core.formatter.MapboxDistanceFormatter import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp +import com.mapbox.navigation.core.trip.session.LocationMatcherResult +import com.mapbox.navigation.core.trip.session.LocationObserver import com.mapbox.navigation.core.trip.session.RouteProgressObserver import com.mapbox.navigation.ui.maneuver.api.MapboxManeuverApi @@ -43,10 +47,13 @@ class MapboxToolbox(lifecycle: Lifecycle, private val context: MainActivity) { fun onStart() { MapboxNavigationApp.current()?.registerRouteProgressObserver(routeProgressObserver) + MapboxNavigationApp.current()?.registerLocationObserver(locationObserver) +// MapboxNavigationApp.current()?.registerNavigationSessionStateObserver() } fun onStop() { MapboxNavigationApp.current()?.unregisterRouteProgressObserver(routeProgressObserver) + MapboxNavigationApp.current()?.unregisterLocationObserver(locationObserver) } fun onDestroy() { @@ -64,6 +71,21 @@ class MapboxToolbox(lifecycle: Lifecycle, private val context: MainActivity) { } private val routeProgressObserver = - RouteProgressObserver { routeProgress -> maneuverApi.getManeuvers(routeProgress).value?.apply { context.garmin.process(this[0]) } } + RouteProgressObserver { routeProgress -> + maneuverApi.getManeuvers(routeProgress).value?.apply { + context.garmin.process( + this[0] + ) + } + } + + private val locationObserver = object : LocationObserver { + override fun onNewLocationMatcherResult(locationMatcherResult: LocationMatcherResult) { + Log.d("LOCATION", "") + } + + override fun onNewRawLocation(rawLocation: Location) { + } + } } \ No newline at end of file diff --git a/app/src/main/java/eu/ztsh/garmin/data/DataCache.kt b/app/src/main/java/eu/ztsh/garmin/data/DataCache.kt new file mode 100644 index 0000000..1b7eb16 --- /dev/null +++ b/app/src/main/java/eu/ztsh/garmin/data/DataCache.kt @@ -0,0 +1,66 @@ +package eu.ztsh.garmin.data + +import com.mapbox.navigation.ui.maneuver.model.Maneuver + +class DataCache { + + private val stateCache: State = State() + private var maneuverCache: Maneuver? = null + + // state + fun hasChanged(lanes: Lanes?): Boolean { + return stateCache.lineArrows == null || stateCache.lineArrows != lanes + } + + fun hasChanged(outlines: Outlines?): Boolean { + return stateCache.lineOutlines == null || stateCache.lineOutlines != outlines + } + + fun hasChanged(distance: Distance?): Boolean { + return stateCache.distance == null || stateCache.distance != distance + } + + fun hasChanged(direction: Direction?): Boolean { + return stateCache.direction == null || stateCache.direction != direction + } + + fun hasChanged(speed: Speed?): Boolean { + return stateCache.speed == null || stateCache.speed != speed + } + + fun hasChanged(arrival: Arrival?): Boolean { + return stateCache.arrival == null || stateCache.arrival != arrival + } + + // Merge states + fun update(state: State) { + if (state.lineArrows != null) { + stateCache.lineArrows = state.lineArrows + } + if (state.lineOutlines != null) { + state.lineOutlines = state.lineOutlines + } + if (state.direction != null) { + stateCache.direction = state.direction + } + if (state.distance != null) { + stateCache.distance = state.distance + } + if (state.speed != null) { + stateCache.speed = state.speed + } + if (state.arrival != null) { + stateCache.arrival = state.arrival + } + } + + // maneuver + fun hasChanged(maneuver: Maneuver): Boolean { + return maneuverCache == null || maneuverCache!! != maneuver + } + + fun update(maneuver: Maneuver) { + maneuverCache = maneuver + } + +} \ No newline at end of file diff --git a/app/src/main/java/eu/ztsh/garmin/data/ManeuverMapper.kt b/app/src/main/java/eu/ztsh/garmin/data/ManeuverMapper.kt index 89f1996..fe75879 100644 --- a/app/src/main/java/eu/ztsh/garmin/data/ManeuverMapper.kt +++ b/app/src/main/java/eu/ztsh/garmin/data/ManeuverMapper.kt @@ -10,10 +10,12 @@ class ManeuverMapper { val state = State() maneuver.apply { this.primary.apply { + state.direction = Direction() when (this.type) { "roundabout" -> { - state.direction.out = OutType.RightRoundabout + state.direction!!.out = OutType.RightRoundabout } + "arrive" -> { state.flag = true } @@ -21,17 +23,18 @@ class ManeuverMapper { when (this.modifier) { "right" -> { when (this.type) { - "turn" -> state.direction.angle = OutAngle.Right + "turn" -> state.direction!!.angle = OutAngle.Right "roundabout" -> { when (this.degrees) { - 137.0 -> state.direction.angle = OutAngle.EasyRight + 137.0 -> state.direction!!.angle = OutAngle.EasyRight } } } } + "left" -> { when (this.type) { - "turn" -> state.direction.angle = OutAngle.Left + "turn" -> state.direction!!.angle = OutAngle.Left } } } @@ -39,13 +42,14 @@ class ManeuverMapper { this.stepDistance.apply { this.distanceRemaining?.apply { distanceFormatter.formatDistance(distanceRemaining!!).split(" ").apply { - state.distance = this[0].toInt() - state.unit = when (this[1]) { - "m" -> Unit.Metres - "km" -> Unit.Kilometres - else -> { - Unit.Any} - } + state.distance = Distance( + this[0].toInt(), + when (this[1]) { + "m" -> Unit.Metres + "km" -> Unit.Kilometres + else -> Unit.Any + } + ) } } diff --git a/app/src/main/java/eu/ztsh/garmin/data/Model.kt b/app/src/main/java/eu/ztsh/garmin/data/Model.kt index 9092bbb..e4a8262 100644 --- a/app/src/main/java/eu/ztsh/garmin/data/Model.kt +++ b/app/src/main/java/eu/ztsh/garmin/data/Model.kt @@ -52,20 +52,64 @@ enum class Lane(val value: Int) { } +open class Arrows(val lanes: List) { + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Arrows + + return lanes == other.lanes + } + + override fun hashCode(): Int { + return lanes.hashCode() + } +} + +class Lanes(lanes: List) : Arrows(lanes) + +class Outlines(lanes: List) : Arrows(lanes) + +class Distance(val distance: Int, val unit: Unit) { + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Distance + + if (distance != other.distance) return false + if (unit != other.unit) return false + + return true + } + + override fun hashCode(): Int { + var result = distance + result = 31 * result + unit.hashCode() + return result + } + +} + +class Speed(val speed: Int, val limit: Int) + +class Arrival(val hours: Int, val minutes: Int) + class State { - var lineArrows: List = listOf() - var lineOutlines: List = listOf() - var direction = Direction() - var distance: Int = 0 - var unit: Unit = Unit.Any - var speed: Int = 0 - var limit: Int = 0 - var hours: Int = 0 - var minutes: Int = 0 - var traffic: Boolean = false - var flag: Boolean = false - var control: Boolean = false + var lineArrows: Lanes? = null + var lineOutlines: Outlines? = null + var direction : Direction? = null + var distance: Distance? = null + var speed: Speed? = null + var arrival: Arrival? = null + // TODO: support + var traffic: Boolean? = null + var flag: Boolean? = null + var control: Boolean? = null }