Merge branch 'dev_arch_opt_3.0' into dev_robosweeper-d_app-module_221230_1.1.0
This commit is contained in:
@@ -55,4 +55,11 @@ object CallerDevaToolsListenerManager : CallerBase<IMoGoDevaToolsListener>() {
|
||||
}
|
||||
}
|
||||
|
||||
fun invokeMoFangStatus(status:Boolean){
|
||||
M_LISTENERS.forEach {
|
||||
val listener = it.value
|
||||
listener.mofangStatus(status)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -147,6 +147,13 @@ object CallerDevaToolsManager {
|
||||
devaToolsProviderApi?.downLoadPackage(downloadKey, downloadUrl)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新下载进度
|
||||
*/
|
||||
fun updateUpgradeProgress() {
|
||||
devaToolsProviderApi?.updateUpgradeProgress()
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示状态栏
|
||||
*/
|
||||
|
||||
@@ -212,11 +212,4 @@ object CallerHmiManager {
|
||||
hmiProviderApi?.updateStatusBarDownloadView(insert, tag, progress)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新魔方的链接状态
|
||||
*/
|
||||
fun updateMfStatusView(tag: String, status: Boolean) {
|
||||
hmiProviderApi?.updateMfStatus(tag, status)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,8 +45,4 @@ object CallerHmiViewControlListenerManager : CallerBase<IViewControlListener>()
|
||||
M_LISTENERS[tag]?.updateStatusBarDownloadView(insert, tag, progress)
|
||||
}
|
||||
|
||||
fun updateMfStatus(tag: String, viewTag: String, status: Boolean) {
|
||||
M_LISTENERS[tag]?.updateMfStatus(viewTag, status)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.mogo.eagle.core.function.call.map
|
||||
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_IDENTIFY
|
||||
import com.mogo.eagle.core.function.api.map.marker.IMoGoIdentifyListener
|
||||
import com.mogo.eagle.core.function.call.base.CallerBase
|
||||
import mogo.telematics.pad.MessagePad
|
||||
|
||||
object CallerMapIdentifyManager : CallerBase<IMoGoIdentifyListener>() {
|
||||
|
||||
private val identifyApi: IMoGoIdentifyListener
|
||||
get() = ARouter.getInstance().build(PATH_IDENTIFY)
|
||||
.navigation() as IMoGoIdentifyListener
|
||||
|
||||
fun getIdentifyObj(uuid: String): MessagePad.TrackedObject? {
|
||||
return identifyApi.getIdentifyObj(uuid)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,8 +30,8 @@ object CallerMapUIServiceManager {
|
||||
return serviceProvider?.markerService
|
||||
}
|
||||
|
||||
fun getOverlayManager(context: Context): IMogoOverlayManager?{
|
||||
return serviceProvider?.getOverlayManager(context)
|
||||
fun getOverlayManager(): IMogoOverlayManager?{
|
||||
return serviceProvider?.overlayManager
|
||||
}
|
||||
|
||||
fun getGDLocationServer(context: Context):IMogoGDLocationClient?{
|
||||
|
||||
@@ -1,388 +1,24 @@
|
||||
package com.mogo.eagle.core.function.call.map
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.SystemClock
|
||||
import android.util.*
|
||||
import androidx.lifecycle.Lifecycle.Event
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_DESTROY
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.map.*
|
||||
import com.mogo.eagle.core.data.map.MapRoadInfo.StopLine
|
||||
import com.mogo.eagle.core.function.call.autopilot.*
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager.OnRoadListener
|
||||
import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.*
|
||||
import com.mogo.eagle.core.utilcode.kotlin.lifeCycleOwner
|
||||
import com.mogo.eagle.core.utilcode.kotlin.safeCancel
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
|
||||
import com.mogo.map.uicontroller.VisualAngleMode
|
||||
import com.zhidaoauto.map.sdk.open.tools.MapTools
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.android.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.internal.synchronized
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeUnit.SECONDS
|
||||
import java.util.concurrent.atomic.*
|
||||
import kotlin.math.*
|
||||
import com.alibaba.android.arouter.launcher.*
|
||||
import com.mogo.eagle.core.data.constants.*
|
||||
import com.mogo.eagle.core.function.api.map.angle.*
|
||||
|
||||
|
||||
/**
|
||||
* 高精地图视角管理类
|
||||
*/
|
||||
object CallerVisualAngleManager {
|
||||
|
||||
private const val TAG = "VisualAngle"
|
||||
|
||||
@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(Handler(Looper.getMainLooper()).asCoroutineDispatcher("change-visual-angle") + SupervisorJob())
|
||||
private val provider by lazy { ARouter.getInstance().build(MogoServicePaths.PATH_VISUAL_ANGLE)
|
||||
.navigation() as? IMoGoVisualAngleChangeProvider
|
||||
}
|
||||
|
||||
private interface IAttach {
|
||||
val angle: VisualAngleMode
|
||||
val priority: Int
|
||||
val displayThreshold: Long //最大展示时长 > 0; 表示最长展示多长时间, -1 表示,一直展示,直到触发默认视角, 0: 默认视角专用值,
|
||||
fun changeAngle(scene: Scene) {
|
||||
provider?.changeAngle(scene)
|
||||
}
|
||||
|
||||
private val triggerLocation = AtomicReference<MogoLocation>()
|
||||
|
||||
private val distanceOfCarToStopLine = AtomicReference(0.0)
|
||||
|
||||
private val travelled by lazy { AtomicReference(0.0) }
|
||||
|
||||
private val listener = object : OnRoadListener {
|
||||
private val roadId = AtomicReference<String>()
|
||||
private val triggerRoadId = AtomicReference<String>()
|
||||
|
||||
override fun onRoadIdInfo(roadId: String) {
|
||||
this.roadId.set(roadId)
|
||||
Log.d(TAG, "-- onRoadIdInfo --: prev: ${this.triggerRoadId.get()} -> curr: $roadId")
|
||||
val loc = CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02()
|
||||
var triggerClose = false
|
||||
val distance = distanceOfCarToStopLine.get() + 5
|
||||
if (hasCrossRoad && distance > 0) {
|
||||
val prev = triggerLocation.get()
|
||||
if (prev != null && loc != null) {
|
||||
travelled.set(MapTools.distance(loc.longitude, loc.latitude, prev.longitude, prev.latitude) + travelled.get())
|
||||
triggerLocation.set(loc)
|
||||
}
|
||||
val oldRoadId = triggerRoadId.get()
|
||||
Log.d(TAG, "-- onRoadIdInfo --: travelled --: ${travelled.get()}")
|
||||
if ((travelled.get() > distance) && oldRoadId != null && oldRoadId != roadId) {
|
||||
distanceOfCarToStopLine.set(0.0)
|
||||
hasCrossRoad = false
|
||||
triggerRoadId.set(null)
|
||||
travelled.set(0.0)
|
||||
triggerLocation.set(null)
|
||||
Log.d(TAG, "-- onRoadIdInfo --: trigger close --")
|
||||
triggerClose = true
|
||||
}
|
||||
}
|
||||
if (triggerClose) {
|
||||
changeVisualAngle(CrossRoad(false))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onStopLineInfo(info: StopLine) {
|
||||
Log.d(TAG, "-- onStopLineInfo --: ${info.distanceOfCarToStopLine}")
|
||||
if (!hasCrossRoad && info.distanceOfCarToStopLine <= 30.0) {
|
||||
hasCrossRoad = true
|
||||
triggerRoadId.set(this.roadId.get())
|
||||
distanceOfCarToStopLine.set(info.distanceOfCarToStopLine)
|
||||
triggerLocation.set(CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02())
|
||||
changeVisualAngle(CrossRoad(true))
|
||||
}
|
||||
}
|
||||
fun updateLongSightLevel(level: Boolean) {
|
||||
provider?.updateLongSightLevel(level)
|
||||
}
|
||||
|
||||
fun init(ctx: Context) {
|
||||
if (Thread.currentThread() != Looper.getMainLooper().thread) {
|
||||
scope.launch {
|
||||
initListen(ctx)
|
||||
}
|
||||
} else {
|
||||
initListen(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initListen(ctx: Context) {
|
||||
ctx.lifeCycleOwner.lifecycle.addObserver(object : LifecycleEventObserver {
|
||||
override fun onStateChanged(source: LifecycleOwner, event: Event) {
|
||||
if (event == ON_DESTROY) {
|
||||
CallerMapRoadListenerManager.unRegisterRoadListener("VisualAngleChange")
|
||||
}
|
||||
}
|
||||
})
|
||||
CallerMapRoadListenerManager.registerRoadListener("VisualAngleChange", listener)
|
||||
}
|
||||
|
||||
sealed class Scene private constructor(): IAttach {
|
||||
|
||||
/**
|
||||
* 默认视图
|
||||
* @param delay: 表示多少稍后,默认值为2
|
||||
* @param unit: 时间单位,默认为秒
|
||||
*/
|
||||
class Default(val delay: Long = 2, val unit: TimeUnit = SECONDS): Scene() {
|
||||
|
||||
override val angle: VisualAngleMode = VisualAngleMode.MODE_MEDIUM_SIGHT
|
||||
|
||||
override val priority: Int = 1
|
||||
|
||||
override val displayThreshold: Long
|
||||
get() = 0
|
||||
|
||||
override fun toString(): String {
|
||||
return "Default(delay=$delay, unit=$unit, angle=$angle, priority=$priority)"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 变道-接收到转向灯信息号
|
||||
*/
|
||||
class Turning(var open: Boolean = false): Scene() {
|
||||
|
||||
override val angle: VisualAngleMode = VisualAngleMode.MAP_STYLE_VR_ANGLE_TOP
|
||||
|
||||
override val priority: Int = 3
|
||||
|
||||
override val displayThreshold: Long
|
||||
get() = -1
|
||||
|
||||
override fun toString(): String {
|
||||
return "Turning(open: ${open}, priority=$priority, displayThreshold: $displayThreshold, priority=$priority)"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 后方车辆离自车过近
|
||||
*/
|
||||
object TooClose: Scene() {
|
||||
|
||||
override val angle: VisualAngleMode = VisualAngleMode.MAP_STYLE_VR_ANGLE_300
|
||||
|
||||
override val priority: Int = 2
|
||||
|
||||
override val displayThreshold: Long
|
||||
get() = SECONDS.toMillis(8)
|
||||
|
||||
override fun toString(): String {
|
||||
return "TooClose(priority=$priority, displayThreshold: $displayThreshold, priority=$priority)"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 道路事件
|
||||
*/
|
||||
object RoadEvent: Scene() {
|
||||
|
||||
override val angle: VisualAngleMode = VisualAngleMode.MODE_LONG_SIGHT
|
||||
|
||||
override val priority: Int = 5
|
||||
|
||||
override val displayThreshold: Long
|
||||
get() = SECONDS.toMillis(8)
|
||||
|
||||
override fun toString(): String {
|
||||
return "RoadEvent(priority=${priority}, displayThreshold: ${displayThreshold}, priority=${priority})"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 十字路口
|
||||
*/
|
||||
class CrossRoad(var open: Boolean = false): Scene() {
|
||||
override val angle: VisualAngleMode = VisualAngleMode.MAP_STYLE_VR_ANGLE_CROSS
|
||||
override val priority: Int = 4
|
||||
override val displayThreshold: Long
|
||||
get() = -1
|
||||
|
||||
override fun toString(): String {
|
||||
return "CrossRoad(open: ${open}, priority=${priority}, displayThreshold: ${displayThreshold}, priority=${priority})"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 业务实体,不对外暴露
|
||||
* @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>()
|
||||
}
|
||||
|
||||
fun changeVisualAngle(current: Scene) {
|
||||
val appIdentityMode = FunctionBuildConfig.appIdentityMode
|
||||
if (AppIdentityModeUtils.isBus(appIdentityMode) && AppIdentityModeUtils.isPassenger(appIdentityMode)) {
|
||||
return
|
||||
}
|
||||
val triggerTime = SystemClock.elapsedRealtime()
|
||||
scope.launch {
|
||||
Log.d("${M_DEVA}${TAG}", "--- 1 ---")
|
||||
val displayed = getDisplayed()
|
||||
if (displayed == null) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- 2 ---")
|
||||
if (current is Turning) {
|
||||
if (!current.open) {
|
||||
changeVisualAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (current is CrossRoad) {
|
||||
if (!current.open) {
|
||||
changeVisualAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
doRealVisualAngleChange(triggerTime, current, null)
|
||||
} else {
|
||||
val prev = displayed.target
|
||||
Log.d("${M_DEVA}${TAG}", "--- 3 --- old: $prev -> cur: $current")
|
||||
val prevTriggerTime = displayed.triggerTime
|
||||
if (current !is Default && prev.priority > current.priority && (prev is RoadEvent || prev is TooClose)) {
|
||||
val displayDuration = triggerTime - prevTriggerTime
|
||||
Log.d("${M_DEVA}${TAG}", "--- 4 ---:场景[$prev], 已展示时长: duration: $displayDuration")
|
||||
if (displayDuration < prev.displayThreshold) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- 5 --- 场景[$prev]:仍在保护展示时长内,直接return")
|
||||
return@launch
|
||||
} else {
|
||||
Log.d("${M_DEVA}${TAG}", "--- 6 --- 场景[$prev]:已过保护展示时长,从展示的队列中移除,显示默认视角")
|
||||
queue -= displayed
|
||||
changeVisualAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (prev is Turning && current is Turning) {
|
||||
val isOpen = current.open
|
||||
if (!isOpen) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- 7 --- 场景[$current], 收到关闭通知")
|
||||
queue -= displayed
|
||||
changeVisualAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (prev is CrossRoad && current is CrossRoad) {
|
||||
val isOpen = current.open
|
||||
if (!isOpen) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- 8 --- old: $prev -> cur: $current")
|
||||
queue -= displayed
|
||||
changeVisualAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (prev.priority == current.priority) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- 9 --- 场景[$prev]正在展示,尚未收到关闭,优先级一致,直接return")
|
||||
return@launch
|
||||
}
|
||||
if (prev.priority > current.priority && prev.displayThreshold < 0) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- 10 --- 场景[$prev]正在展示,尚未收到关闭,场景,依然展示当前场景,直接return")
|
||||
return@launch
|
||||
}
|
||||
doRealVisualAngleChange(triggerTime, current, displayed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.doRealVisualAngleChange(triggerTime: Long, target: Scene, displayed: Record? = null) {
|
||||
if (target is Default) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- doRealVisualAngleChange --- 1 ---")
|
||||
displayed?.also {
|
||||
queue -= it
|
||||
}
|
||||
defaultDelayJob?.safeCancel()
|
||||
launch {
|
||||
val delay = target.unit.toMillis(target.delay)
|
||||
Log.d("${M_DEVA}${TAG}", "--- doRealVisualAngleChange --- 2 ---")
|
||||
delay(delay)
|
||||
Log.d("${M_DEVA}${TAG}", "--- doRealVisualAngleChange --- 3 ---")
|
||||
doChangeAngle(Record(target, triggerTime = triggerTime))
|
||||
}.also { itx ->
|
||||
itx.invokeOnCompletion {
|
||||
if (it is CancellationException) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- doRealVisualAngleChange --- 4 ---")
|
||||
}
|
||||
}
|
||||
defaultDelayJob = itx
|
||||
}
|
||||
} else {
|
||||
Log.d("${M_DEVA}${TAG}", "--- doRealVisualAngleChange --- 5 ---")
|
||||
defaultDelayJob?.safeCancel()
|
||||
if (displayed == null || displayed.target.priority <= target.priority) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- doRealVisualAngleChange --- 6 ---")
|
||||
displayed?.also {
|
||||
queue -= it
|
||||
}
|
||||
if (target is Turning) {
|
||||
if (!target.open) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- doRealVisualAngleChange --- 7 ---")
|
||||
changeVisualAngle(Default())
|
||||
return
|
||||
}
|
||||
}
|
||||
if (target is CrossRoad) {
|
||||
if (!target.open) {
|
||||
Log.d("${M_DEVA}${TAG}", "--- doRealVisualAngleChange --- 8 ---")
|
||||
changeVisualAngle(Default())
|
||||
return
|
||||
}
|
||||
}
|
||||
Log.d("${M_DEVA}${TAG}", "--- doRealVisualAngleChange --- 10 ---")
|
||||
doChangeAngle(Record(target, triggerTime = triggerTime))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InternalCoroutinesApi::class)
|
||||
private fun doChangeAngle(record: Record) {
|
||||
val angle = record.target.angle
|
||||
CallerMapUIServiceManager.getMapUIController()?.also {
|
||||
Log.d("${M_DEVA}${TAG}", "--- doChangeAngle ---: ${record.target}")
|
||||
if (record.target !is Default) {
|
||||
record.isDisplay = true
|
||||
synchronized(queue) {
|
||||
queue += record
|
||||
}
|
||||
}
|
||||
it.changeMapVisualAngle(angle, null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有正在展示的
|
||||
*/
|
||||
@Synchronized
|
||||
private fun getDisplayed() = queue.firstOrNull()
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user