From cf56e1c7814fa8e4b4722fe0277c780930a00e9e Mon Sep 17 00:00:00 2001 From: TheSaminator Date: Mon, 4 Jul 2022 15:42:21 -0400 Subject: [PATCH] Improve cluster data-structure ID generation --- .../starshipfights/campaign/cluster_gen.kt | 11 +- .../starshipfights/campaign/cluster_test.kt | 3 +- .../data/space/star_clusters.kt | 176 +++++++++++------- 3 files changed, 117 insertions(+), 73 deletions(-) diff --git a/src/jvmMain/kotlin/net/starshipfights/campaign/cluster_gen.kt b/src/jvmMain/kotlin/net/starshipfights/campaign/cluster_gen.kt index 242e05c..483fcc7 100644 --- a/src/jvmMain/kotlin/net/starshipfights/campaign/cluster_gen.kt +++ b/src/jvmMain/kotlin/net/starshipfights/campaign/cluster_gen.kt @@ -3,6 +3,7 @@ package net.starshipfights.campaign import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import net.starshipfights.data.Id +import net.starshipfights.data.invoke import net.starshipfights.game.* import net.starshipfights.game.ai.mean import net.starshipfights.game.ai.random @@ -38,7 +39,7 @@ class ClusterGenerator(val settings: ClusterGenerationSettings) { val systems = (positions.toList() zip unplacedStarSystems).associate { (idAndPos, data) -> val (id, pos) = idAndPos - id to data.place(id, pos) + id to data.place(pos) } StarClusterView( @@ -88,9 +89,9 @@ class ClusterGenerator(val settings: ClusterGenerationSettings) { } private suspend fun indexPositions(positions: List): Map, Vec2> { - return positions.withIndex().associate { (i, pos) -> + return positions.associateBy { throttle() - Id("star-system-${i + 1}") to pos + Id() } } @@ -361,13 +362,13 @@ private data class UnplacedStarSystem( val radius: Double, val bodies: Set ) { - fun place(id: Id, position: Vec2) = StarSystem( + fun place(position: Vec2) = StarSystem( name = name, holder = null, fleets = emptyMap(), position = Position(position), radius = radius, - bodies = bodies.withIndex().associate { (i, body) -> Id("${id.id}-body-$i") to body } + bodies = bodies.associateBy { Id() } ) } diff --git a/src/jvmMain/kotlin/net/starshipfights/campaign/cluster_test.kt b/src/jvmMain/kotlin/net/starshipfights/campaign/cluster_test.kt index f99ab33..b6f1104 100644 --- a/src/jvmMain/kotlin/net/starshipfights/campaign/cluster_test.kt +++ b/src/jvmMain/kotlin/net/starshipfights/campaign/cluster_test.kt @@ -3,6 +3,7 @@ package net.starshipfights.campaign import net.starshipfights.data.Id import net.starshipfights.data.admiralty.AdmiralNameFlavor import net.starshipfights.data.admiralty.AdmiralNames +import net.starshipfights.data.invoke import net.starshipfights.game.AdmiralRank import net.starshipfights.game.FactionFlavor import kotlin.random.Random @@ -22,7 +23,7 @@ fun StarClusterView.testPostProcess(): StarClusterView { val fleets = (1..numOfFleets).associate { i -> val admiralIsFemale = flavor == FactionFlavor.FELINAE_FELICES || Random.nextBoolean() - Id("${systemId.id}-fleet-$i") to FleetPresence( + Id() to FleetPresence( name = "Test Fleet $i", owner = flavor, ships = emptyMap(), diff --git a/src/jvmMain/kotlin/net/starshipfights/data/space/star_clusters.kt b/src/jvmMain/kotlin/net/starshipfights/data/space/star_clusters.kt index f921ddd..124f3b4 100644 --- a/src/jvmMain/kotlin/net/starshipfights/data/space/star_clusters.kt +++ b/src/jvmMain/kotlin/net/starshipfights/data/space/star_clusters.kt @@ -2,21 +2,24 @@ package net.starshipfights.data.space import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch import kotlinx.serialization.Serializable import net.starshipfights.campaign.* import net.starshipfights.data.DataDocument import net.starshipfights.data.DocumentTable import net.starshipfights.data.Id +import net.starshipfights.data.invoke import net.starshipfights.game.FactionFlavor import net.starshipfights.game.Position +import org.litote.kmongo.eq @Serializable data class StarCluster( override val id: Id, val background: StarClusterBackground, - val systems: Set>, val lanes: Set ) : DataDocument { companion object Table : DocumentTable by DocumentTable.create() @@ -25,110 +28,149 @@ data class StarCluster( @Serializable data class ClusterStarSystem( override val id: Id, + val clusterId: Id, val name: String, val holder: FactionFlavor?, - val fleets: Set>, val position: Position, val radius: Double, - val bodies: Set>, ) : DataDocument { - companion object Table : DocumentTable by DocumentTable.create() + companion object Table : DocumentTable by DocumentTable.create({ + index(ClusterStarSystem::clusterId) + }) } @Serializable data class ClusterCelestialObject( override val id: Id, + val starSystemId: Id, val celestialObject: CelestialObject ) : DataDocument { - companion object Table : DocumentTable by DocumentTable.create() + companion object Table : DocumentTable by DocumentTable.create({ + index(ClusterCelestialObject::starSystemId) + }) } @Serializable data class ClusterFleetPresence( override val id: Id, + val starSystemId: Id, val fleetPresence: FleetPresence ) : DataDocument { - companion object Table : DocumentTable by DocumentTable.create() + companion object Table : DocumentTable by DocumentTable.create({ + index(ClusterFleetPresence::starSystemId) + }) } suspend fun deleteCluster(clusterId: Id) { coroutineScope { - val cluster = StarCluster.get(clusterId) ?: return@coroutineScope - - for (systemId in cluster.systems) - launch { - val system = ClusterStarSystem.get(systemId) ?: return@launch - - for (bodyId in system.bodies) - launch { - ClusterCelestialObject.del(bodyId) - } - - for (fleetId in system.fleets) - launch { - ClusterFleetPresence.del(fleetId) - } - - ClusterStarSystem.del(systemId) + launch { StarCluster.del(clusterId) } + launch { + ClusterStarSystem.filter(ClusterStarSystem::clusterId eq clusterId).collect { cSystem -> + launch { + ClusterCelestialObject.remove(ClusterCelestialObject::starSystemId eq cSystem.id) + } + launch { + ClusterFleetPresence.remove(ClusterFleetPresence::starSystemId eq cSystem.id) + } + launch { + ClusterStarSystem.del(cSystem.id) + } } - - StarCluster.del(clusterId) + } } } -suspend fun view(clusterId: Id): StarClusterView? { - return coroutineScope { - val cluster = StarCluster.get(clusterId) ?: return@coroutineScope null - - val systems = cluster.systems.map { systemId -> - systemId.reinterpret() to async { - val system = ClusterStarSystem.get(systemId) ?: return@async null +suspend fun createCluster(clusterView: StarClusterView): Id { + val cluster = StarCluster( + id = Id(), + background = clusterView.background, + lanes = clusterView.lanes + ) + + coroutineScope { + launch { StarCluster.put(cluster) } + launch { + for ((systemId, system) in clusterView.systems) { + val clusterSystem = ClusterStarSystem( + id = systemId.reinterpret(), + clusterId = cluster.id, + name = system.name, + holder = system.holder, + position = system.position, + radius = system.radius + ) - val bodiesAsync = async { - system.bodies - .map { bodyId -> - bodyId to async { ClusterCelestialObject.get(bodyId) } - } - .mapNotNull { (id, deferred) -> - deferred.await()?.let { id to it } - } - .associate { (id, clusterObject) -> - id.reinterpret() to clusterObject.celestialObject + launch { ClusterStarSystem.put(clusterSystem) } + launch { + for ((bodyId, body) in system.bodies) + launch { + ClusterCelestialObject.put( + ClusterCelestialObject( + id = bodyId.reinterpret(), + starSystemId = clusterSystem.id, + celestialObject = body + ) + ) } } - - val fleetsAsync = async { - system.fleets - .map { fleetId -> - fleetId to async { ClusterFleetPresence.get(fleetId) } + launch { + for ((fleetId, fleet) in system.fleets) + launch { + ClusterFleetPresence.put( + ClusterFleetPresence( + id = fleetId.reinterpret(), + starSystemId = clusterSystem.id, + fleetPresence = fleet + ) + ) } - .mapNotNull { (id, deferred) -> - deferred.await()?.let { id to it } + } + } + } + } + + return cluster.id +} + +suspend fun viewCluster(clusterId: Id): StarClusterView? { + return coroutineScope { + val clusterAsync = async { StarCluster.get(clusterId) } + val systemsAsync = async { + ClusterStarSystem.filter(ClusterStarSystem::clusterId eq clusterId).map { cSystem -> + async { + val bodiesAsync = async { + val bodies = ClusterCelestialObject.filter(ClusterCelestialObject::starSystemId eq cSystem.id).toList() + + bodies.associate { cBody -> + cBody.id.reinterpret() to cBody.celestialObject } - .associate { (id, clusterFleet) -> - id.reinterpret() to clusterFleet.fleetPresence + } + val fleetsAsync = async { + val fleets = ClusterFleetPresence.filter(ClusterFleetPresence::starSystemId eq cSystem.id).toList() + + fleets.associate { cFleet -> + cFleet.id.reinterpret() to cFleet.fleetPresence } + } + + cSystem.id.reinterpret() to StarSystem( + cSystem.name, + cSystem.holder, + fleetsAsync.await(), + cSystem.position, + cSystem.radius, + bodiesAsync.await() + ) } - - val bodies = bodiesAsync.await() - val fleets = fleetsAsync.await() - - StarSystem( - name = system.name, - holder = system.holder, - fleets = fleets, - position = system.position, - radius = system.radius, - bodies = bodies - ) - } - }.mapNotNull { (id, deferred) -> - deferred.await()?.let { id to it } - }.toMap() + }.toList().associate { it.await() } + } + + val cluster = clusterAsync.await() ?: return@coroutineScope null + val systems = systemsAsync.await() StarClusterView( background = cluster.background, -- 2.25.1