From 72d6db0a17765cac2b0e4482abb5b43968e1d0bb Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 3 May 2024 17:07:21 +0700 Subject: [PATCH] Make entity query Lua binding have less overhead --- .../lua/bindings/WorldEntityBindings.kt | 46 ++++++++++++------- .../lua/bindings/WorldObjectBindings.kt | 6 +-- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/bindings/WorldEntityBindings.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/bindings/WorldEntityBindings.kt index f308621a..116f2aa5 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/bindings/WorldEntityBindings.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/bindings/WorldEntityBindings.kt @@ -43,7 +43,6 @@ import ru.dbotthepony.kstarbound.world.entities.HumanoidActorEntity import ru.dbotthepony.kstarbound.world.entities.ItemDropEntity import ru.dbotthepony.kstarbound.world.entities.api.InspectableEntity import ru.dbotthepony.kstarbound.world.entities.api.InteractiveEntity -import ru.dbotthepony.kstarbound.world.entities.api.LoungeableEntity import ru.dbotthepony.kstarbound.world.entities.api.ScriptedEntity import ru.dbotthepony.kstarbound.world.entities.player.PlayerEntity import ru.dbotthepony.kstarbound.world.entities.tile.ContainerObject @@ -59,11 +58,24 @@ private enum class EntityBoundMode(override val jsonName: String) : IStringSeria POSITION("Position") } +private val callScriptStr = ByteString.of("callScript") +private val callScriptArgsStr = ByteString.of("callScriptArgs") +private val callScriptResultStr = ByteString.of("callScriptResult") +private val lineStr = ByteString.of("line") +private val polyStr = ByteString.of("poly") +private val rectStr = ByteString.of("rect") +private val withoutEntityIdStr = ByteString.of("withoutEntityId") +private val includedTypesStr = ByteString.of("includedTypes") +private val radiusStr = ByteString.of("radius") +private val centerStr = ByteString.of("center") +private val boundModeStr = ByteString.of("boundMode") +private val orderStr = ByteString.of("order") + private fun ExecutionContext.entityQueryImpl(self: World<*, *>, options: Table, predicate: Predicate = Predicate { true }): Table { - val withoutEntityId = (indexNoYield(options, "withoutEntityId") as Number?)?.toInt() + val withoutEntityId = (indexNoYield(options, withoutEntityIdStr) as Number?)?.toInt() val includedTypes = EnumSet.allOf(EntityType::class.java) - val getIncludedTypes = indexNoYield(options, "includedTypes") as Table? + val getIncludedTypes = indexNoYield(options, includedTypesStr) as Table? if (getIncludedTypes != null) { includedTypes.clear() @@ -92,24 +104,24 @@ private fun ExecutionContext.entityQueryImpl(self: World<*, *>, options: Table, } } - val callScript = (indexNoYield(options, "callScript") as ByteString?)?.decode() - val callScriptArgs = (indexNoYield(options, "callScriptArgs") as Table?)?.unpackAsArray() ?: arrayOf() - val callScriptResult = indexNoYield(options, "callScriptResult") ?: true + val callScript = (indexNoYield(options, callScriptStr) as ByteString?)?.decode() + val callScriptArgs = (indexNoYield(options, callScriptArgsStr) as Table?)?.unpackAsArray() ?: arrayOf() + val callScriptResult = indexNoYield(options, callScriptResultStr) ?: true - val lineQuery = (indexNoYield(options, "line") as Table?)?.let { toLine2d(it) } - val polyQuery = (indexNoYield(options, "poly") as Table?)?.let { toPoly(it) } - val rectQuery = (indexNoYield(options, "rect") as Table?)?.let { toAABB(it) } + val lineQuery = (indexNoYield(options, lineStr) as Table?)?.let { toLine2d(it) } + val polyQuery = (indexNoYield(options, polyStr) as Table?)?.let { toPoly(it) } + val rectQuery = (indexNoYield(options, rectStr) as Table?)?.let { toAABB(it) } - val radius = indexNoYield(options, "radius") + val radius = indexNoYield(options, radiusStr) val radiusQuery = if (radius is Number) { - val center = toVector2d(indexNoYield(options, "center") ?: throw LuaRuntimeException("Specified 'radius', but not 'center'")) + val center = toVector2d(indexNoYield(options, centerStr) ?: throw LuaRuntimeException("Specified 'radius', but not 'center'")) center to radius.toDouble() } else { null } - val boundMode = EntityBoundMode.entries.valueOf((indexNoYield(options, "boundMode") as ByteString?)?.decode() ?: "CollisionArea") + val boundMode = EntityBoundMode.entries.valueOf((indexNoYield(options, boundModeStr) as ByteString?)?.decode() ?: "CollisionArea") val innerPredicate = Predicate { if (!predicate.test(it)) return@Predicate false @@ -185,7 +197,7 @@ private fun ExecutionContext.entityQueryImpl(self: World<*, *>, options: Table, mutableListOf() } - when (val order = (indexNoYield(options, "order") as ByteString?)?.decode()?.lowercase()) { + when (val order = (indexNoYield(options, orderStr) as ByteString?)?.decode()?.lowercase()) { null -> {} // do nothing "random" -> entitites.shuffle(self.random) "nearest" -> { @@ -204,11 +216,11 @@ private fun ExecutionContext.intermediateQueryFunction(self: World<*, *>, pos1: val actualOptions = options ?: tableOf() if (pos2OrRadius is Number) { - actualOptions["center"] = pos1 - actualOptions["radius"] = pos2OrRadius + actualOptions[centerStr] = pos1 + actualOptions[radiusStr] = pos2OrRadius } else { pos2OrRadius as Table - actualOptions["rect"] = tableOf(pos1[1L], pos1[2L], pos2OrRadius[1L], pos2OrRadius[2L]) + actualOptions[rectStr] = tableOf(pos1[1L], pos1[2L], pos2OrRadius[1L], pos2OrRadius[2L]) } returnBuffer.setTo(entityQueryImpl(self, actualOptions, predicate)) @@ -216,7 +228,7 @@ private fun ExecutionContext.intermediateQueryFunction(self: World<*, *>, pos1: private fun ExecutionContext.intermediateLineQueryFunction(self: World<*, *>, pos1: Table, pos2: Table, options: Table?, predicate: Predicate) { val actualOptions = options ?: tableOf() - actualOptions["line"] = tableOf(pos1, pos2) + actualOptions[lineStr] = tableOf(pos1, pos2) returnBuffer.setTo(entityQueryImpl(self, actualOptions, predicate)) } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/bindings/WorldObjectBindings.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/bindings/WorldObjectBindings.kt index 0307bf5e..3cdce01c 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/bindings/WorldObjectBindings.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/bindings/WorldObjectBindings.kt @@ -73,19 +73,19 @@ fun provideWorldObjectBindings(self: WorldObject, lua: LuaEnvironment) { table["level"] = luaFunction { returnBuffer.setTo(self.lookupProperty(JsonPath("level")) { JsonPrimitive(self.world.template.threatLevel) }.asDouble) } table["toAbsolutePosition"] = luaFunction { pos: Table -> returnBuffer.setTo(from(toVector2d(pos) + self.position)) } - table["say"] = luaFunction { line: ByteString, tags: Table?, config: Table -> + table["say"] = luaFunction { line: ByteString, tags: Table?, sayConfig: Table? -> if (tags == null) { if (line.isEmpty) { returnBuffer.setTo(false) } else { - self.addChatMessage(line.decode(), config.toJson()) + self.addChatMessage(line.decode(), sayConfig?.toJson() ?: JsonNull.INSTANCE) returnBuffer.setTo(true) } } else { if (line.isEmpty) { returnBuffer.setTo(false) } else { - self.addChatMessage(SBPattern.of(line.decode()).resolveOrSkip({ tags[it]?.toString() }), config.toJson()) + self.addChatMessage(SBPattern.of(line.decode()).resolveOrSkip({ tags[it]?.toString() }), sayConfig?.toJson() ?: JsonNull.INSTANCE) returnBuffer.setTo(true) } }