245 lines
7.7 KiB
Kotlin
245 lines
7.7 KiB
Kotlin
package ru.dbotthepony.kstarbound.lua
|
|
|
|
import com.google.gson.JsonElement
|
|
import it.unimi.dsi.fastutil.objects.ObjectIterators
|
|
import org.classdump.luna.LuaRuntimeException
|
|
import org.classdump.luna.Table
|
|
import org.classdump.luna.TableFactory
|
|
import org.classdump.luna.impl.NonsuspendableFunctionException
|
|
import org.classdump.luna.lib.ArgumentIterator
|
|
import org.classdump.luna.runtime.AbstractFunction0
|
|
import org.classdump.luna.runtime.AbstractFunction1
|
|
import org.classdump.luna.runtime.AbstractFunction2
|
|
import org.classdump.luna.runtime.AbstractFunction3
|
|
import org.classdump.luna.runtime.AbstractFunction4
|
|
import org.classdump.luna.runtime.AbstractFunctionAnyArg
|
|
import org.classdump.luna.runtime.Dispatch
|
|
import org.classdump.luna.runtime.ExecutionContext
|
|
import org.classdump.luna.runtime.LuaFunction
|
|
import org.classdump.luna.runtime.UnresolvedControlThrowable
|
|
|
|
fun ExecutionContext.indexNoYield(table: Any, key: Any): Any? {
|
|
return try {
|
|
Dispatch.index(this, table, key)
|
|
returnBuffer.get0()
|
|
} catch (err: UnresolvedControlThrowable) {
|
|
throw RuntimeException("attempt to yield across C boundary", err)
|
|
}
|
|
}
|
|
|
|
fun ExecutionContext.indexSetNoYield(table: Any, key: Any, value: Any?) {
|
|
try {
|
|
Dispatch.setindex(this, table, key, value)
|
|
} catch (err: UnresolvedControlThrowable) {
|
|
throw RuntimeException("attempt to yield across C boundary", err)
|
|
}
|
|
}
|
|
|
|
fun ArgumentIterator.nextOptionalFloat(): Double? {
|
|
if (hasNext()) {
|
|
return nextFloat()
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
|
|
fun ArgumentIterator.nextOptionalInteger(): Long? {
|
|
if (hasNext()) {
|
|
return nextInteger()
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
|
|
operator fun Table.set(index: Any, value: Any?) {
|
|
rawset(index, value)
|
|
}
|
|
|
|
@Deprecated("Trying to set JSON to Lua table", level = DeprecationLevel.ERROR)
|
|
operator fun Table.set(index: Any, value: JsonElement?) {
|
|
rawset(index, value)
|
|
}
|
|
|
|
operator fun Table.set(index: Long, value: Any?) {
|
|
rawset(index, value)
|
|
}
|
|
|
|
@Deprecated("Trying to set JSON to Lua table", level = DeprecationLevel.ERROR)
|
|
operator fun Table.set(index: Long, value: JsonElement?) {
|
|
rawset(index, value)
|
|
}
|
|
|
|
operator fun Table.set(index: Int, value: Any?) {
|
|
rawset(index.toLong(), value)
|
|
}
|
|
|
|
@Deprecated("Trying to set JSON to Lua table", level = DeprecationLevel.ERROR)
|
|
operator fun Table.set(index: Int, value: JsonElement?) {
|
|
rawset(index.toLong(), value)
|
|
}
|
|
|
|
operator fun Table.get(index: Any): Any? = rawget(index)
|
|
operator fun Table.get(index: Long): Any? = rawget(index)
|
|
operator fun Table.get(index: Int): Any? = rawget(index.toLong())
|
|
|
|
operator fun Table.iterator(): Iterator<Map.Entry<Any, Any>> {
|
|
var key: Any? = initialKey() ?: return ObjectIterators.emptyIterator()
|
|
data class Pair(override val key: Any, override val value: Any) : Map.Entry<Any, Any>
|
|
|
|
return object : Iterator<Map.Entry<Any, Any>> {
|
|
override fun hasNext(): Boolean {
|
|
return key != null
|
|
}
|
|
|
|
override fun next(): Map.Entry<Any, Any> {
|
|
val ikey = key ?: throw NoSuchElementException()
|
|
val value = get(ikey)!!
|
|
key = successorKeyOf(ikey)
|
|
return Pair(ikey, value)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun TableFactory.tableOf(vararg values: Any?): Table {
|
|
val table = newTable(values.size, 0)
|
|
|
|
for ((i, v) in values.withIndex()) {
|
|
table[i + 1L] = v
|
|
}
|
|
|
|
return table
|
|
}
|
|
|
|
@Deprecated("Function is a stub")
|
|
fun luaStub(message: String = "not yet implemented"): LuaFunction<Any?, Any?, Any?, Any?, Any?> {
|
|
return object : LuaFunction<Any?, Any?, Any?, Any?, Any?>() {
|
|
override fun resume(context: ExecutionContext?, suspendedState: Any?) {
|
|
throw NonsuspendableFunctionException(this::class.java)
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext?) {
|
|
throw LuaRuntimeException("NYI: $message")
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext?, arg1: Any?) {
|
|
throw LuaRuntimeException("NYI: $message")
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext?, arg1: Any?, arg2: Any?) {
|
|
throw LuaRuntimeException("NYI: $message")
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext?, arg1: Any?, arg2: Any?, arg3: Any?) {
|
|
throw LuaRuntimeException("NYI: $message")
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext?, arg1: Any?, arg2: Any?, arg3: Any?, arg4: Any?) {
|
|
throw LuaRuntimeException("NYI: $message")
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext?, arg1: Any?, arg2: Any?, arg3: Any?, arg4: Any?, arg5: Any?) {
|
|
throw LuaRuntimeException("NYI: $message")
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext?, args: Array<out Any>?) {
|
|
throw LuaRuntimeException("NYI: $message")
|
|
}
|
|
}
|
|
}
|
|
|
|
fun luaFunctionN(name: String, callable: ExecutionContext.(ArgumentIterator) -> Unit): LuaFunction<Any, Any, Any, Any, Any> {
|
|
return object : AbstractFunctionAnyArg() {
|
|
override fun resume(context: ExecutionContext, suspendedState: Any) {
|
|
throw NonsuspendableFunctionException(this::class.java)
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext, args: Array<out Any>) {
|
|
callable.invoke(context, ArgumentIterator.of(context, name, args))
|
|
}
|
|
}
|
|
}
|
|
|
|
fun luaFunctionNS(name: String, callable: ExecutionContext.(ArgumentIterator) -> StateMachine): LuaFunction<Any, Any, Any, Any, Any> {
|
|
return object : AbstractFunctionAnyArg() {
|
|
override fun resume(context: ExecutionContext, suspendedState: Any) {
|
|
(suspendedState as StateMachine).run(context)
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext, args: Array<out Any>) {
|
|
callable.invoke(context, ArgumentIterator.of(context, name, args)).run(context)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun luaFunctionArray(callable: ExecutionContext.(Array<out Any?>) -> Unit): LuaFunction<Any, Any, Any, Any, Any> {
|
|
return object : AbstractFunctionAnyArg() {
|
|
override fun resume(context: ExecutionContext, suspendedState: Any) {
|
|
throw NonsuspendableFunctionException(this::class.java)
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext, args: Array<out Any?>) {
|
|
callable.invoke(context, args)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun luaFunction(callable: ExecutionContext.() -> Unit): LuaFunction<*, *, *, *, *> {
|
|
return object : AbstractFunction0() {
|
|
override fun resume(context: ExecutionContext, suspendedState: Any) {
|
|
throw NonsuspendableFunctionException(this::class.java)
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext) {
|
|
callable.invoke(context)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun <T> luaFunction(callable: ExecutionContext.(T) -> Unit): LuaFunction<T, *, *, *, *> {
|
|
return object : AbstractFunction1<T>() {
|
|
override fun resume(context: ExecutionContext, suspendedState: Any) {
|
|
throw NonsuspendableFunctionException(this::class.java)
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext, arg1: T) {
|
|
callable.invoke(context, arg1)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun <T, T2> luaFunction(callable: ExecutionContext.(T, T2) -> Unit): LuaFunction<T, T2, *, *, *> {
|
|
return object : AbstractFunction2<T, T2>() {
|
|
override fun resume(context: ExecutionContext, suspendedState: Any) {
|
|
throw NonsuspendableFunctionException(this::class.java)
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext, arg1: T, arg2: T2) {
|
|
callable.invoke(context, arg1, arg2)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun <T, T2, T3> luaFunction(callable: ExecutionContext.(T, T2, T3) -> Unit): LuaFunction<T, T2, T3, *, *> {
|
|
return object : AbstractFunction3<T, T2, T3>() {
|
|
override fun resume(context: ExecutionContext, suspendedState: Any) {
|
|
throw NonsuspendableFunctionException(this::class.java)
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext, arg1: T, arg2: T2, arg3: T3) {
|
|
callable.invoke(context, arg1, arg2, arg3)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun <T, T2, T3, T4> luaFunction(callable: ExecutionContext.(T, T2, T3, T4) -> Unit): LuaFunction<T, T2, T3, T4, *> {
|
|
return object : AbstractFunction4<T, T2, T3, T4>() {
|
|
override fun resume(context: ExecutionContext, suspendedState: Any) {
|
|
throw NonsuspendableFunctionException(this::class.java)
|
|
}
|
|
|
|
override fun invoke(context: ExecutionContext, arg1: T, arg2: T2, arg3: T3, arg4: T4) {
|
|
callable.invoke(context, arg1, arg2, arg3, arg4)
|
|
}
|
|
}
|
|
}
|