Skip to content

Commit

Permalink
Small TransferContext.kt refactor to call rewind() early.
Browse files Browse the repository at this point in the history
  • Loading branch information
CedNaru committed Oct 14, 2023
1 parent 1df9a4e commit 784010e
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 37 deletions.
9 changes: 1 addition & 8 deletions kt/godot-library/src/main/kotlin/godot/core/Constructors.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,7 @@ abstract class KtConstructor<T : KtObject>(
abstract operator fun invoke(): T

fun construct(rawPtr: VoidPtr, instanceId: Long) = KtObject.instantiateWith(rawPtr, instanceId) {
val argsSize = TransferContext.buffer.int
require(argsSize == parameterCount) {
"Expecting $parameterCount parameter(s) for constructor, but got $argsSize instead."
}
for (i in 0 until parameterCount) {
paramsArray[i] = TransferContext.readSingleArgument(parameterTypes[i], parameterNullables[i])
}
TransferContext.buffer.rewind()
TransferContext.readArguments(parameterTypes, parameterNullables, paramsArray)
val instance = invoke()
resetParamsArray()
instance
Expand Down
11 changes: 2 additions & 9 deletions kt/godot-library/src/main/kotlin/godot/core/KtObject.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,12 @@ abstract class KtObject {

internal inline fun callConstructor(classIndex: Int, scriptIndex: Int): Unit {
TransferContext.createNativeObject(classIndex, this, scriptIndex)
readPtrAndIdFromBuffer()
TransferContext.initializeKtObject(this)
}

internal inline fun getSingleton(classIndex: Int) {
TransferContext.getSingleton(classIndex)
readPtrAndIdFromBuffer()
}

private inline fun readPtrAndIdFromBuffer() {
val buffer = TransferContext.buffer
rawPtr = buffer.long
id = ObjectID(buffer.long)
buffer.rewind()
TransferContext.initializeKtObject(this)
}

open fun _onDestroy() = Unit
Expand Down
3 changes: 0 additions & 3 deletions kt/godot-library/src/main/kotlin/godot/core/Properties.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,8 @@ open class KtProperty<T : KtObject, P : Any?>(
}

protected fun <P> extractSetterArgument(): P {
val argsSize = TransferContext.buffer.int
require(argsSize == 1) { "Setter should be called with only one argument." }
//TODO: manage nullable argument of enum setter (only for objects)
val arg = TransferContext.readSingleArgument(variantType)
TransferContext.buffer.rewind()
@Suppress("UNCHECKED_CAST")
return arg as P
}
Expand Down
15 changes: 3 additions & 12 deletions kt/godot-library/src/main/kotlin/godot/core/callable/KtCallable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,17 @@ abstract class KtCallable<T : KtObject, R : Any?>(
val variantType: VariantType,
vararg parameterTypes: Pair<VariantType, Boolean>
) {
private val types: List<VariantType> = parameterTypes.map { it.first }
private val isNullables: List<Boolean> = parameterTypes.map { it.second }
private val types: Array<VariantType> = parameterTypes.map { it.first }.toTypedArray()
private val isNullables: Array<Boolean> = parameterTypes.map { it.second }.toTypedArray()

fun invoke(instance: T) {
val argsSize = TransferContext.buffer.int
require(argsSize == parameterCount) { "Expecting $parameterCount parameter(s) for function $name, but got $argsSize instead." }
readArguments(argsSize)
TransferContext.readArguments(types, isNullables, paramsArray)
val ret = invokeKt(instance)
resetParamsArray()

TransferContext.writeReturnValue(ret, variantType)
}

private fun readArguments(argsSize: Int) {
for (i in 0 until argsSize) {
paramsArray[i] = TransferContext.readSingleArgument(types[i], isNullables[i])
}
TransferContext.buffer.rewind()
}

companion object {
val paramsArray by threadLocal {
Array<Any?>(Constraints.MAX_FUNCTION_ARG_COUNT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package godot.core.memory

import godot.core.KtObject
import godot.core.LongStringQueue
import godot.core.ObjectID
import godot.core.VariantType
import godot.tools.common.constants.Constraints
import godot.util.VoidPtr
Expand All @@ -22,31 +23,51 @@ internal object TransferContext {
return (LongStringQueue.stringMaxSize + 12).coerceAtLeast(68) * Constraints.MAX_FUNCTION_ARG_COUNT + 4
}

val buffer by threadLocalLazy<ByteBuffer> {
private val buffer by threadLocalLazy<ByteBuffer> {
val buf = ByteBuffer.allocateDirect(bufferSize)
buf.order(ByteOrder.LITTLE_ENDIAN)
buf
}

fun writeArguments(vararg values: Pair<VariantType, Any?>) {
buffer.rewind()
buffer.putInt(values.size)
for (value in values) {
value.first.toGodot(buffer, value.second)
}
}

fun readSingleArgument(variantType: VariantType, isNullable: Boolean = false): Any? {
buffer.rewind()
val argsSize = buffer.int
require(argsSize == 1) {
"Expecting 1 parameter, but got $argsSize instead."
}
return variantType.toKotlin(buffer, isNullable)
}

fun readSingleArgument(variantType: VariantType, isNullable: Boolean = false) =
variantType.toKotlin(buffer, isNullable)
fun readArguments(variantTypes: Array<VariantType>, areNullable: Array<Boolean>, returnArray: Array<Any?>) {
buffer.rewind()
val argsSize = buffer.int
val argumentCount = variantTypes.size
require(argsSize == argumentCount) {
"Expecting $argumentCount parameter(s), but got $argsSize instead."
}

// Assume that variantTypes and areNullable have the same size and that returnArray is big enough
for (i in 0 until argsSize) {
returnArray[i] = variantTypes[i].toKotlin(buffer, areNullable[i])
}
}

fun writeReturnValue(value: Any?, type: VariantType) {
type.toGodot(buffer, value)
buffer.rewind()
type.toGodot(buffer, value)
}

fun readReturnValue(type: VariantType, isNullable: Boolean = false): Any? {
val ret = type.toKotlin(buffer, isNullable)
buffer.rewind()
val ret = type.toKotlin(buffer, isNullable)
return ret
}

Expand All @@ -58,6 +79,12 @@ internal object TransferContext {
)
}

fun initializeKtObject(obj: KtObject) {
buffer.rewind()
obj.rawPtr = buffer.long
obj.id = ObjectID(buffer.long)
}

fun removeScriptInstance(id: Long) {
MemoryManager.unregisterScriptInstance(id)
}
Expand Down

0 comments on commit 784010e

Please sign in to comment.