All code now compiles with Kotlin 2.0.0 and all tests pass.

This commit is contained in:
Daan Vanden Bosch 2024-07-16 21:47:47 +02:00
parent 22d01776d0
commit a8b1a00e06
2185 changed files with 4121 additions and 495 deletions

View File

@ -9,31 +9,26 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up JDK
uses: actions/setup-java@v1
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '11'
- name: Cache Gradle packages
uses: actions/cache@v2
with:
path: |
~/.gradle
.gradle
build/js
key: ${{ runner.os }}-gradle
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Build
run: './gradlew :web:browserDistribution'
run: './gradlew :web:jsBrowserDistribution'
- name: Deploy
uses: JamesIves/github-pages-deploy-action@3.6.2
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: gh-pages
FOLDER: web/build/distributions
FOLDER: web/build/dist/js/productionExecutable
CLEAN: true

View File

@ -12,28 +12,16 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v1
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '11'
- name: Cache Gradle packages
uses: actions/cache@v2
with:
path: |
~/.gradle
.gradle
build/js
key: ${{ runner.os }}-gradle
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Test
run: ./gradlew check
- name: Cleanup Gradle Cache
# Remove some files from the Gradle cache, so they aren't cached by GitHub Actions.
# Restoring these files from a GitHub Actions cache might cause problems for future builds.
run: |
rm -f ~/.gradle/caches/modules-2/modules-2.lock
rm -f ~/.gradle/caches/modules-2/gc.properties
run: './gradlew check'

3
.gitignore vendored
View File

@ -13,3 +13,6 @@ karma.config.generated.js
# Config
/psoserv/psoserv.conf
# Kotlin
/.kotlin

View File

@ -32,7 +32,7 @@ Then, for the web application:
1. `cd` to the project directory
2. Launch webpack server on [http://localhost:1623/](http://localhost:1623/)
with `./gradlew :web:run --continuous`
with `./gradlew :web:jsBrowserDevelopmentRun --continuous`
3. [web/src/main/kotlin/world/phantasmal/web/Main.kt](web/src/main/kotlin/world/phantasmal/web/Main.kt)
is the application's entry point
@ -95,6 +95,8 @@ Work-in-progress PSO server and fully functional PSO proxy server.
Run the unit tests with `./gradlew check`. JS tests are run with Karma and Mocha, JVM tests with
Junit 5. Tests can also be run per project with e.g. `./gradlew :psolib:check`.
TODO: Figure out why `./gradlew check` runs the cell tests twice since upgrade to Gradle 8.9.
### Code Style and Formatting
The Kotlin [coding conventions](https://kotlinlang.org/docs/coding-conventions.html) are used.
@ -103,7 +105,7 @@ The Kotlin [coding conventions](https://kotlinlang.org/docs/coding-conventions.h
#### Web Application
Create an optimized production build with `./gradlew :web:browserDistribution`.
Create an optimized production build with `./gradlew :web:jsBrowserDistribution`.
#### PSO Server

View File

@ -1,11 +0,0 @@
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
tasks.wrapper {
gradleVersion = "7.1.1"
}
// Temporary fix for issue with incompatible webpack-cli and @webpack-cli versions.
rootProject.plugins.withType<NodeJsRootPlugin> {
rootProject.the<NodeJsRootExtension>().versions.webpackCli.version = "4.9.0"
}

View File

@ -7,6 +7,6 @@ repositories {
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31")
implementation("org.jetbrains.kotlin:kotlin-serialization:1.5.31")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0")
implementation("org.jetbrains.kotlin:kotlin-serialization:1.9.24")
}

View File

@ -1,8 +0,0 @@
package world.phantasmal
val EXPERIMENTAL_ANNOTATIONS: List<String> = listOf(
"kotlin.RequiresOptIn",
"kotlin.ExperimentalUnsignedTypes",
"kotlin.contracts.ExperimentalContracts",
"kotlin.time.ExperimentalTime",
)

View File

@ -1,5 +1,9 @@
package world.phantasmal
import org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("plugin.serialization") apply false
}
@ -8,9 +12,35 @@ repositories {
mavenCentral()
}
project.extra["coroutinesVersion"] = "1.5.2"
project.extra["junitVersion"] = "5.7.1"
tasks.withType<KotlinCompilationTask<*>> {
compilerOptions {
allWarningsAsErrors.set(true)
optIn.set(
listOf(
"kotlin.contracts.ExperimentalContracts",
"kotlin.ExperimentalUnsignedTypes",
)
)
freeCompilerArgs.add("-Xexpect-actual-classes")
}
}
tasks.withType<KotlinCompile>().configureEach {
compilerOptions {
jvmTarget.set(JVM_11)
freeCompilerArgs.addAll(
"-Xjdk-release=${jvmTarget.get().target}",
"-Xjvm-default=all",
)
}
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
project.extra["coroutinesVersion"] = "1.9.0-RC"
project.extra["kotlinLoggingVersion"] = "2.0.11"
project.extra["ktorVersion"] = "1.6.1"
project.extra["ktorVersion"] = "2.3.12"
project.extra["log4jVersion"] = "2.14.1"
project.extra["serializationVersion"] = "1.2.2"
project.extra["serializationVersion"] = "1.7.1"

View File

@ -1,16 +1,13 @@
package world.phantasmal
plugins {
kotlin("js")
kotlin("multiplatform")
id("world.phantasmal.common")
id("world.phantasmal.karma-resources")
}
kotlin {
js {
compilations.configureEach {
EXPERIMENTAL_ANNOTATIONS.forEach(languageSettings::optIn)
}
browser {
testTask {
useKarma {
@ -19,8 +16,12 @@ kotlin {
}
}
}
}
dependencies {
testImplementation(kotlin("test-js"))
sourceSets {
commonTest {
dependencies {
implementation(kotlin("test"))
}
}
}
}

View File

@ -1,35 +1,18 @@
package world.phantasmal
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm")
id("world.phantasmal.common")
}
val junitVersion: String by project.extra
val log4jVersion: String by project.extra
kotlin {
sourceSets.configureEach {
EXPERIMENTAL_ANNOTATIONS.forEach(languageSettings::optIn)
}
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "11"
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
}
jvmToolchain(11)
}
dependencies {
runtimeOnly("org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion")
testImplementation(kotlin("test-junit5"))
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testImplementation(kotlin("test"))
}

View File

@ -2,40 +2,20 @@ package world.phantasmal
plugins {
kotlin("multiplatform")
id("world.phantasmal.common")
id("world.phantasmal.js")
id("world.phantasmal.karma-resources")
}
val coroutinesVersion: String by project.ext
val junitVersion: String by project.extra
val kotlinLoggingVersion: String by project.extra
val log4jVersion: String by project.extra
kotlin {
js {
browser {
testTask {
useKarma {
useChromeHeadless()
}
}
}
}
jvmToolchain(11)
jvm {
compilations.configureEach {
kotlinOptions {
jvmTarget = "11"
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
}
}
}
jvm {}
sourceSets {
configureEach {
EXPERIMENTAL_ANNOTATIONS.forEach(languageSettings::optIn)
}
commonMain {
dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
@ -43,34 +23,10 @@ kotlin {
}
}
commonTest {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
getByName("jsTest") {
dependencies {
implementation(kotlin("test-js"))
}
}
getByName("jvmMain") {
dependencies {
runtimeOnly("org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion")
}
}
getByName("jvmTest") {
dependencies {
implementation(kotlin("test-junit5"))
runtimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
}
}
}
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}

View File

@ -1,6 +1,6 @@
package world.phantasmal.cell
import kotlin.contracts.InvocationKind
import kotlin.contracts.InvocationKind.EXACTLY_ONCE
import kotlin.contracts.contract
abstract class AbstractDependency<T> : Dependency<T> {
@ -22,7 +22,7 @@ abstract class AbstractDependency<T> : Dependency<T> {
protected inline fun applyChange(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
callsInPlace(block, EXACTLY_ONCE)
}
MutationManager.changeDependency {

View File

@ -28,7 +28,11 @@ internal class SimpleListCell<E>(
override operator fun set(index: Int, element: E): E {
checkIndex(index, elements.lastIndex)
applyChange {
// TODO: Use applyChange instead of MutationManager.changeDependency, once
// https://youtrack.jetbrains.com/issue/KT-69964 is fixed.
MutationManager.changeDependency {
emitDependencyInvalidated()
val removed = elements.set(index, element)
finalizeChange(
@ -81,7 +85,11 @@ internal class SimpleListCell<E>(
override fun removeAt(index: Int): E {
checkIndex(index, elements.lastIndex)
applyChange {
// TODO: Use applyChange instead of MutationManager.changeDependency, once
// https://youtrack.jetbrains.com/issue/KT-69964 is fixed.
MutationManager.changeDependency {
emitDependencyInvalidated()
val prevSize = elements.size
val removed = elements.removeAt(index)

View File

@ -11,7 +11,8 @@ class FilteredListCellPredicateDependencyEmitsTests : ListCellTests, CellWithDep
private var maxValue = if (empty) 0 else 1
// The predicate cell changes, the predicate results don't.
private val predicateCell = SimpleCell<(Int) -> Cell<Boolean>> { cell(it <= maxValue) }
private val predicateCell: SimpleCell<(Int) -> Cell<Boolean>> =
SimpleCell { cell(it <= maxValue) }
override val cell =
FilteredListCell(

View File

@ -2,9 +2,14 @@ package world.phantasmal.core
// Char.isWhitespace is very slow in JS, use this until
// https://youtrack.jetbrains.com/issue/KT-43216 lands.
expect inline fun Char.fastIsWhitespace(): Boolean
@Suppress("NOTHING_TO_INLINE")
inline fun Char.fastIsWhitespace(): Boolean =
code == 0x20 || (code in 0x09..0x0D)
expect inline fun Char.isDigit(): Boolean
// This is optimized for KJS. Last checked with Kotlin 1.6.
@Suppress("NOTHING_TO_INLINE")
inline fun Char.isDigit(): Boolean =
code in 0x30..0x39
/**
* Returns true if the bit at the given position is set. Bits are indexed from lowest-order

View File

@ -1,5 +1,3 @@
@file:Suppress("NOTHING_TO_INLINE")
package world.phantasmal.core
import org.w3c.dom.DOMRectReadOnly
@ -19,21 +17,27 @@ external interface JsArray<T> {
fun splice(start: Int, deleteCount: Int, vararg items: T): JsArray<T>
}
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> JsArray<T>.get(index: Int): T = asDynamic()[index].unsafeCast<T>()
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> JsArray<T>.set(index: Int, value: T) {
asDynamic()[index] = value
}
@Suppress("NOTHING_TO_INLINE")
inline fun <T> jsArrayOf(vararg elements: T): JsArray<T> =
elements.unsafeCast<JsArray<T>>()
@Suppress("NOTHING_TO_INLINE")
inline fun <T> JsArray<T>.asArray(): Array<T> =
unsafeCast<Array<T>>()
@Suppress("NOTHING_TO_INLINE")
inline fun <T> Array<T>.asJsArray(): JsArray<T> =
unsafeCast<JsArray<T>>()
@Suppress("NOTHING_TO_INLINE")
inline fun <T> List<T>.toJsArray(): JsArray<T> =
toTypedArray().asJsArray()
@ -43,7 +47,10 @@ external interface JsPair<out A, out B>
inline val <T> JsPair<T, *>.first: T get() = asDynamic()[0].unsafeCast<T>()
inline val <T> JsPair<*, T>.second: T get() = asDynamic()[1].unsafeCast<T>()
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> JsPair<T, *>.component1(): T = first
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> JsPair<*, T>.component2(): T = second
@JsName("Object")

View File

@ -1,9 +0,0 @@
package world.phantasmal.core
@Suppress("NOTHING_TO_INLINE")
actual inline fun Char.fastIsWhitespace(): Boolean =
asDynamic() == 0x20 || (asDynamic() >= 0x09 && asDynamic() <= 0x0D)
@Suppress("NOTHING_TO_INLINE")
actual inline fun Char.isDigit(): Boolean =
asDynamic() >= 0x30 && asDynamic() <= 0x39

View File

@ -1,9 +0,0 @@
@file:JvmName("PrimitiveExtensionsJvm")
package world.phantasmal.core
@Suppress("NOTHING_TO_INLINE")
actual inline fun Char.fastIsWhitespace(): Boolean = isWhitespace()
@Suppress("NOTHING_TO_INLINE")
actual inline fun Char.isDigit(): Boolean = this in '0'..'9'

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

2
gradlew vendored
View File

@ -72,7 +72,7 @@ case "`uname`" in
Darwin* )
darwin=true
;;
MINGW* )
MSYS* | MINGW* )
msys=true
;;
NONSTOP* )

3300
kotlin-js-store/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,8 @@ buildscript {
}
/** Source code generated by the build script goes here. */
val generatedCommonSrc = File(buildDir, "generated-src/commonMain/kotlin")
val generatedCommonSrc =
layout.buildDirectory.get().asFile.resolve("generated-src/commonMain/kotlin")
val serializationVersion: String by project.extra
@ -46,7 +47,7 @@ val generateOpcodes = tasks.register("generateOpcodes") {
val packageName = "world.phantasmal.psolib.asm"
val opcodesFile = file("srcGeneration/asm/opcodes.yml")
val outputFile = File(generatedCommonSrc, "${packageName.replace('.', '/')}/Opcodes.kt")
val outputFile = generatedCommonSrc.resolve("${packageName.replace('.', '/')}/Opcodes.kt")
inputs.file(opcodesFile)
outputs.file(outputFile)
@ -75,8 +76,8 @@ val generateOpcodes = tasks.register("generateOpcodes") {
fun opcodeToCode(writer: PrintWriter, opcode: Map<String, Any>) {
val code = (opcode["code"] as String).drop(2).toInt(16)
val codeStr = code.toString(16).toUpperCase().padStart(2, '0')
val mnemonic = opcode["mnemonic"] as String? ?: "unknown_${codeStr.toLowerCase()}"
val codeStr = code.toString(16).uppercase().padStart(2, '0')
val mnemonic = opcode["mnemonic"] as String? ?: "unknown_${codeStr.lowercase()}"
val doc = (opcode["doc"] as String?)?.let {
"\"${it.replace("\n", "\\n")}\""
}
@ -87,7 +88,7 @@ fun opcodeToCode(writer: PrintWriter, opcode: Map<String, Any>) {
.replace("=", "e")
.replace("<", "l")
.replace(">", "g")
.toUpperCase()
.uppercase()
val stackInteraction = when (stack) {
"push" -> "StackInteraction.Push"
@ -114,7 +115,7 @@ fun opcodeToCode(writer: PrintWriter, opcode: Map<String, Any>) {
in 0xF900..0xF9FF -> "OPCODES_F9"
else -> error("Invalid opcode $codeStr ($mnemonic).")
}
val indexStr = (code and 0xFF).toString(16).toUpperCase().padStart(2, '0')
val indexStr = (code and 0xFF).toString(16).uppercase().padStart(2, '0')
writer.println(
"""
@ -155,6 +156,7 @@ fun paramsToCode(params: List<Map<String, Any>>, indent: Int): String {
paramsToCode(it, indent + 4)
} ?: "null"
})"""
"reg_var" -> "RegVarType"
"pointer" -> "PointerType"
else -> error("Type ${param["type"]} not implemented.")

View File

@ -300,6 +300,8 @@ private fun findAndParseSegments(
}
}
}
else -> {}
}
i++
@ -819,16 +821,20 @@ fun writeBytecode(bytecodeIr: BytecodeIr, dcGcFormat: Boolean): BytecodeAndLabel
cursor.writeShort(a.coerceInt().toShort())
}
}
is LabelType -> cursor.writeShort(arg.coerceInt().toShort())
StringType -> {
val str = arg.coerceString()
if (dcGcFormat) cursor.writeStringAscii(str, str.length + 1)
else cursor.writeStringUtf16(str, 2 * str.length + 2)
}
is RegType -> {
cursor.writeByte(arg.coerceInt().toByte())
}
RegVarType -> {
cursor.writeByte(args.size.toByte())
@ -836,6 +842,7 @@ fun writeBytecode(bytecodeIr: BytecodeIr, dcGcFormat: Boolean): BytecodeAndLabel
cursor.writeByte(a.coerceInt().toByte())
}
}
else -> error(
"Parameter type ${param.type::class.simpleName} not supported."
)

View File

@ -4,7 +4,6 @@ import world.phantasmal.psolib.buffer.Buffer
// TODO: set properties of friendly NPCs based on episode.
internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
@Suppress("NON_EXHAUSTIVE_WHEN")
when (type) {
NpcType.FemaleFat -> {
view.setShort(2, 2)
@ -13,6 +12,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -16432)
view.setShort(70, 1834)
}
NpcType.FemaleMacho -> {
view.setShort(2, 2)
view.setShort(4, 1876)
@ -20,12 +20,14 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -12528)
view.setShort(70, 1834)
}
NpcType.FemaleTall -> {
view.setShort(2, 2)
view.setShort(4, 1883)
view.setShort(68, -5504)
view.setShort(70, 1834)
}
NpcType.MaleDwarf -> {
view.setShort(2, 2)
view.setShort(4, 1873)
@ -33,6 +35,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -15456)
view.setShort(70, 1834)
}
NpcType.MaleFat -> {
view.setShort(2, 2)
view.setShort(4, 1882)
@ -40,6 +43,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -6528)
view.setShort(70, 1834)
}
NpcType.MaleMacho -> {
view.setShort(2, 2)
view.setShort(4, 1880)
@ -47,6 +51,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -8576)
view.setShort(70, 1834)
}
NpcType.MaleOld -> {
view.setShort(2, 2)
view.setShort(4, 1878)
@ -54,6 +59,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -10576)
view.setShort(70, 1834)
}
NpcType.BlueSoldier -> {
view.setShort(2, 2)
view.setShort(4, 1875)
@ -61,6 +67,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -13504)
view.setShort(70, 1834)
}
NpcType.RedSoldier -> {
view.setShort(2, 2)
view.setShort(4, 1874)
@ -68,12 +75,14 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -14480)
view.setShort(70, 1834)
}
NpcType.Principal -> {
view.setShort(4, 1888)
view.setShort(10, 5985)
view.setShort(68, -384)
view.setShort(70, 1834)
}
NpcType.Tekker -> {
view.setShort(2, 2)
view.setShort(4, 1879)
@ -81,6 +90,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -9600)
view.setShort(70, 1834)
}
NpcType.GuildLady -> {
view.setShort(2, 2)
view.setShort(4, 1891)
@ -88,6 +98,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 11584)
view.setShort(70, 1835)
}
NpcType.Scientist -> {
view.setShort(2, 2)
view.setShort(4, 1877)
@ -95,6 +106,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -11552)
view.setShort(70, 1834)
}
NpcType.Nurse -> {
view.setShort(2, 2)
view.setShort(4, 1884)
@ -102,24 +114,28 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -4480)
view.setShort(70, 1834)
}
NpcType.Irene -> {
view.setShort(4, 1889)
view.setShort(10, 5986)
view.setShort(68, 640)
view.setShort(70, 1835)
}
NpcType.ItemShop -> {
view.setShort(4, 8)
view.setShort(10, 6453)
view.setShort(68, 16560)
view.setShort(70, 1176)
}
NpcType.Nurse2 -> {
view.setShort(4, 2330)
view.setShort(10, 6496)
view.setShort(68, -13280)
view.setShort(70, 1200)
}
NpcType.Hildebear -> {
view.setShort(4, -1)
view.setShort(8, 2)
@ -128,16 +144,19 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 29968)
view.setShort(70, -29446)
}
NpcType.RagRappy -> {
view.setShort(8, 1)
view.setShort(10, -1)
view.setShort(68, 1072)
view.setShort(70, -29444)
}
NpcType.Monest -> {
view.setFloat(48, 5.000000953674316f) // Start number
view.setFloat(52, 10.000004768371582f) // Total number
}
NpcType.BarbarousWolf -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -145,10 +164,12 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 8576)
view.setShort(70, -29445)
}
NpcType.Booma -> {
view.setFloat(44, 0.30000001192092896f) // Scale x
view.setFloat(48, 40.00001907348633f) // Idle distance
}
NpcType.Gobooma -> {
view.setShort(8, 1)
view.setShort(10, -1)
@ -157,6 +178,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 11600)
view.setShort(70, -29444)
}
NpcType.Gigobooma -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -164,6 +186,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -4000)
view.setShort(70, -29446)
}
NpcType.Dragon -> {
view.setShort(4, 1173)
view.setShort(8, 11)
@ -171,6 +194,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 24624)
view.setShort(70, -29446)
}
NpcType.GrassAssassin -> view.setShort(8, 4)
NpcType.PoisonLily -> view.setShort(8, 4)
NpcType.NanoDragon -> view.setShort(8, 3)
@ -187,6 +211,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -11088)
view.setShort(70, -29445)
}
NpcType.Dubchic -> {
view.setShort(4, 2626)
view.setShort(8, 7)
@ -194,6 +219,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -25504)
view.setShort(70, 561)
}
NpcType.Gilchic -> {
view.setShort(4, -1)
view.setShort(8, 6)
@ -202,6 +228,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 5968)
view.setShort(70, -29444)
}
NpcType.Garanz -> {
view.setShort(4, -1)
view.setShort(8, 7)
@ -209,6 +236,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -26128)
view.setShort(70, 561)
}
NpcType.SinowBeat -> {
view.setShort(4, -1)
view.setShort(8, 6)
@ -216,6 +244,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 6288)
view.setShort(70, -29444)
}
NpcType.SinowGold -> {
view.setShort(4, -1)
view.setShort(8, 6)
@ -224,6 +253,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 8048)
view.setShort(70, -29444)
}
NpcType.Canadine -> {
view.setShort(4, -1)
view.setShort(8, 6)
@ -231,6 +261,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 8496)
view.setShort(70, -29444)
}
NpcType.Canane -> {
view.setShort(4, -1)
view.setShort(8, 6)
@ -238,6 +269,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 7264)
view.setShort(70, -29444)
}
NpcType.Dubswitch -> {
view.setShort(4, 2626)
view.setShort(8, 7)
@ -245,6 +277,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -16736)
view.setShort(70, 561)
}
NpcType.VolOptPart1 -> view.setShort(6, 35) // Clone count
NpcType.VolOptPart2 -> view.setShort(8, 13)
NpcType.DarkFalz -> {
@ -254,6 +287,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 25008)
view.setShort(70, -29446)
}
NpcType.Hildebear2 -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -262,6 +296,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7296)
view.setShort(70, -32759)
}
NpcType.RagRappy2 -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -269,6 +304,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7296)
view.setShort(70, 8201)
}
NpcType.Monest2 -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -278,6 +314,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7296)
view.setShort(70, -12252)
}
NpcType.PoisonLily2 -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -285,6 +322,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7296)
view.setShort(70, 8230)
}
NpcType.GrassAssassin2 -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -292,6 +330,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7296)
view.setShort(70, 24595)
}
NpcType.Dimenian2 -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -299,6 +338,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7296)
view.setShort(70, -4086)
}
NpcType.LaDimenian2 -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -306,6 +346,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7296)
view.setShort(70, -16367)
}
NpcType.SoDimenian2 -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -314,6 +355,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7040)
view.setShort(70, 8372)
}
NpcType.DarkBelra2 -> {
view.setShort(4, -1)
view.setShort(8, 1)
@ -321,6 +363,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7040)
view.setShort(70, -32642)
}
NpcType.BarbaRay -> {
view.setShort(4, -1)
view.setShort(8, 14)
@ -328,6 +371,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -2688)
view.setShort(70, 24576)
}
NpcType.SavageWolf2 -> {
view.setShort(4, 11785)
view.setShort(8, 3)
@ -335,6 +379,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 8250)
}
NpcType.BarbarousWolf2 -> {
view.setShort(4, -1)
view.setShort(8, 3)
@ -342,6 +387,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, -32650)
}
NpcType.PanArms2 -> {
view.setShort(4, -1)
view.setShort(8, 3)
@ -349,6 +395,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, -16251)
}
NpcType.Dubchic2 -> {
view.setShort(4, -1)
view.setShort(8, 3)
@ -356,6 +403,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 16513)
}
NpcType.Gilchic2 -> {
view.setShort(4, -1)
view.setShort(8, 3)
@ -363,6 +411,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, -32654)
}
NpcType.Garanz2 -> {
view.setShort(4, 27144)
view.setShort(8, 3)
@ -370,6 +419,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 24683)
}
NpcType.Dubswitch2 -> {
view.setShort(4, -1)
view.setShort(8, 3)
@ -377,6 +427,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, -20363)
}
NpcType.Delsaber2 -> {
view.setShort(4, -1)
view.setShort(8, 3)
@ -384,6 +435,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 16513)
}
NpcType.ChaosSorcerer2 -> {
view.setShort(4, -1)
view.setShort(8, 4)
@ -391,6 +443,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7296)
view.setShort(70, -7963)
}
NpcType.GolDragon -> {
view.setShort(4, -19963)
view.setShort(8, 15)
@ -398,6 +451,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -3712)
view.setShort(70, 16555)
}
NpcType.SinowBerill -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -407,6 +461,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 47)
}
NpcType.SinowSpigell -> {
view.setShort(4, 880)
view.setShort(8, 5)
@ -414,6 +469,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -11584)
view.setShort(70, 1163)
}
NpcType.Merillia -> {
view.setShort(4, -1)
view.setShort(8, 6)
@ -423,6 +479,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 16456)
}
NpcType.Meriltas -> {
view.setShort(4, -1)
view.setShort(8, 6)
@ -432,6 +489,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 16456)
}
NpcType.Mericarol -> {
view.setShort(4, -1)
view.setShort(8, 17)
@ -441,6 +499,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, -4016)
}
NpcType.Mericus -> {
view.setShort(4, 32010)
view.setShort(8, 17)
@ -450,6 +509,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 28762)
}
NpcType.Merikle -> {
view.setShort(4, 32010)
view.setShort(8, 17)
@ -459,6 +519,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, -3997)
}
NpcType.UlGibbon -> {
view.setShort(4, -1)
view.setShort(8, 6)
@ -467,6 +528,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 20554)
}
NpcType.ZolGibbon -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -474,6 +536,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -26688)
view.setShort(70, 565)
}
NpcType.Gibbles -> {
view.setShort(4, -1)
view.setShort(8, 17)
@ -483,6 +546,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, -12210)
}
NpcType.Gee -> {
view.setShort(4, -1)
view.setShort(8, 6)
@ -490,6 +554,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, -4024)
}
NpcType.GiGue -> {
view.setShort(4, 32010)
view.setShort(8, 17)
@ -499,6 +564,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 12374)
}
NpcType.IllGill -> {
view.setShort(4, 4104)
view.setShort(8, 17)
@ -506,6 +572,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 24639)
}
NpcType.DelLily -> {
view.setShort(4, -1)
view.setShort(8, 17)
@ -513,6 +580,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -26576)
view.setShort(70, 564)
}
NpcType.Epsilon -> {
view.setShort(4, -1)
view.setShort(8, 17)
@ -520,6 +588,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -4224)
view.setShort(70, -16379)
}
NpcType.GalGryphon -> {
view.setShort(4, 1173)
view.setShort(8, 11)
@ -527,6 +596,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 24624)
view.setShort(70, -29446)
}
NpcType.Deldepth -> {
view.setShort(4, 2095)
view.setShort(8, 11)
@ -534,6 +604,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -26352)
view.setShort(70, 665)
}
NpcType.Delbiter -> {
view.setShort(4, -1)
view.setShort(8, 11)
@ -545,6 +616,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 24639)
}
NpcType.Dolmolm -> {
view.setShort(4, -1)
view.setShort(8, 11)
@ -553,6 +625,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, 12370)
}
NpcType.Dolmdarl -> {
view.setShort(4, -1)
view.setShort(8, 11)
@ -561,6 +634,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -7552)
view.setShort(70, -4001)
}
NpcType.Morfos -> {
view.setShort(4, 1993)
view.setShort(8, 11)
@ -568,6 +642,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -25424)
view.setShort(70, 561)
}
NpcType.Recobox -> {
view.setShort(4, -1)
view.setShort(8, 11)
@ -575,6 +650,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -26160)
view.setShort(70, 686)
}
NpcType.SinowZoa -> {
view.setShort(4, 2634)
view.setShort(8, 11)
@ -583,6 +659,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -19488)
view.setShort(70, 665)
}
NpcType.SinowZele -> {
view.setShort(4, 2634)
view.setShort(8, 11)
@ -590,6 +667,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -25152)
view.setShort(70, 665)
}
NpcType.OlgaFlow -> {
view.setShort(4, -1)
view.setShort(8, 13)
@ -597,6 +675,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -4480)
view.setShort(70, -28572)
}
NpcType.SandRappy -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -604,6 +683,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -27344)
view.setShort(70, 616)
}
NpcType.DelRappy -> {
view.setShort(4, -1)
view.setShort(8, 3)
@ -611,6 +691,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -17168)
view.setShort(70, 410)
}
NpcType.Astark -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -618,6 +699,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -26896)
view.setShort(70, 616)
}
NpcType.SatelliteLizard -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -625,6 +707,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -27088)
view.setShort(70, 616)
}
NpcType.Yowie -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -633,6 +716,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -25872)
view.setShort(70, 616)
}
NpcType.MerissaA -> {
view.setShort(4, -1)
view.setShort(8, 7)
@ -640,6 +724,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -16512)
view.setShort(70, 542)
}
NpcType.MerissaAA -> {
view.setShort(4, -1)
view.setShort(8, 8)
@ -647,6 +732,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -27328)
view.setShort(70, 1230)
}
NpcType.Girtablulu -> {
view.setShort(4, -1)
view.setShort(8, 7)
@ -654,6 +740,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -26256)
view.setShort(70, 459)
}
NpcType.Zu -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -661,6 +748,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -28304)
view.setShort(70, 616)
}
NpcType.Pazuzu -> {
view.setShort(4, 937)
view.setShort(8, 3)
@ -668,6 +756,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -15216)
view.setShort(70, 410)
}
NpcType.Boota -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -675,6 +764,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -27216)
view.setShort(70, 616)
}
NpcType.ZeBoota -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -682,6 +772,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -20304)
view.setShort(70, 616)
}
NpcType.BaBoota -> {
view.setShort(4, -1)
view.setShort(8, 5)
@ -689,6 +780,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -14800)
view.setShort(70, 616)
}
NpcType.Dorphon -> {
view.setShort(4, 2308)
view.setShort(8, 5)
@ -696,6 +788,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -26480)
view.setShort(70, 616)
}
NpcType.DorphonEclair -> {
view.setShort(4, 951)
view.setShort(8, 3)
@ -703,6 +796,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -30064)
view.setShort(70, 410)
}
NpcType.Goran -> {
view.setShort(4, -1)
view.setShort(8, 8)
@ -710,6 +804,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -27216)
view.setShort(70, 610)
}
NpcType.PyroGoran -> {
view.setShort(4, -1)
view.setShort(8, 7)
@ -717,6 +812,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -16384)
view.setShort(70, 542)
}
NpcType.GoranDetonator -> {
view.setShort(4, -1)
view.setShort(8, 7)
@ -724,6 +820,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, -16384)
view.setShort(70, 542)
}
NpcType.SaintMilion -> {
view.setShort(4, 1297)
view.setShort(6, 24) // Clone count
@ -732,6 +829,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 28144)
view.setShort(70, 673)
}
NpcType.Shambertin -> {
view.setShort(4, 1362)
view.setShort(6, 24) // Clone count
@ -741,5 +839,7 @@ internal fun setNpcDefaultData(type: NpcType, view: Buffer) {
view.setShort(68, 31280)
view.setShort(70, 491)
}
else -> {}
}
}

View File

@ -11,7 +11,7 @@ plugins {
version = "0.0.1"
/** Source code generated by the build script goes here. */
val generatedSrc = File(buildDir, "generated-src/main/kotlin")
val generatedSrc = layout.buildDirectory.get().asFile.resolve("generated-src/main/kotlin")
kotlin {
sourceSets {
@ -25,19 +25,21 @@ val generateVersionInfo by tasks.registering {
group = "code generation"
val packageName = "world.phantasmal.psoserv"
val outputFile = File(generatedSrc, "${packageName.replace('.', '/')}/VersionInfo.kt")
val outputFile = generatedSrc.resolve("${packageName.replace('.', '/')}/VersionInfo.kt")
inputs.property("version", version)
outputs.file(outputFile)
doLast {
outputFile.writeText("""
outputFile.writeText(
"""
package $packageName
object VersionInfo {
val version: String = "$version"
}
""".trimIndent())
""".trimIndent()
)
}
}
@ -46,7 +48,7 @@ tasks.withType<KotlinCompile>().configureEach {
}
val mainClassFqn = "world.phantasmal.psoserv.MainKt"
val nativeAgentOutputDir = File(buildDir, "agent-output")
val nativeAgentOutputDir = layout.buildDirectory.get().asFile.resolve("agent-output")
application {
mainClass.set(mainClassFqn)

View File

@ -1,3 +1,7 @@
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}
rootProject.name = "phantasmal-world"
include(

View File

@ -4,8 +4,14 @@ import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.promise
internal actual fun testAsync(block: suspend () -> Unit): dynamic =
// We need to return the promise here while still letting the type checker think we're not returning
// anything, i.e. returning Unit. The Mocha JS test framework needs this promise to be able to wait
// for test completion. This is a giant hack, and at this point we should probably switch to using
// the kotlinx-coroutines-test library.
internal actual fun testAsync(block: suspend () -> Unit): Unit =
@Suppress("UnsafeCastFromDynamic")
@OptIn(DelicateCoroutinesApi::class)
GlobalScope.promise { block() }
GlobalScope.promise { block() }.asDynamic()
// KJS is relatively slow, so we don't execute the slow tests on KJS.
internal actual fun canExecuteSlowTests(): Boolean = false

View File

@ -4,16 +4,20 @@ plugins {
kotlin {
js {
compilations.configureEach {
languageSettings.optIn("kotlinx.serialization.ExperimentalSerializationApi")
}
binaries.executable()
}
}
dependencies {
api(project(":web:shared"))
sourceSets {
getByName("jsMain") {
dependencies {
api(project(":web:shared"))
}
}
testImplementation(project(":test-utils"))
getByName("jsTest") {
dependencies {
implementation(project(":test-utils"))
}
}
}
}

View File

@ -379,6 +379,8 @@ class AsmAnalyser {
)
}
}
else -> {}
}
return Response.GetHighlights(requestId, results)

View File

@ -15,7 +15,7 @@ dependencies {
}
tasks.register<JavaExec>("generateAssets") {
val outputFile = File(buildDir, "generatedAssets")
val outputFile = layout.buildDirectory.get().asFile.resolve("generatedAssets")
outputs.dir(outputFile)
classpath = sourceSets.main.get().runtimeClasspath

View File

@ -1,62 +1,70 @@
plugins {
id("world.phantasmal.js")
kotlin("plugin.serialization")
}
kotlin {
js {
compilations.configureEach {
languageSettings.optIn("kotlinx.serialization.ExperimentalSerializationApi")
}
browser {
commonWebpackConfig {
cssSupport.enabled = true
}
runTask {
devServer = devServer!!.copy(
open = false,
port = 1623,
)
}
}
binaries.executable()
}
}
val ktorVersion: String by project.extra
val serializationVersion: String by project.extra
dependencies {
implementation(project(":psolib"))
implementation(project(":webui"))
implementation(project(":web:shared"))
kotlin {
js {
browser {
commonWebpackConfig {
cssSupport { enabled.set(true) }
}
runTask {
devServerProperty.set(
devServerProperty.get().copy(
open = false,
port = 1623,
)
)
}
}
binaries.executable()
}
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-serialization:$ktorVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.1")
implementation(npm("golden-layout", "^1.5.9"))
implementation(npm("monaco-editor", "0.26.1"))
implementation(npm("three", "^0.128.0"))
implementation(npm("javascript-lp-solver", "0.4.17"))
sourceSets {
getByName("jsMain") {
dependencies {
implementation(project(":psolib"))
implementation(project(":webui"))
implementation(project(":web:shared"))
implementation(devNpm("file-loader", "^6.2.0"))
implementation(devNpm("monaco-editor-webpack-plugin", "4.1.1"))
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0")
implementation(npm("golden-layout", "^1.5.9"))
implementation(npm("monaco-editor", "0.26.1"))
implementation(npm("three", "^0.128.0"))
implementation(npm("javascript-lp-solver", "0.4.17"))
testImplementation(project(":test-utils"))
implementation(devNpm("file-loader", "^6.2.0"))
implementation(devNpm("monaco-editor-webpack-plugin", "4.1.1"))
}
}
getByName("jsTest") {
dependencies {
implementation(project(":test-utils"))
}
}
}
}
val copyAssemblyWorkerJsTask = tasks.register<Copy>("copyAssemblyWorkerJs") {
dependsOn(":web:assembly-worker:build")
val workerDist = project(":web:assembly-worker").buildDir.resolve("distributions")
val workerDist =
project(":web:assembly-worker").layout.buildDirectory.get().asFile.resolve("dist/js/productionExecutable")
from(workerDist.resolve("assembly-worker.js"), workerDist.resolve("assembly-worker.js.map"))
into(buildDir.resolve("processedResources/js/main"))
into(layout.buildDirectory.get().asFile.resolve("processedResources/js/main"))
}
// TODO: Figure out how to make this work with --continuous.
tasks.named("processResources").configure { dependsOn(copyAssemblyWorkerJsTask) }
tasks.named("jsProcessResources").configure { dependsOn(copyAssemblyWorkerJsTask) }
tasks.register<Copy>("generateAssets") {
dependsOn(":web:assets-generation:generateAssets")

View File

@ -1,8 +1,9 @@
package world.phantasmal.web
import io.ktor.client.*
import io.ktor.client.features.json.*
import io.ktor.client.features.json.serializer.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.http.*
import io.ktor.serialization.kotlinx.*
import kotlinx.browser.document
import kotlinx.browser.window
import kotlinx.coroutines.cancel
@ -49,8 +50,8 @@ private fun init(): Disposable {
val rootElement = document.body!!.root()
val httpClient = HttpClient {
install(JsonFeature) {
serializer = KotlinxSerializer(JSON_FORMAT)
install(ContentNegotiation) {
serialization(ContentType.Application.Json, JSON_FORMAT)
}
}
disposer.add(disposable { httpClient.cancel() })

View File

@ -58,7 +58,7 @@ fun euler(x: Double, y: Double, z: Double): Euler =
fun Euler.toQuaternion(): Quaternion =
Quaternion().setFromEuler(this)
@OptIn(ExperimentalContracts::class)
@Suppress("NOTHING_TO_INLINE")
inline fun Object3D.isMesh(): Boolean {
contract {
returns(true) implies (this@isMesh is Mesh)
@ -67,7 +67,7 @@ inline fun Object3D.isMesh(): Boolean {
return unsafeCast<Mesh>().isMesh
}
@OptIn(ExperimentalContracts::class)
@Suppress("NOTHING_TO_INLINE")
inline fun Object3D.isSkinnedMesh(): Boolean {
contract {
returns(true) implies (this@isSkinnedMesh is SkinnedMesh)

View File

@ -0,0 +1,43 @@
package world.phantasmal.web.core.loading
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.util.reflect.*
import io.ktor.utils.io.js.*
import kotlinx.browser.window
import org.khronos.webgl.ArrayBuffer
class AssetLoader(
private val httpClient: HttpClient,
private val origin: String = window.location.origin,
private val basePath: String = defaultBasePath(),
) {
suspend inline fun <reified T : Any> load(path: String): T =
load(path, typeInfo<T>())
suspend fun <T : Any> load(path: String, typeInfo: TypeInfo): T =
get(path).body(typeInfo)
suspend fun loadArrayBuffer(path: String): ArrayBuffer =
get(path).bodyAsChannel().readRemaining().readArrayBuffer()
private suspend fun get(path: String): HttpResponse =
httpClient.get("$origin$basePath$path")
companion object {
fun defaultBasePath(): String {
val pathname = window.location.pathname
val appPath =
if (pathname.endsWith(".html")) {
pathname.substring(0, pathname.lastIndexOf('/'))
} else {
pathname.removeSuffix("/")
}
return "$appPath/assets"
}
}
}

View File

@ -1,4 +1,4 @@
package world.phantasmal.web.questEditor.loading
package world.phantasmal.web.core.loading
import kotlinx.coroutines.*
import world.phantasmal.core.disposable.TrackedDisposable

View File

@ -11,10 +11,14 @@ fun vec2ToThree(v: Vec2): Vector2 = Vector2(v.x.toDouble(), v.y.toDouble())
fun vec3ToThree(v: Vec3): Vector3 = Vector3(v.x.toDouble(), v.y.toDouble(), v.z.toDouble())
// Inline to generate easier to understand JS.
@Suppress("NOTHING_TO_INLINE")
inline fun Vector3.setFromVec3(v: Vec3) {
set(v.x.toDouble(), v.y.toDouble(), v.z.toDouble())
}
// Inline to generate easier to understand JS.
@Suppress("NOTHING_TO_INLINE")
inline fun Euler.setFromVec3(v: Vec3) {
set(v.x.toDouble(), v.y.toDouble(), v.z.toDouble())
}

View File

@ -4,7 +4,7 @@ import world.phantasmal.core.unsafe.UnsafeMap
import world.phantasmal.psolib.fileFormats.quest.NpcType
import world.phantasmal.web.core.loading.AssetLoader
import world.phantasmal.web.core.models.Server
import world.phantasmal.web.questEditor.loading.LoadingCache
import world.phantasmal.web.core.loading.LoadingCache
import world.phantasmal.web.shared.dto.Difficulty
import world.phantasmal.web.shared.dto.EnemyDrop
import world.phantasmal.web.shared.dto.ItemType

View File

@ -2,7 +2,7 @@ package world.phantasmal.web.core.stores
import world.phantasmal.web.core.loading.AssetLoader
import world.phantasmal.web.core.models.Server
import world.phantasmal.web.questEditor.loading.LoadingCache
import world.phantasmal.web.core.loading.LoadingCache
import world.phantasmal.web.shared.dto.ItemType
import world.phantasmal.webui.stores.Store

View File

@ -91,9 +91,11 @@ class DockWidget(
} catch (e: Exception) {
logger.error(e) { """Couldn't instantiate widget with ID "$id".""" }
node.addChild(UnavailableWidget(
message = "Something went wrong while initializing this tab.",
))
node.addChild(
UnavailableWidget(
message = "Something went wrong while initializing this tab.",
)
)
}
idToChildWidget[id] = widget
@ -239,7 +241,7 @@ class DockWidget(
"component" -> {
val id =
(item.unsafeCast<GoldenLayout.ComponentConfig>()).componentName as String?
(item.unsafeCast<GoldenLayout.ComponentConfig>()).componentName
val title = item.title
if (id == null || title == null) {
@ -257,7 +259,8 @@ class DockWidget(
// Use #pw-root for higher specificity than the default GoldenLayout CSS.
@Suppress("CssUnusedSymbol", "CssUnresolvedCustomProperty", "CssInvalidPropertyValue")
// language=css
style("""
style(
"""
.pw-core-dock {
overflow: hidden;
}
@ -348,7 +351,8 @@ class DockWidget(
box-sizing: border-box;
background-color: hsla(0, 0%, 50%, 0.2);
}
""".trimIndent())
""".trimIndent()
)
}
}
}

View File

@ -55,7 +55,7 @@ external class GoldenLayout(configuration: Config, container: Element = definedE
}
interface ComponentConfig : ItemConfig {
var componentName: String
var componentName: String?
var componentState: Any?
}

View File

@ -45,9 +45,9 @@ external interface ITokenThemeRule {
var fontStyle: String?
}
external enum class ScrollType {
Smooth /* = 0 */,
Immediate /* = 1 */
sealed external class ScrollType {
object Smooth : ScrollType /* = 0 */
object Immediate : ScrollType /* = 1 */
}
external interface IDimension {
@ -134,21 +134,21 @@ external interface IEditor {
fun setModel(model: ITextModel?)
}
external enum class MouseTargetType {
UNKNOWN /* = 0 */,
TEXTAREA /* = 1 */,
GUTTER_GLYPH_MARGIN /* = 2 */,
GUTTER_LINE_NUMBERS /* = 3 */,
GUTTER_LINE_DECORATIONS /* = 4 */,
GUTTER_VIEW_ZONE /* = 5 */,
CONTENT_TEXT /* = 6 */,
CONTENT_EMPTY /* = 7 */,
CONTENT_VIEW_ZONE /* = 8 */,
CONTENT_WIDGET /* = 9 */,
OVERVIEW_RULER /* = 10 */,
SCROLLBAR /* = 11 */,
OVERLAY_WIDGET /* = 12 */,
OUTSIDE_EDITOR /* = 13 */,
sealed external class MouseTargetType {
object UNKNOWN : MouseTargetType /* = 0 */
object TEXTAREA : MouseTargetType /* = 1 */
object GUTTER_GLYPH_MARGIN : MouseTargetType /* = 2 */
object GUTTER_LINE_NUMBERS : MouseTargetType /* = 3 */
object GUTTER_LINE_DECORATIONS : MouseTargetType /* = 4 */
object GUTTER_VIEW_ZONE : MouseTargetType /* = 5 */
object CONTENT_TEXT : MouseTargetType /* = 6 */
object CONTENT_EMPTY : MouseTargetType /* = 7 */
object CONTENT_VIEW_ZONE : MouseTargetType /* = 8 */
object CONTENT_WIDGET : MouseTargetType /* = 9 */
object OVERVIEW_RULER : MouseTargetType /* = 10 */
object SCROLLBAR : MouseTargetType /* = 11 */
object OVERLAY_WIDGET : MouseTargetType /* = 12 */
object OUTSIDE_EDITOR : MouseTargetType /* = 13 */
}
external interface IMouseTarget {
@ -460,26 +460,26 @@ external interface IColorizerElementOptions : IColorizerOptions {
var mimeType: String?
}
external enum class ScrollbarVisibility {
Auto /* = 1 */,
Hidden /* = 2 */,
Visible /* = 3 */
sealed external class ScrollbarVisibility {
object Auto : ScrollbarVisibility /* = 1 */
object Hidden : ScrollbarVisibility /* = 2 */
object Visible : ScrollbarVisibility /* = 3 */
}
external interface ThemeColor {
var id: String
}
external enum class OverviewRulerLane {
Left /* = 1 */,
Center /* = 2 */,
Right /* = 4 */,
Full /* = 7 */
sealed external class OverviewRulerLane {
object Left : OverviewRulerLane /* = 1 */
object Center : OverviewRulerLane /* = 2 */
object Right : OverviewRulerLane /* = 4 */
object Full : OverviewRulerLane /* = 7 */
}
external enum class MinimapPosition {
Inline /* = 1 */,
Gutter /* = 2 */
sealed external class MinimapPosition {
object Inline : MinimapPosition /* = 1 */
object Gutter : MinimapPosition /* = 2 */
}
external interface IDecorationOptions {
@ -532,20 +532,20 @@ external interface IWordAtPosition {
var endColumn: Number
}
external enum class EndOfLinePreference {
TextDefined /* = 0 */,
LF /* = 1 */,
CRLF /* = 2 */
sealed external class EndOfLinePreference {
object TextDefined : EndOfLinePreference /* = 0 */
object LF : EndOfLinePreference /* = 1 */
object CRLF : EndOfLinePreference /* = 2 */
}
external enum class DefaultEndOfLine {
LF /* = 1 */,
CRLF /* = 2 */
sealed external class DefaultEndOfLine {
object LF : DefaultEndOfLine /* = 1 */
object CRLF : DefaultEndOfLine /* = 2 */
}
external enum class EndOfLineSequence {
LF /* = 0 */,
CRLF /* = 1 */
sealed external class EndOfLineSequence {
object LF : EndOfLineSequence /* = 0 */
object CRLF : EndOfLineSequence /* = 1 */
}
external interface ISingleEditOperation {
@ -589,11 +589,11 @@ open external class FindMatch {
open var matches: Array<String>?
}
external enum class TrackedRangeStickiness {
AlwaysGrowsWhenTypingAtEdges /* = 0 */,
NeverGrowsWhenTypingAtEdges /* = 1 */,
GrowsOnlyWhenTypingBefore /* = 2 */,
GrowsOnlyWhenTypingAfter /* = 3 */
sealed external class TrackedRangeStickiness {
object AlwaysGrowsWhenTypingAtEdges : TrackedRangeStickiness /* = 0 */
object NeverGrowsWhenTypingAtEdges : TrackedRangeStickiness /* = 1 */
object GrowsOnlyWhenTypingBefore : TrackedRangeStickiness /* = 2 */
object GrowsOnlyWhenTypingAfter : TrackedRangeStickiness /* = 3 */
}
external interface ITextModel {
@ -787,14 +787,14 @@ external interface IModelOptionsChangedEvent {
var trimAutoWhitespace: Boolean
}
external enum class CursorChangeReason {
NotSet /* = 0 */,
ContentFlush /* = 1 */,
RecoverFromMarkers /* = 2 */,
Explicit /* = 3 */,
Paste /* = 4 */,
Undo /* = 5 */,
Redo /* = 6 */
sealed external class CursorChangeReason {
object NotSet : CursorChangeReason /* = 0 */
object ContentFlush : CursorChangeReason /* = 1 */
object RecoverFromMarkers : CursorChangeReason /* = 2 */
object Explicit : CursorChangeReason /* = 3 */
object Paste : CursorChangeReason /* = 4 */
object Undo : CursorChangeReason /* = 5 */
object Redo : CursorChangeReason /* = 6 */
}
external interface ICursorPositionChangedEvent {
@ -814,16 +814,16 @@ external interface ICursorSelectionChangedEvent {
var reason: CursorChangeReason
}
external enum class AccessibilitySupport {
Unknown /* = 0 */,
Disabled /* = 1 */,
Enabled /* = 2 */
sealed external class AccessibilitySupport {
object Unknown : AccessibilitySupport /* = 0 */
object Disabled : AccessibilitySupport /* = 1 */
object Enabled : AccessibilitySupport /* = 2 */
}
external enum class EditorAutoIndentStrategy {
None /* = 0 */,
Keep /* = 1 */,
Brackets /* = 2 */,
Advanced /* = 3 */,
Full /* = 4 */
sealed external class EditorAutoIndentStrategy {
object None : EditorAutoIndentStrategy /* = 0 */
object Keep : EditorAutoIndentStrategy /* = 1 */
object Brackets : EditorAutoIndentStrategy /* = 2 */
object Advanced : EditorAutoIndentStrategy /* = 3 */
object Full : EditorAutoIndentStrategy /* = 4 */
}

View File

@ -1,8 +1,12 @@
package world.phantasmal.web.externals.monacoEditor
// Inline to generate easier to understand JS.
@Suppress("NOTHING_TO_INLINE")
inline operator fun IColors.get(name: String): String =
asDynamic()[name].unsafeCast<String>()
// Inline to generate easier to understand JS.
@Suppress("NOTHING_TO_INLINE")
inline operator fun IColors.set(name: String, value: String) {
asDynamic()[name] = value
}

View File

@ -152,11 +152,11 @@ external interface IAutoClosingPairConditional : IAutoClosingPair {
set(value) = definedExternally
}
external enum class IndentAction {
None /* = 0 */,
Indent /* = 1 */,
IndentOutdent /* = 2 */,
Outdent /* = 3 */
sealed external class IndentAction {
object None : IndentAction /* = 0 */
object Indent : IndentAction /* = 1 */
object IndentOutdent : IndentAction /* = 2 */
object Outdent : IndentAction /* = 3 */
}
external interface EnterAction {
@ -271,50 +271,51 @@ external interface CompletionItemRanges {
var replace: IRange
}
external enum class CompletionItemKind {
Method /* = 0 */,
Function /* = 1 */,
Constructor /* = 2 */,
Field /* = 3 */,
Variable /* = 4 */,
Class /* = 5 */,
Struct /* = 6 */,
Interface /* = 7 */,
Module /* = 8 */,
Property /* = 9 */,
Event /* = 10 */,
Operator /* = 11 */,
Unit /* = 12 */,
Value /* = 13 */,
Constant /* = 14 */,
Enum /* = 15 */,
EnumMember /* = 16 */,
Keyword /* = 17 */,
Text /* = 18 */,
Color /* = 19 */,
File /* = 20 */,
Reference /* = 21 */,
Customcolor /* = 22 */,
Folder /* = 23 */,
TypeParameter /* = 24 */,
Snippet /* = 25 */,
sealed external class CompletionItemKind {
object Method : CompletionItemKind /* = 0 */
object Function : CompletionItemKind /* = 1 */
object Constructor : CompletionItemKind /* = 2 */
object Field : CompletionItemKind /* = 3 */
object Variable : CompletionItemKind /* = 4 */
object Class : CompletionItemKind /* = 5 */
object Struct : CompletionItemKind /* = 6 */
object Interface : CompletionItemKind /* = 7 */
object Module : CompletionItemKind /* = 8 */
object Property : CompletionItemKind /* = 9 */
object Event : CompletionItemKind /* = 10 */
object Operator : CompletionItemKind /* = 11 */
object Unit : CompletionItemKind /* = 12 */
object Value : CompletionItemKind /* = 13 */
object Constant : CompletionItemKind /* = 14 */
object Enum : CompletionItemKind /* = 15 */
object EnumMember : CompletionItemKind /* = 16 */
object Keyword : CompletionItemKind /* = 17 */
object Text : CompletionItemKind /* = 18 */
object Color : CompletionItemKind /* = 19 */
object File : CompletionItemKind /* = 20 */
object Reference : CompletionItemKind /* = 21 */
object Customcolor : CompletionItemKind /* = 22 */
object Folder : CompletionItemKind /* = 23 */
object TypeParameter : CompletionItemKind /* = 24 */
object Snippet : CompletionItemKind /* = 25 */
}
external enum class CompletionItemTag {
Deprecated /* = 1 */,
sealed external class CompletionItemTag {
object Deprecated : CompletionItemTag
}
external enum class CompletionItemInsertTextRule {
sealed external class CompletionItemInsertTextRule {
/**
* Adjust whitespace/indentation of multiline insert texts to
* match the current line indentation.
*/
KeepWhitespace /* = 1 */,
object KeepWhitespace : CompletionItemInsertTextRule
/**
* `insertText` is a snippet.
*/
InsertAsSnippet /* = 4 */,
object InsertAsSnippet : CompletionItemInsertTextRule
}
external interface Command {
@ -434,10 +435,10 @@ external interface CompletionList {
/**
* How a suggest provider was triggered.
*/
external enum class CompletionTriggerKind {
Invoke /* = 0 */,
TriggerCharacter /* = 1 */,
TriggerForIncompleteCompletions /* = 2 */,
sealed external class CompletionTriggerKind {
object Invoke : CompletionTriggerKind
object TriggerCharacter : CompletionTriggerKind
object TriggerForIncompleteCompletions : CompletionTriggerKind
}
/**
@ -548,10 +549,10 @@ external interface SignatureHelp {
var activeParameter: Int
}
external enum class SignatureHelpTriggerKind {
Invoke /* = 1 */,
TriggerCharacter /* = 2 */,
ContentChange /* = 3 */,
sealed external class SignatureHelpTriggerKind {
object Invoke : SignatureHelpTriggerKind
object TriggerCharacter : SignatureHelpTriggerKind
object ContentChange : SignatureHelpTriggerKind
}
external interface SignatureHelpContext {
@ -658,37 +659,37 @@ external interface DefinitionProvider {
): Promise<Array<LocationLink>?>
}
external enum class SymbolKind {
File /* = 0 */,
Module /* = 1 */,
Namespace /* = 2 */,
Package /* = 3 */,
Class /* = 4 */,
Method /* = 5 */,
Property /* = 6 */,
Field /* = 7 */,
Constructor /* = 8 */,
Enum /* = 9 */,
Interface /* = 10 */,
Function /* = 11 */,
Variable /* = 12 */,
Constant /* = 13 */,
String /* = 14 */,
Number /* = 15 */,
Boolean /* = 16 */,
Array /* = 17 */,
Object /* = 18 */,
Key /* = 19 */,
Null /* = 20 */,
EnumMember /* = 21 */,
Struct /* = 22 */,
Event /* = 23 */,
Operator /* = 24 */,
TypeParameter /* = 25 */
sealed external class SymbolKind {
object File : SymbolKind
object Module : SymbolKind
object Namespace : SymbolKind
object Package : SymbolKind
object Class : SymbolKind
object Method : SymbolKind
object Property : SymbolKind
object Field : SymbolKind
object Constructor : SymbolKind
object Enum : SymbolKind
object Interface : SymbolKind
object Function : SymbolKind
object Variable : SymbolKind
object Constant : SymbolKind
object String : SymbolKind
object Number : SymbolKind
object Boolean : SymbolKind
object Array : SymbolKind
object Object : SymbolKind
object Key : SymbolKind
object Null : SymbolKind
object EnumMember : SymbolKind
object Struct : SymbolKind
object Event : SymbolKind
object Operator : SymbolKind
object TypeParameter : SymbolKind /* = 25 */
}
external enum class SymbolTag {
Deprecated /* = 1 */
sealed external class SymbolTag {
object Deprecated : SymbolTag /* = 1 */
}
external interface DocumentSymbol {
@ -711,10 +712,10 @@ external interface DocumentSymbolProvider {
): Promise<Array<DocumentSymbol>>
}
external enum class DocumentHighlightKind {
Text /* = 0 */,
Read /* = 1 */,
Write /* = 2 */
sealed external class DocumentHighlightKind {
object Text : DocumentHighlightKind
object Read : DocumentHighlightKind
object Write : DocumentHighlightKind /* = 2 */
}
external interface DocumentHighlight {

View File

@ -2,9 +2,13 @@ package world.phantasmal.web.externals.monacoEditor
typealias IMonarchLanguageRule = IExpandedMonarchLanguageRule
// Inline to generate easier to understand JS.
@Suppress("NOTHING_TO_INLINE")
inline operator fun IMonarchLanguageTokenizer.get(name: String): Array<IMonarchLanguageRule> =
asDynamic()[name].unsafeCast<Array<IMonarchLanguageRule>>()
// Inline to generate easier to understand JS.
@Suppress("NOTHING_TO_INLINE")
inline operator fun IMonarchLanguageTokenizer.set(
name: String,
value: Array<IMonarchLanguageRule>,
@ -12,9 +16,13 @@ inline operator fun IMonarchLanguageTokenizer.set(
asDynamic()[name] = value
}
// Inline to generate easier to understand JS.
@Suppress("NOTHING_TO_INLINE")
inline operator fun IMarkdownStringUris.get(name: String): UriComponents =
asDynamic()[name].unsafeCast<UriComponents>()
// Inline to generate easier to understand JS.
@Suppress("NOTHING_TO_INLINE")
inline operator fun IMarkdownStringUris.set(name: String, value: UriComponents) {
asDynamic()[name] = value
}

View File

@ -20,16 +20,16 @@ external interface CancellationToken {
): IDisposable
}
external enum class MarkerTag {
Unnecessary /* = 1 */,
Deprecated /* = 2 */
sealed external class MarkerTag {
object Unnecessary : MarkerTag /* = 1 */
object Deprecated : MarkerTag /* = 2 */
}
external enum class MarkerSeverity {
Hint /* = 1 */,
Info /* = 2 */,
Warning /* = 4 */,
Error /* = 8 */
sealed external class MarkerSeverity {
object Hint : MarkerSeverity /* = 1 */
object Info : MarkerSeverity /* = 2 */
object Warning : MarkerSeverity /* = 4 */
object Error : MarkerSeverity /* = 8 */
}
external interface IRange {
@ -126,9 +126,9 @@ open external class Selection(
}
}
external enum class SelectionDirection {
LTR /* = 0 */,
RTL /* = 1 */
sealed external class SelectionDirection {
object LTR : SelectionDirection /* = 0 */
object RTL : SelectionDirection /* = 1 */
}
external interface IPosition {

View File

@ -786,20 +786,20 @@ external interface Mipmap {
var height: Int
}
external enum class MOUSE {
LEFT,
MIDDLE,
RIGHT,
ROTATE,
DOLLY,
PAN,
sealed external class MOUSE {
object LEFT : MOUSE
object MIDDLE : MOUSE
object RIGHT : MOUSE
object ROTATE : MOUSE
object DOLLY : MOUSE
object PAN : MOUSE
}
external enum class TOUCH {
ROTATE,
PAN,
DOLLY_PAN,
DOLLY_ROTATE,
sealed external class TOUCH {
object ROTATE : TOUCH
object PAN : TOUCH
object DOLLY_PAN : TOUCH
object DOLLY_ROTATE : TOUCH
}
external class Raycaster(

Some files were not shown because too many files have changed in this diff Show More