if (msg.getMessageTypeEnum() == MessageWrapperClass.MessageWrapper.MessageTypeEnum.MESSAGE_TYPE_ENTITY) {
EntityClass.Entity entity = msg.getMessageEntity();
Log.d(TAG, "Listener:run (thread): Entity received\"" + entity.toString());
// 0 deg points north, vertically in map
double heading = Math.atan2(
entity.getKinematics().getEastSpeed(),
entity.getKinematics().getNorthSpeed()) * 180.0 / Math.PI;
// Put to [0,360] range
if (heading < 0) {
heading += 360.0;
}
Position position = new Position(
heading,
entity.getKinematics().getPosition().getLatitudeDeg(),
entity.getKinematics().getPosition().getLongitudeDeg(),
entity.getKinematics().getPosition().getAltitudeHaeMeters(),
0.0);
HostileEntity unit = new HostileEntity(
Utils.TrimUUID(entity.getEntityID().getValue().toString()),
//todo: we need callsign here
"red", //entity.getEntityID().getValue().toString(),
position, false);
Datasource.INSTANCE.UpdateEntity(unit); // <---------- This accesses the shared list
}
/**
* [Datasource] holds the data that is utilized by the UI
*/
object Datasource {
var currentStatus = ""
var currentMode = Modes.Nav
var Settings:SettingsClass = SettingsClass()
//This is the list of automations
var AutomationList = mutableListOf<AutomationClass>(
WTP(),
EW()
)
var TabPages = mutableListOf<String>()
var TabPageContents = mutableListOf<TabPage>()
var KillPairs = mutableListOf<KillPair>()
var SelectedTab:Int = 0
var newTab:String = ""
var locklineschanged = false
val entityUnitListMutex = Mutex(false)
val killPairsMutex = Mutex(false)
/*
This is the list of units. Any unit added to this list will get added to the map.
*/
val entityUnitList = mutableStateListOf<EntityUnit>()
fun UpdateEntity(entity:EntityUnit)
{
if (!entity.isPositionValid()) {
Log.e(ContentValues.TAG, "Datasource::UpdateEntity " + "Invalid entity passed:")
return
}
entity.lifeTime_ms = System.currentTimeMillis() // update its life time
try {
// NOTE - FindEntity() call must remain OUTSIDE of runblocking and mutex because
// FindEntity also has mutex and we do not want to nest mutex calls. Deadlock may occur
val existingEntity = FindEntity(entity.id)
runBlocking {
entityUnitListMutex.withLock {
if (existingEntity != null) {
entity.status = existingEntity.status
entity.missionCount = existingEntity.missionCount
val index = entityUnitList.indexOf(existingEntity)
entityUnitList[index] = entity
} else {
entityUnitList.add(entity)
}
}// end mutex
}
}
catch(e:Exception)
{
Log.e(ContentValues.TAG, "Datasource::UpdateEntity " + e.toString())
}
}
/*
Find the entity in the list of active entities
*/
fun FindEntity(entityName: String): EntityUnit? {
try {
var returnval: EntityUnit? = null
runBlocking {
entityUnitListMutex.withLock {
for (i in entityUnitList.indices) {
if (entityUnitList[i].id == entityName) {
returnval = entityUnitList[i]
break
}
}
}// end mutex
}
return returnval
} catch (e: Exception) {
Log.e(ContentValues.TAG, "Datasource::FindEntity " + e.toString())
return null
}
}
entityUnitList[index] = entity
...
entityUnitList.add(entity)
fun PutStuffOnMap(
uiState: FOXUiState, mapView: MapView, onEntityClicked: (entityClicked: String) -> Unit
) {
try {
val items = ArrayList<OverlayItem>()
runBlocking {
Datasource.entityUnitListMutex.withLock {
for (i in entityUnitList.indices) {
val entity = entityUnitList[i]
PlotEntity(mapView, entity)?.let { items.add(it) }
}
}// end mutex
}
. . .
@Composable
fun MapRow(
uiState: FOXUiState,
onEntityClicked: (entityClicked: String) -> Unit,
modifier: Modifier = Modifier){
Row(modifier = modifier) {
AndroidView(
factory = { context ->
MapView(context).apply {
SetUpMap( uiState, this, onEntityClicked)
}
},
update = {
mapView ->
PutStuffOnMap( uiState, mapView, onEntityClicked)
}
)
}
}
7G2 C E G E D R A 000001-999999
We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.