Data cache

This commit is contained in:
Piotr Dec 2023-08-25 08:25:06 +02:00
parent 89e16fb805
commit b5cc580cf8
No known key found for this signature in database
GPG key ID: ABD6CB83D6110D27
5 changed files with 178 additions and 40 deletions

View file

@ -6,17 +6,13 @@ import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket import android.bluetooth.BluetoothSocket
import android.util.Log import android.util.Log
import com.mapbox.navigation.ui.maneuver.model.Maneuver 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.GarminMapper
import eu.ztsh.garmin.data.ManeuverMapper 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.io.IOException
import java.util.* import java.util.*
import java.util.concurrent.SynchronousQueue import java.util.concurrent.SynchronousQueue
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
class Garmin( class Garmin(
val context: MainActivity, val context: MainActivity,
@ -26,7 +22,7 @@ class Garmin(
private lateinit var connection: ConnectThread private lateinit var connection: ConnectThread
private lateinit var processing: ProcessingThread private lateinit var processing: ProcessingThread
private var stateCache: State = State() private val cache = DataCache()
fun start() { fun start() {
connection = ConnectThread() connection = ConnectThread()
@ -46,22 +42,24 @@ class Garmin(
private inner class ProcessingThread(val maneuver: Maneuver) : Thread() { private inner class ProcessingThread(val maneuver: Maneuver) : Thread() {
override fun run() { override fun run() {
// TODO: check for equality before mapping! if (cache.hasChanged(maneuver)) {
cache.update(maneuver)
send(ManeuverMapper.apply(maneuver)) send(ManeuverMapper.apply(maneuver))
} }
}
fun send(incoming: eu.ztsh.garmin.data.State) { fun send(incoming: eu.ztsh.garmin.data.State) {
if (stateCache.distance != incoming.distance) { if (cache.hasChanged(incoming.distance)) {
setDistance(incoming) setDistance(incoming)
} }
if (stateCache.direction != incoming.direction) { if (cache.hasChanged(incoming.direction)) {
setDirection(stateCache) setDirection(incoming)
} }
stateCache = incoming cache.update(incoming)
} }
private fun setLines(state: eu.ztsh.garmin.data.State) { private fun setLines(state: eu.ztsh.garmin.data.State) {
} }
@ -94,10 +92,13 @@ class Garmin(
sleep(3000) sleep(3000)
readAll() readAll()
while (true) { while (true) {
val newCurrent = Optional.ofNullable(queue.poll()).orElse(current) val newCurrent = queue.poll()
if (newCurrent == null) {
sleep(500)
} else {
current = newCurrent current = newCurrent
}
send(current) send(current)
sleep(900)
} }
} }
@ -138,6 +139,7 @@ class Garmin(
} }
companion object { companion object {
fun prepareData(input: IntArray): IntArray { fun prepareData(input: IntArray): IntArray {
val n = input.size val n = input.size
var crc = (0xeb + n + n).toUInt() var crc = (0xeb + n + n).toUInt()

View file

@ -1,6 +1,8 @@
package eu.ztsh.garmin package eu.ztsh.garmin
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.location.Location
import android.util.Log
import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner 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.base.options.NavigationOptions
import com.mapbox.navigation.core.formatter.MapboxDistanceFormatter import com.mapbox.navigation.core.formatter.MapboxDistanceFormatter
import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp 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.core.trip.session.RouteProgressObserver
import com.mapbox.navigation.ui.maneuver.api.MapboxManeuverApi import com.mapbox.navigation.ui.maneuver.api.MapboxManeuverApi
@ -43,10 +47,13 @@ class MapboxToolbox(lifecycle: Lifecycle, private val context: MainActivity) {
fun onStart() { fun onStart() {
MapboxNavigationApp.current()?.registerRouteProgressObserver(routeProgressObserver) MapboxNavigationApp.current()?.registerRouteProgressObserver(routeProgressObserver)
MapboxNavigationApp.current()?.registerLocationObserver(locationObserver)
// MapboxNavigationApp.current()?.registerNavigationSessionStateObserver()
} }
fun onStop() { fun onStop() {
MapboxNavigationApp.current()?.unregisterRouteProgressObserver(routeProgressObserver) MapboxNavigationApp.current()?.unregisterRouteProgressObserver(routeProgressObserver)
MapboxNavigationApp.current()?.unregisterLocationObserver(locationObserver)
} }
fun onDestroy() { fun onDestroy() {
@ -64,6 +71,21 @@ class MapboxToolbox(lifecycle: Lifecycle, private val context: MainActivity) {
} }
private val routeProgressObserver = 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) {
}
}
} }

View file

@ -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
}
}

View file

@ -10,10 +10,12 @@ class ManeuverMapper {
val state = State() val state = State()
maneuver.apply { maneuver.apply {
this.primary.apply { this.primary.apply {
state.direction = Direction()
when (this.type) { when (this.type) {
"roundabout" -> { "roundabout" -> {
state.direction.out = OutType.RightRoundabout state.direction!!.out = OutType.RightRoundabout
} }
"arrive" -> { "arrive" -> {
state.flag = true state.flag = true
} }
@ -21,17 +23,18 @@ class ManeuverMapper {
when (this.modifier) { when (this.modifier) {
"right" -> { "right" -> {
when (this.type) { when (this.type) {
"turn" -> state.direction.angle = OutAngle.Right "turn" -> state.direction!!.angle = OutAngle.Right
"roundabout" -> { "roundabout" -> {
when (this.degrees) { when (this.degrees) {
137.0 -> state.direction.angle = OutAngle.EasyRight 137.0 -> state.direction!!.angle = OutAngle.EasyRight
} }
} }
} }
} }
"left" -> { "left" -> {
when (this.type) { 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.stepDistance.apply {
this.distanceRemaining?.apply { this.distanceRemaining?.apply {
distanceFormatter.formatDistance(distanceRemaining!!).split(" ").apply { distanceFormatter.formatDistance(distanceRemaining!!).split(" ").apply {
state.distance = this[0].toInt() state.distance = Distance(
state.unit = when (this[1]) { this[0].toInt(),
when (this[1]) {
"m" -> Unit.Metres "m" -> Unit.Metres
"km" -> Unit.Kilometres "km" -> Unit.Kilometres
else -> { else -> Unit.Any
Unit.Any}
} }
)
} }
} }

View file

@ -52,20 +52,64 @@ enum class Lane(val value: Int) {
} }
open class Arrows(val lanes: List<Lane>) {
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<Lane>) : Arrows(lanes)
class Outlines(lanes: List<Lane>) : 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 { class State {
var lineArrows: List<Lane> = listOf() var lineArrows: Lanes? = null
var lineOutlines: List<Lane> = listOf() var lineOutlines: Outlines? = null
var direction = Direction() var direction : Direction? = null
var distance: Int = 0 var distance: Distance? = null
var unit: Unit = Unit.Any var speed: Speed? = null
var speed: Int = 0 var arrival: Arrival? = null
var limit: Int = 0 // TODO: support
var hours: Int = 0 var traffic: Boolean? = null
var minutes: Int = 0 var flag: Boolean? = null
var traffic: Boolean = false var control: Boolean? = null
var flag: Boolean = false
var control: Boolean = false
} }