[6.5.0][视角切换] 代码重构+添加场景变化回调
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
package com.mogo.eagle.core.function.angle
|
||||
|
||||
import android.content.*
|
||||
import android.os.*
|
||||
import android.util.*
|
||||
@@ -7,27 +6,25 @@ import androidx.lifecycle.*
|
||||
import androidx.lifecycle.Lifecycle.Event
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_DESTROY
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.data.map.*
|
||||
import com.mogo.eagle.core.function.angle.scenes.CrossRoad
|
||||
import com.mogo.eagle.core.function.angle.scenes.Default
|
||||
import com.mogo.eagle.core.function.angle.scenes.RoadEvent
|
||||
import com.mogo.eagle.core.function.api.map.angle.*
|
||||
import com.mogo.eagle.core.function.api.map.angle.IMoGoVisualAngleChangeProvider.OnMoGoVisualAngleSceneChangeListener
|
||||
import com.mogo.eagle.core.function.api.map.angle.Scene
|
||||
import com.mogo.eagle.core.function.api.map.road.IMoGoMapRoadListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.*
|
||||
import com.mogo.eagle.core.function.call.map.*
|
||||
import com.mogo.eagle.core.utilcode.kotlin.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.zhidaoauto.map.data.road.StopLine
|
||||
import com.zhidaoauto.map.sdk.open.MapAutoApi
|
||||
import com.zhidaoauto.map.sdk.open.common.tools.MapTools
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
import kotlinx.coroutines.android.asCoroutineDispatcher
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.atomic.*
|
||||
|
||||
|
||||
@Route(path = MogoServicePaths.PATH_VISUAL_ANGLE)
|
||||
class MoGoVisualAngleChangeProvider: IMoGoVisualAngleChangeProvider {
|
||||
|
||||
@@ -35,31 +32,15 @@ class MoGoVisualAngleChangeProvider: IMoGoVisualAngleChangeProvider {
|
||||
private const val TAG = "VisualAngleChange"
|
||||
}
|
||||
|
||||
private val listeners by lazy { ConcurrentHashMap<String, ArrayList<OnMoGoVisualAngleSceneChangeListener>>() }
|
||||
|
||||
private val triggerLocation = AtomicReference<MogoLocation>()
|
||||
|
||||
private val distanceOfCarToStopLine = AtomicReference(0.0)
|
||||
|
||||
private val travelled by lazy { AtomicReference(0.0) }
|
||||
|
||||
@Volatile
|
||||
private var roadEventFlag = false
|
||||
|
||||
/**
|
||||
* 业务实体,不对外暴露
|
||||
* @param target: 目标场景
|
||||
* @param isDisplay: 是否正在展示
|
||||
* @param triggerTime: 触发时间
|
||||
*/
|
||||
private data class Record(val target: Scene, var isDisplay: Boolean = false, var triggerTime: Long): Comparable<Record> {
|
||||
override fun compareTo(other: Record): Int {
|
||||
//如果时间一样,优先级越高,越靠近堆顶
|
||||
return other.target.priority - target.priority
|
||||
}
|
||||
}
|
||||
|
||||
private val queue by lazy {
|
||||
PriorityQueue<Record>()
|
||||
}
|
||||
private val prevScene by lazy { AtomicReference<Scene>() }
|
||||
|
||||
private val listener = object : IMoGoMapRoadListener {
|
||||
private val roadId = AtomicReference<String>()
|
||||
@@ -90,7 +71,7 @@ class MoGoVisualAngleChangeProvider: IMoGoVisualAngleChangeProvider {
|
||||
}
|
||||
}
|
||||
if (triggerClose) {
|
||||
changeAngle(CrossRoad(false))
|
||||
changeAngle(Default())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +83,7 @@ class MoGoVisualAngleChangeProvider: IMoGoVisualAngleChangeProvider {
|
||||
triggerRoadId.set(this.roadId.get())
|
||||
distanceOfCarToStopLine.set(info.distance)
|
||||
triggerLocation.set(CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02())
|
||||
changeAngle(CrossRoad(true))
|
||||
changeAngle(CrossRoad(2))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,24 +113,16 @@ class MoGoVisualAngleChangeProvider: IMoGoVisualAngleChangeProvider {
|
||||
@Volatile
|
||||
private var hasCrossRoad = false
|
||||
|
||||
|
||||
private var scope: CoroutineScope = acquireScope()
|
||||
@Synchronized
|
||||
get() {
|
||||
if (field.isActive) {
|
||||
return field
|
||||
}
|
||||
val scope = acquireScope()
|
||||
field = scope
|
||||
return field
|
||||
}
|
||||
|
||||
private var defaultDelayJob: Job? = null
|
||||
|
||||
private fun acquireScope(): CoroutineScope {
|
||||
return CoroutineScope(Executors.newSingleThreadExecutor().asCoroutineDispatcher() + SupervisorJob())
|
||||
val handler = HandlerThread("visual-angle-change").let { it.start(); Handler(it.looper) }
|
||||
return CoroutineScope(handler.asCoroutineDispatcher() + SupervisorJob())
|
||||
}
|
||||
|
||||
@Volatile
|
||||
private var prevJob: Job? = null
|
||||
|
||||
@Volatile
|
||||
private var mLevel:Boolean = false
|
||||
|
||||
@@ -161,146 +134,46 @@ class MoGoVisualAngleChangeProvider: IMoGoVisualAngleChangeProvider {
|
||||
if(mLevel){
|
||||
return
|
||||
}
|
||||
val triggerTime = SystemClock.elapsedRealtime()
|
||||
prevJob?.safeCancel()
|
||||
scope.launch {
|
||||
Log.d(TAG, "--- 1 ---")
|
||||
val displayed = getDisplayed()
|
||||
if (displayed == null) {
|
||||
Log.d(TAG, "--- 2 ---")
|
||||
if (scene is CrossRoad) {
|
||||
if (!scene.open) {
|
||||
changeAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
doRealVisualAngleChange(triggerTime, scene, null)
|
||||
} else {
|
||||
val prev = displayed.target
|
||||
Log.d(TAG, "--- 3 --- old: $prev -> cur: $scene")
|
||||
val prevTriggerTime = displayed.triggerTime
|
||||
if (scene !is Default && prev.priority > scene.priority && (prev is RoadEvent)) {
|
||||
val displayDuration = triggerTime - prevTriggerTime
|
||||
Log.d(TAG, "--- 4 ---:场景[$prev], 已展示时长: duration: $displayDuration")
|
||||
if (displayDuration < prev.displayThreshold) {
|
||||
Log.d(TAG, "--- 5 --- 场景[$prev]:仍在保护展示时长内,直接return")
|
||||
return@launch
|
||||
} else {
|
||||
Log.d(TAG, "--- 6 --- 场景[$prev]:已过保护展示时长,从展示的队列中移除,显示默认视角")
|
||||
queue -= displayed
|
||||
changeAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (prev is CrossRoad && scene is CrossRoad) {
|
||||
val isOpen = scene.open
|
||||
if (!isOpen) {
|
||||
Log.d(TAG, "--- 8 --- old: $prev -> cur: $scene")
|
||||
queue -= displayed
|
||||
changeAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (prev.priority == scene.priority) {
|
||||
Log.d(TAG, "--- 9 --- 场景[$prev]正在展示,尚未收到关闭,优先级一致,直接return")
|
||||
return@launch
|
||||
}
|
||||
if (prev.priority > scene.priority && prev.displayThreshold < 0) {
|
||||
Log.d(TAG, "--- 10 --- 场景[$prev]正在展示,尚未收到关闭,场景,依然展示当前场景,直接return")
|
||||
return@launch
|
||||
}
|
||||
doRealVisualAngleChange(triggerTime, scene, displayed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.doRealVisualAngleChange(triggerTime: Long, target: Scene, displayed: Record? = null) {
|
||||
if (target is Default) {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 1 ---")
|
||||
displayed?.also {
|
||||
queue -= it
|
||||
}
|
||||
defaultDelayJob?.safeCancel()
|
||||
launch {
|
||||
val delay = target.unit.toMillis(target.delay)
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 2 ---")
|
||||
val delay = scene.delay
|
||||
if (delay > 0) {
|
||||
delay(delay)
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 3 ---")
|
||||
doChangeAngle(Record(target, triggerTime = triggerTime), displayed)
|
||||
}.also { itx ->
|
||||
itx.invokeOnCompletion {
|
||||
if (it is CancellationException) {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 4 ---")
|
||||
}
|
||||
}
|
||||
defaultDelayJob = itx
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 5 ---")
|
||||
defaultDelayJob?.safeCancel()
|
||||
if (displayed == null || displayed.target.priority <= target.priority) {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 6 ---")
|
||||
displayed?.also {
|
||||
queue -= it
|
||||
}
|
||||
if (target is CrossRoad) {
|
||||
if (!target.open) {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 8 ---")
|
||||
changeAngle(Default())
|
||||
return
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 10 ---")
|
||||
doChangeAngle(Record(target, triggerTime = triggerTime), displayed)
|
||||
}
|
||||
|
||||
doChangeAngle(scene)
|
||||
}.also {
|
||||
prevJob = it
|
||||
}
|
||||
}
|
||||
|
||||
private fun doChangeAngle(target: Record, previous: Record? = null) {
|
||||
val angle = target.target.angle
|
||||
private fun doChangeAngle(target: Scene) {
|
||||
val angle = target.angle
|
||||
CallerMapUIServiceManager.getMapUIController()?.also {
|
||||
Log.d(TAG, "--- doChangeAngle ---: ${target.target}")
|
||||
if (target.target !is Default) {
|
||||
target.isDisplay = true
|
||||
synchronized(queue) {
|
||||
queue += target
|
||||
}
|
||||
}
|
||||
if (target.target is Default && roadEventFlag) {
|
||||
roadEventFlag = false
|
||||
it.setLockMode(true)
|
||||
}
|
||||
if (target.target is RoadEvent) {
|
||||
//taxi乘客屏,使用的新地图效果,切了视角也看不到
|
||||
if (!AppIdentityModeUtils.isTaxiPassenger(FunctionBuildConfig.appIdentityMode)) {
|
||||
roadEventFlag = true
|
||||
it.setLockMode(false)
|
||||
/**
|
||||
* var center = mapAutoView.getCurrentLonLatPoint()
|
||||
* var target = LonLatPoint(112.57295762931203, 26.823537024568793)
|
||||
* var angle = MapAutoApi.getAngle(center.longitude,center.latitude,target.longitude,target.latitude)
|
||||
*/
|
||||
val isGps = target.target.isGps
|
||||
val car = if (isGps) CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() else CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02()
|
||||
val rotateAngle = MapAutoApi.getAngle(car.longitude, car.latitude, target.target.poi_lon, target.target.poi_lat)
|
||||
Log.d(TAG, "angle->:$rotateAngle")
|
||||
it.animateTo(0.0 ,0.0,1f, -rotateAngle,11.5f,12f,3000,target.target.isGps)
|
||||
}
|
||||
} else {
|
||||
if (target.target is Default && previous != null && (previous.target is RoadEvent)) {
|
||||
Log.d(TAG, "==== doChangeAngle === 1 ===")
|
||||
if (AppIdentityModeUtils.isTaxiPassenger(FunctionBuildConfig.appIdentityMode)) {
|
||||
Log.d(TAG, "==== doChangeAngle === 2 ===")
|
||||
return
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "--- doChangeAngle ---: $target")
|
||||
val prev = prevScene.get()
|
||||
try {
|
||||
it.changeMapVisualAngle(angle, null)
|
||||
} finally {
|
||||
if (prev == null || prev.javaClass != target.javaClass) {
|
||||
notifyChanged(target)
|
||||
}
|
||||
prevScene.set(target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有正在展示的
|
||||
*/
|
||||
@Synchronized
|
||||
private fun getDisplayed() = queue.firstOrNull()
|
||||
override fun addListener(tag: String, listener: OnMoGoVisualAngleSceneChangeListener) {
|
||||
listeners.getOrPut(tag) { ArrayList() }.takeIf { !it.contains(listener) }?.add(listener)
|
||||
}
|
||||
|
||||
override fun removeListener(tag: String) {
|
||||
listeners.remove(tag)
|
||||
}
|
||||
|
||||
private fun notifyChanged(scene: Scene) {
|
||||
for (listener in listeners.values.flatten()) {
|
||||
listener.onSceneChanged(scene)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_CROSS
|
||||
/**
|
||||
* 十字路口
|
||||
*/
|
||||
class CrossRoad(var open: Boolean = false): Scene {
|
||||
class CrossRoad(private val delayTime: Long): Scene {
|
||||
override val angle: VisualAngleMode
|
||||
get() = MAP_STYLE_VR_ANGLE_CROSS
|
||||
|
||||
@@ -15,7 +15,13 @@ class CrossRoad(var open: Boolean = false): Scene {
|
||||
override val displayThreshold: Long
|
||||
get() = -1
|
||||
|
||||
override val delay: Long
|
||||
get() = delayTime
|
||||
|
||||
override val isCanSwitch: Boolean
|
||||
get() = false
|
||||
|
||||
override fun toString(): String {
|
||||
return "CrossRoad(open: ${open}, priority=${priority}, displayThreshold: ${displayThreshold}, priority=${priority})"
|
||||
return "CrossRoad(delayTime=${delayTime}, priority=${priority}, displayThreshold: ${displayThreshold}, priority=${priority})"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.concurrent.TimeUnit
|
||||
* @param delay: 表示多少稍后,默认值为2
|
||||
* @param unit: 时间单位,默认为秒
|
||||
*/
|
||||
class Default(val delay: Long = 2, val unit: TimeUnit = TimeUnit.SECONDS): Scene {
|
||||
class Default(val delayTime: Long = 2, val unit: TimeUnit = TimeUnit.SECONDS): Scene {
|
||||
|
||||
override val angle: VisualAngleMode
|
||||
get() = CallerMapUIServiceManager.getMapUIController()?.getVrAngleDefaultMode() ?: MODE_MEDIUM_SIGHT
|
||||
@@ -21,6 +21,12 @@ class Default(val delay: Long = 2, val unit: TimeUnit = TimeUnit.SECONDS): Scene
|
||||
override val displayThreshold: Long
|
||||
get() = 0
|
||||
|
||||
override val delay: Long
|
||||
get() = unit.toMillis(delayTime)
|
||||
|
||||
override val isCanSwitch: Boolean
|
||||
get() = true
|
||||
|
||||
override fun toString(): String {
|
||||
return "Default(delay=$delay, unit=$unit, angle=$angle, priority=$priority)"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.mogo.eagle.core.function.angle.scenes
|
||||
|
||||
import com.mogo.eagle.core.function.api.map.angle.Scene
|
||||
import com.mogo.map.uicontroller.VisualAngleMode
|
||||
import com.mogo.map.uicontroller.VisualAngleMode.MODE_LONG_SIGHT
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class LongSight(private val delayTime: Long, private val unit: TimeUnit = TimeUnit.SECONDS): Scene {
|
||||
|
||||
override val angle: VisualAngleMode
|
||||
get() = MODE_LONG_SIGHT
|
||||
override val priority: Int
|
||||
get() = 0
|
||||
override val displayThreshold: Long
|
||||
get() = 0
|
||||
|
||||
override val delay: Long
|
||||
get() = unit.toMillis(delayTime)
|
||||
|
||||
override val isCanSwitch: Boolean
|
||||
get() = true
|
||||
}
|
||||
@@ -1,22 +1,30 @@
|
||||
package com.mogo.eagle.core.function.angle.scenes
|
||||
|
||||
import com.mogo.eagle.core.function.api.map.angle.Scene
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import com.mogo.map.uicontroller.VisualAngleMode
|
||||
import com.mogo.map.uicontroller.VisualAngleMode.MODE_MEDIUM_SIGHT
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* 道路事件
|
||||
*/
|
||||
class RoadEvent(val poi_lon: Double, val poi_lat: Double, val poi_angle: Double, val isGps: Boolean = true): Scene {
|
||||
class RoadEvent(private val delayTime: Long, private val unit: TimeUnit): Scene {
|
||||
|
||||
override val angle: VisualAngleMode = VisualAngleMode.MODE_LONG_SIGHT
|
||||
override val angle: VisualAngleMode = CallerMapUIServiceManager.getMapUIController()?.getVrAngleDefaultMode() ?: MODE_MEDIUM_SIGHT
|
||||
|
||||
override val priority: Int = 5
|
||||
|
||||
override val displayThreshold: Long
|
||||
get() = TimeUnit.SECONDS.toMillis(8)
|
||||
|
||||
override val delay: Long
|
||||
get() = unit.toMillis(delayTime)
|
||||
|
||||
override fun toString(): String {
|
||||
return "RoadEvent(priority=${priority}, displayThreshold: ${displayThreshold}, priority=${priority}, lon: $poi_lon, lat: $poi_lat, angle: $poi_angle)"
|
||||
return "RoadEvent(priority=${priority}, displayThreshold: ${displayThreshold}, priority=${priority}"
|
||||
}
|
||||
|
||||
override val isCanSwitch: Boolean
|
||||
get() = true
|
||||
}
|
||||
Reference in New Issue
Block a user