diff --git a/asd.md b/asd.md new file mode 100644 index 0000000..669dfcc --- /dev/null +++ b/asd.md @@ -0,0 +1,63 @@ +How I can run a npx Gradle task with Kotlin/JS? + +I have a project that includes some dependencies downloaded from NPM and source code in Typescript. + +I want to use [TypeScriptToLua](https://typescripttolua.github.io/) to convert my Typescript files +into Lua. + +I see that Kotlin/JS has two + +https://github.com/JetBrains/kotlin/blob/b76cbdaa41c8cae04d8bd1bd857186d7835045b5/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmProject.kt#L86 + +```kotlin +fun useTool( + exec: ExecSpec, + tool: String, + nodeArgs: List = listOf(), + args: List +) { + exec.workingDir = dir + exec.executable = nodeExecutable + exec.args = nodeArgs + require(tool) + args +} +``` + +https://github.com/JetBrains/kotlin/blob/92d200e093c693b3c06e53a39e0b0973b84c7ec5/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/dukat/DukatRunner.kt#L47 + +```kotlin +npmProject.useTool( + exec, + "dukat/bin/dukat-cli.js", + listOf(), + args +) +``` + +https://github.com/JetBrains/kotlin/blob/711b882e7176060fc7fe2968773a393c7be73cb8/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt + +In `build.gradle.kts` I've configured the Kotlin Multiplatform plugin to download +the `typescript-to-lua` dependency + +```kotlin +plugins { + kotlin("multiplatform") +} + +kotlin { + js(IR) { + browser() + } + + sourceSets { + val jsMain: KotlinSourceSet by getting { + dependencies { + implementation(npm("typescript-to-lua", "1.1.1")) + } + } + } +} +``` + +and this correctly downloads the NPM module binaries: +`build/js/packages/data-model/node_modules/.bin/tstl` + diff --git a/build.gradle.kts b/build.gradle.kts index 7cdb0ce..1d51ecb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ group = "dev.adamko.factoriowebmap" version = "0.0.3" tasks.wrapper { - gradleVersion = "7.2" + gradleVersion = "7.3" distributionType = Wrapper.DistributionType.ALL } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1c9ab46..f07747a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,8 +1,27 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { + idea `kotlin-dsl` kotlin("jvm") version "1.5.31" + `java-gradle-plugin` +} + +gradlePlugin { + plugins { + create("tstl") { + id = "dev.adamko.tstl" + description = + "Gradle plugin for TypescriptToLua. Requires plugin `com.github.node-gradle.node`." + implementationClass = "dev.adamko.gradle.tstl.TstlPlugin" + } + create("json-kotlin-schema-gen") { + id = "dev.adamko.json-kotlin-schema-gen" + description = + "Gradle plugin for 'json-kotlin-schema-codegen' - Code generation for JSON Schema (Draft 07) https://github.com/pwall567/json-kotlin-schema-codegen" + implementationClass = "dev.adamko.gradle.jsonkotlinschemagen.JsonKotlinSchemaGenPlugin" + } + } } dependencies { @@ -21,18 +40,43 @@ dependencies { implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") + implementation("net.pwall.json:json-kotlin-schema-codegen:0.53") } +val projectJvmTarget = "11" + tasks.withType().configureEach { kotlinOptions { - jvmTarget = "11" + jvmTarget = projectJvmTarget + apiVersion = "1.5" + languageVersion = "1.5" } kotlinOptions.freeCompilerArgs += listOf( "-Xopt-in=kotlin.OptIn", + "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.time.ExperimentalTime", "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", ) -} \ No newline at end of file +} + + +kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(projectJvmTarget)) + } + + kotlinDslPluginOptions { + jvmTarget.set(projectJvmTarget) + } +} + +idea { + module { + isDownloadSources = true + isDownloadJavadoc = true + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts index 49c8445..4d1d5e9 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts @@ -26,7 +26,7 @@ kotlin { } dependencies { - val kotlinWrappersVersion = "0.0.1-pre.259-kotlin-1.5.31" + val kotlinWrappersVersion = "0.0.1-pre.263-kotlin-1.5.31" implementation( project.dependencies.enforcedPlatform( "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" @@ -48,7 +48,7 @@ val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) val nodePath: Directory by extra { val file = rootPackageJson.rootPackageJson.parentFile.normalize() logger.lifecycle("Kotlin/JS NODE_PATH: $file") - project.layout.dir(provider { file }).get() + project.layout.dir(project.provider { file }).get() } val nodeModulesDir: Directory by extra { @@ -56,14 +56,3 @@ val nodeModulesDir: Directory by extra { logger.lifecycle("Kotlin/JS NODE_MODULES: $file") file } - -node { - download.set(true) - version.set("14.18.0") - - distBaseUrl.set(null as String?) // set by dependencyResolutionManagement - -// nodeProjectDir.set(nodePath) -// nodeProjectDir.set(packageJson.packageJson.parentFile.normalize()) -} - diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts index f96fb0c..913b1a8 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts @@ -43,11 +43,20 @@ dependencies { } tasks.withType().configureEach { + + kotlinOptions { + jvmTarget = "11" + apiVersion = "1.5" + languageVersion = "1.5" + } + kotlinOptions.freeCompilerArgs += listOf( "-Xopt-in=kotlin.OptIn", + "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.time.ExperimentalTime", "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts new file mode 100644 index 0000000..e110efb --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts @@ -0,0 +1,22 @@ +package dev.adamko.factoriowebmap.archetype + +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension + + +plugins { + id("dev.adamko.factoriowebmap.archetype.base") + id("dev.adamko.factoriowebmap.archetype.node") + kotlin("multiplatform") +} + + +afterEvaluate { + + rootProject.extensions.configure { + val projectNodeInstallDir = file("$rootDir/.gradle").resolve("nodejs") + if (installationDir != projectNodeInstallDir) { + installationDir = projectNodeInstallDir + } + } + +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts index cb83376..77788fc 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts @@ -2,7 +2,10 @@ package dev.adamko.factoriowebmap.archetype import org.gradle.kotlin.dsl.kotlin import com.github.gradle.node.npm.task.NpmTask +import com.github.gradle.node.npm.task.NpxTask import com.github.gradle.node.task.NodeTask +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin +import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin import org.jetbrains.kotlin.gradle.targets.js.dukat.DtsResolver import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask @@ -21,3 +24,6 @@ node { distBaseUrl.set(null as String?) // set by dependencyResolutionManagement } +project.plugins.withType() +project.plugins.withType() + diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts new file mode 100644 index 0000000..374f9f2 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts @@ -0,0 +1,12 @@ +package dev.adamko.gradle + +import org.gradle.kotlin.dsl.`component-model-base` +import org.gradle.kotlin.dsl.kotlin + + +plugins { + base +} + + + diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt new file mode 100644 index 0000000..d506592 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt @@ -0,0 +1,24 @@ +package dev.adamko.gradle.tstl + +import com.github.gradle.node.NodePlugin +import dev.adamko.gradle.tstl.tasks.TypescriptToLuaTask +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.BasePlugin +import org.gradle.kotlin.dsl.withType +import org.gradle.language.base.plugins.LifecycleBasePlugin + + +class TstlPlugin : Plugin { + override fun apply(project: Project) { + + project.plugins.withType { + } + + project.plugins.withType { + project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME) { + dependsOn(project.tasks.withType()) + } + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt new file mode 100644 index 0000000..4da82d3 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt @@ -0,0 +1,50 @@ +package dev.adamko.gradle.tstl.tasks + +import com.github.gradle.node.npm.task.* +import org.gradle.api.file.* +import org.gradle.api.provider.* +import org.gradle.api.tasks.* +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import org.gradle.kotlin.dsl.* + +abstract class TypescriptToLuaTask : NpmTask() { + + @get:Internal + val intermediateOutputDir: RegularFileProperty = project.objects.fileProperty() + .convention { temporaryDir } + + @get:Internal + val intermediateOutputCanonicalPath: Provider = + intermediateOutputDir.map { it.asFile.canonicalPath } + + @get:Input + val identifier: Property = project.objects.property().convention(name) + + @get:Internal + val luaOutputDirConvention: Provider = + project.layout.buildDirectory.map { it.dir("typescriptToLua/${identifier.get()}") } + + @get:OutputDirectory + val luaOutputDir: DirectoryProperty = project.objects.directoryProperty() + .convention(luaOutputDirConvention) + + init { + group = "typescriptToLua" + + execOverrides { standardOutput = System.out } + + super.dependsOn(project.tasks.withType()) + ignoreExitValue.set(false) + } + + @TaskAction + fun convert() { + args.set(parseSpaceSeparatedArgs("-- --outDir ${intermediateOutputCanonicalPath.get()}")) + + project.delete(intermediateOutputDir.get()) + + super.exec() + + } + +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a0f7639..fbce071 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index d592108..618df6e 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,6 +1,14 @@ +import org.gradle.process.internal.DefaultExecSpec +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation +import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + + plugins { - id("dev.adamko.factoriowebmap.archetype.base") - kotlin("multiplatform") + id("dev.adamko.factoriowebmap.archetype.kotlin-multiplatform") + kotlin("plugin.serialization") } val projectId: String by project.extra @@ -13,6 +21,8 @@ kotlin { compilations.configureEach { kotlinOptions { jvmTarget = "11" + apiVersion = "1.5" + languageVersion = "1.5" } } } @@ -20,8 +30,12 @@ kotlin { sourceSets { val jvmMain by getting { dependencies { - api("com.google.protobuf:protobuf-javalite:3.19.1") - api("com.google.protobuf:protobuf-kotlin-lite:3.19.1") + implementation("com.github.ntrrgc:ts-generator:1.1.1") + implementation("org.jetbrains.kotlin:kotlin-reflect") + + val kotlinXSerializationVersion = "1.3.0" + implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinXSerializationVersion") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinXSerializationVersion") } } val jvmTest by getting { @@ -32,11 +46,24 @@ kotlin { // js(IR) { - browser() + moduleName = "data-model" + browser { } + binaries.executable() } sourceSets { - val jsMain by getting { + val jsMain: KotlinSourceSet by getting { + + dependencies { + + implementation(npm("lua-types", "^2.11.0")) + implementation(npm("@types/node", "^12.0.8")) + implementation(npm("typescript-to-lua", "1.1.1")) + implementation(npm("typescript", "4.4.4")) + implementation(npm("typed-factorio", "0.11.0-packagetypes-1", false)) + + } + } val jsTest by getting { @@ -52,11 +79,113 @@ kotlin { languageVersion = "1.5" // enableLanguageFeature("InlineClasses") // language feature name optIn("kotlin.OptIn") + optIn("kotlin.RequiresOptIn") optIn("kotlin.ExperimentalStdlibApi") optIn("kotlin.time.ExperimentalTime") optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") optIn("kotlin.js.ExperimentalJsExport") + optIn("kotlinx.serialization.ExperimentalSerializationApi") // progressiveMode = true // false by default } } } + + + + +//kotlin.js() +// .compilations +// .getByName(KotlinCompilation.MAIN_COMPILATION_NAME) +// .npmProject +// .useTool() + + +afterEvaluate { + +// val nodeJsExecTstl by tasks.creating(NodeJsExec::class) { +// group = project.name +// +// nodeArgs += listOf( +// "tstl", +// ) +// } + + val kotlinJsCompilation: KotlinJsCompilation = + kotlin.targets + .flatMap { it.compilations } + .filterIsInstance() + .first { it.name == KotlinCompilation.MAIN_COMPILATION_NAME } + val npmProject = kotlinJsCompilation.npmProject + + tasks.create("tstl") { + group = project.name + + standardOutput = System.out + errorOutput = System.err + + workingDir = npmProject.dir + executable = + when (npmProject.nodeJs.requireConfigured().isWindows) { + true -> "npx.cmd" + false -> "npx" + } + + args(parseSpaceSeparatedArgs("tstl --out $temporaryDir")) + + } + + tasks.create("asd") { + group = project.name + + doLast { + + val execSpec = + project.objects.newInstance(DefaultExecSpec::class.java).apply { + isIgnoreExitValue = false + standardOutput = System.out + errorOutput = System.err + } + + kotlin.targets + .flatMap { it.compilations } + .filterIsInstance() + .filter { it.name == KotlinCompilation.MAIN_COMPILATION_NAME } + .forEach { + + org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsExec.create(it, "blahDeBlah") { + + } + + execSpec.workingDir = it.npmProject.dir + + execSpec.executable = + when (it.npmProject.nodeJs.requireConfigured().isWindows) { + true -> "npx.cmd" + false -> "npx" + } + + execSpec.args("tstl", "--version") + +// execSpec.commandLine + + +// it.npmProject.useTool( +// execSpec, +// "typescript-to-lua/dist/tstl.js", +// listOf(), +// listOf( "--outDir","$buildDir/testAsd"), +// listOf("--version"), +// listOf(), +// ) + } + + exec { + execSpec.copyTo(this) + } + + } + } + +} + + diff --git a/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt b/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt new file mode 100644 index 0000000..25ff622 --- /dev/null +++ b/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt @@ -0,0 +1,56 @@ +package dev.adamko.factorioevents.model + +import kotlin.js.ExperimentalJsExport +import kotlin.js.JsExport + +// +//@JsExport +//@ExperimentalJsExport +//data class FactorioEvent( +// val modVersion: String, +// val tick: F_uint, +// val eventType: String, +// val data: FactorioObjectData, +//) +// +//@JsExport +//abstract class FactorioObjectData { +// abstract val objectName: String +//} +// +//@JsExport +//data class PlayerData( +// override val objectName: String, +// val name: String, +// val characterUnitNumber: F_uint, +// val associatedCharactersUnitNumbers: List, +// val position: PositionData, +//) : FactorioObjectData() +// +// +//@JsExport +//data class PositionData( +// val x: F_int, +// val y: F_int, +//) +// +// +// +//typealias F_float = Float +//typealias F_double = Double +//typealias F_int = Int +//typealias F_int8 = Byte +// +// +////@JsExport +////@ExperimentalJsExport +//typealias F_uint = UInt +////expect class F_uint +// +////expect value class F_uint internal constructor(internal val data: Int) +//expect value class F_uint8 internal constructor(internal val data: Int) +//expect value class F_uint16 internal constructor(internal val data: Int) +//expect value class F_uint64 internal constructor(internal val data: Int) +// +//typealias F_table = Any? +// diff --git a/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt b/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt new file mode 100644 index 0000000..2e0cc08 --- /dev/null +++ b/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt @@ -0,0 +1,13 @@ +package dev.adamko.factorioevents.model + +import kotlin.js.* + +// +//@JsModule("typed-factorio") +//external class uint +// +//actual typealias F_uint = uint +//actual typealias F_uint8 = UByte +//actual typealias F_uint16 = UShort +//actual typealias F_uint64 = ULong +// diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt new file mode 100644 index 0000000..162eed3 --- /dev/null +++ b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt @@ -0,0 +1,97 @@ +@file:Suppress("ClassName") + +package dev.adamko.factorioevents.model + + +import kotlinx.serialization.Serializable + + +/* + * The basic types used in the Factorio API. While Lua only supports the `boolean`, `number`, + * `string`, and `table` types (as they relate to the types listed below), the API docs will + * specify what C++ types these are converted to or from internally. + */ + + +/** + * Tables are enclosed in curly brackets, like this `{}` + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#table) + */ +typealias F_table = MutableMap + +sealed interface FBuiltInType { + + sealed interface FNumber { + /** + * A floating-point number. This is a single-precision floating point number. Whilst Lua only uses double-precision + * numbers, when a function takes a float, the game engine will immediately convert the double-precision number to + * single-precision. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#float) + */ + @Serializable + @JvmInline + value class F_float(val float: Float) : FNumber + /** + * A double-precision floating-point number. This is the same data type as all Lua numbers use. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#double) + */ + @Serializable + @JvmInline + value class F_double(val double: Double) : FNumber + + /** + * 32-bit signed integer. Possible values are -2,147,483,648 to 2,147,483,647. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#int) + */ + @Serializable + @JvmInline + value class F_int(val int: Int) : FNumber + /** + * 8-bit signed integer. Possible values are -128 to 127. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#int8) + */ + @Serializable + @JvmInline + value class F_int8(val int8: Byte) : FNumber + + /** + * 32-bit unsigned integer. Possible values are 0 to 4,294,967,295. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint) + */ + @Serializable + @JvmInline + value class F_uint(val uint: UInt) : FNumber + /** + * 8-bit unsigned integer. Possible values are 0 to 255. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint8) + */ + @Serializable + @JvmInline + value class F_uint8(val uint8: UByte) : FNumber + /** + * 16-bit unsigned integer. Possible values are 0 to 65535. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint16) + */ + @Serializable + @JvmInline + value class F_uint16(val uint16: UShort) : FNumber + /** + * 64-bit unsigned integer. Possible values are 0 to 18,446,744,073,709,551,615. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint64) + */ + @Serializable + @JvmInline + value class F_uint64(val uint64: ULong) : FNumber + } + + +} diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt new file mode 100644 index 0000000..1c6d81c --- /dev/null +++ b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt @@ -0,0 +1,58 @@ +package dev.adamko.factorioevents.model + +import dev.adamko.factorioevents.model.FBuiltInType.FNumber.F_float +import dev.adamko.factorioevents.model.FBuiltInType.FNumber.F_int +import dev.adamko.factorioevents.model.FBuiltInType.FNumber.F_uint + +import kotlinx.serialization.* +import kotlinx.serialization.builtins.* +import kotlinx.serialization.json.* +import kotlinx.serialization.modules.* + + +@Serializable +data class FactorioEvent( + val modVersion: String, + val tick: UInt, + val eventType: String, + val data: FactorioObjectData, +) + +@JsonClassDiscriminator("object_name") +sealed interface FactorioObjectData { + val objectName: String +} + +@SerialName("player") +data class PlayerData( + override val objectName: String, + val characterUnitNumber: UInt, + val associatedCharacterUnitNumbers: List, + val positionData: PositionData, +) : FactorioObjectData + +data class EntityData( + override val objectName: String, + val name: String, + val type: String, + val active: Boolean, + val healthRatio: Float, + val health: Float?, + val surface_index: Int, + val unit_number: UInt?, + val position: PositionData, + val player_index: UInt?, +) : FactorioObjectData + + +data class SurfaceData( + override val objectName: String, + val name: String, + val index: UInt, + val daytime: Float, +) : FactorioObjectData + +data class PositionData( + val x: Int, + val y: Int, +) \ No newline at end of file diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt new file mode 100644 index 0000000..84248ae --- /dev/null +++ b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt @@ -0,0 +1,46 @@ +package dev.adamko.factorioevents.model + +import kotlin.reflect.KClass +import kotlin.reflect.KProperty +import me.ntrrgc.tsGenerator.ClassTransformer +import me.ntrrgc.tsGenerator.TypeScriptGenerator +import me.ntrrgc.tsGenerator.camelCaseToSnakeCase + + +fun main() { + + val gen = + TypeScriptGenerator( + rootClasses = + buildSet { + add(FactorioEvent::class) + addAll(FactorioObjectData::class.sealedSubclasses) + }, + mappings = mapOf( + // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` + Float::class to "float", + Double::class to "double", + Int::class to "int", + Byte::class to "int8", + UInt::class to "uint", + UByte::class to "uint8", + UShort::class to "uint16", + ULong::class to "uint64", + ), + classTransformers = listOf( + PropertyNameTransformer, + ) + ) + + println(gen.definitionsText) +} + +object PropertyNameTransformer : ClassTransformer { + override fun transformPropertyName( + propertyName: String, + property: KProperty<*>, + klass: KClass<*> + ): String { + return camelCaseToSnakeCase(propertyName) + } +} diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 5868ba2..fa0274f 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -3,7 +3,9 @@ import org.apache.tools.ant.filters.ReplaceTokens import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { + idea id("dev.adamko.factoriowebmap.archetype.node") + id("dev.adamko.tstl") } val projectId: String by project.extra @@ -33,7 +35,7 @@ val tstlTask = tasks.register("typescriptToLua") { val intermediateOutputDir = temporaryDir args.set(parseSpaceSeparatedArgs("-- --outDir $intermediateOutputDir")) - val outputDir = modBuildDir.dir("typescriptToLua") + val outputDir: Directory = modBuildDir.dir("typescriptToLua") outputs.dir(outputDir) .withPropertyName("outputDir") @@ -54,19 +56,17 @@ val tstlTask = tasks.register("typescriptToLua") { idea { module { - sourceDirs.add(layout.projectDirectory.dir("src/main/typescript").asFile) - excludeDirs.add(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile) - resourceDirs.add(layout.projectDirectory.dir("src/main/resources").asFile) - - resourceDirs.add(layout.projectDirectory.dir("infra").asFile) - excludeDirs.add(layout.projectDirectory.dir("infra/factorio-server").asFile) + sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile)) + excludeDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile)) + resourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/resources").asFile)) + resourceDirs.add(mkdir(layout.projectDirectory.dir("infra").asFile)) + excludeDirs.add(mkdir(layout.projectDirectory.dir("infra/factorio-server").asFile)) } } - val typescriptSrcSet = project.objects.sourceDirectorySet("typescript", "typescript").apply { - srcDir(mkdir("$projectDir/src/main/typescript")) + srcDir(layout.projectDirectory.dir("src/main/typescript")) destinationDirectory.set(modBuildDir.dir("typescriptToLua").asFile) compiledBy(tstlTask) { @@ -228,33 +228,3 @@ tasks.register("downloadFactorioApiDocs") { logger.lifecycle("Downloaded Factorio API json: $apiFile") } } - -//tasks.register("downloadLuaProtobuf") { -// group = projectId -// -// val luaProtobufVersion = "0.3.3" -// -// val target = uri("https://github.com/starwing/lua-protobuf/archive/refs/tags/$luaProtobufVersion.zip") -// val downloadedFile = file("$temporaryDir/luaProtobuf-$luaProtobufVersion.zip") -// -// val luaProto = modBuildDir.file(apiFilename) -// outputs.file(apiFile) -// -// doLast { -// -// ant.invokeMethod( -// "get", mapOf( -// "src" to target, -// "dest" to downloadedFile, -// "verbose" to true, -// ) -// ) -// -// val json = downloadedFile.readText() -// val prettyJson = groovy.json.JsonOutput.prettyPrint(json) -// -// apiFile.asFile.writeText(prettyJson) -// -// logger.lifecycle("Downloaded Factorio API json: $apiFile") -// } -//} \ No newline at end of file diff --git a/modules/mod/infra/docker-compose.yml b/modules/mod/infra/docker-compose.yml index 180c22b..3ee1c60 100644 --- a/modules/mod/infra/docker-compose.yml +++ b/modules/mod/infra/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: factorio-server: - image: factoriotools/factorio:1.1.42 + image: factoriotools/factorio:1.1.46 # logging: # driver: "json-file" container_name: "factorio-server" diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index 4a5d20c..c7744a7 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -8,7 +8,7 @@ import {Serdes} from "./serdes/serdes" import {FactorioEvent, JsonTable} from "./model/model"; -const mapEventIdToName = new LuaTable() +const mapEventIdToName = new LuaTable() for (const [k, v] of pairs(defines.events)) { mapEventIdToName.set(v, k) } diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/mod/src/main/typescript/package-lock.json index b0ae77b..e7eaaf1 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -37,9 +37,9 @@ } }, "is-core-module": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", - "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "requires": { "has": "^1.0.3" } @@ -74,30 +74,27 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.8.0.tgz", - "integrity": "sha512-vuAJfkTBSQKD8mHCN7CAbwJJ73y+xfxLBPlFsYjjd015tMPv8Yrq1hBXxoUFZ1ZWGzNgcFL9RwZ6TspsIH7WJw==", + "version": "0.11.0-packagetypes-1", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.11.0-packagetypes-1.tgz", + "integrity": "sha512-oiN9XjODry434DPcgx3MNyC22/cOrbeU5/q0uM+Tj8BjJ7B42DYH+SR21tEtrHaWHNUJNX5iXD8h1Bk0N3Qvmw==", "requires": { "lua-types": "^2.10.1", "typescript-to-lua": "^1.0.0" } }, + "typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==" + }, "typescript-to-lua": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.0.1.tgz", - "integrity": "sha512-j5mb+8HgUUY8hhAKoNy6KUMeamEN1fsTtMvSbPaxmVkWw40pHdLi3umsQG+Qo7wM6IK+RQffFxbIWEjleF+xpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.1.1.tgz", + "integrity": "sha512-13vk/FSQyqbBkXNvg73LpT0tsPKdepJHPYR6TNtbc9l1ClSxAEUvkB3k49MAwSQ6LoN8Ui4Bgyu9dKFoDB315Q==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", - "source-map": "^0.7.3", - "typescript": "~4.3.5" - }, - "dependencies": { - "typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" - } + "source-map": "^0.7.3" } } } diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index b25c3b9..076d3ae 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -13,8 +13,12 @@ "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", - "typescript-to-lua": "1.0.1", - "typed-factorio": "0.8.0" + "typescript-to-lua": "1.1.1", + "typed-factorio": "0.11.0-packagetypes-1", + "typescript": "4.4.4" + }, + "//": { + "typed-factorio": "0.10.0" }, "peerDependencies": {}, "optionalDependencies": {}, diff --git a/settings.gradle.kts b/settings.gradle.kts index b1206d7..b75fcf8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,6 @@ rootProject.name = "factorio-web-map" include( ":modules:mod", -// ":modules:mod2", // ":modules:server", ":modules:kt-rcon", ":modules:factorio-events-data-model", @@ -31,22 +30,16 @@ dependencyResolutionManagement { repositories { mavenCentral() + maven("https://jitpack.io") maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") // Declare the Node.js download repository - ivy { - name = "Node.js" - setUrl("https://nodejs.org/dist/") - patternLayout { - artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") - } - metadataSources { - artifact() - } - content { - includeModule("org.nodejs", "node") - } + ivy("https://nodejs.org/dist/") { + name = "Node Distributions at $url" + patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } + metadataSources { artifact() } + content { includeModule("org.nodejs", "node") } } }