From 0d85bfca60c664e994e42d9bc7bdc078e40ea446 Mon Sep 17 00:00:00 2001
From: Adam <897017+asemy@users.noreply.github.com>
Date: Sat, 27 Nov 2021 17:57:50 +0100
Subject: [PATCH] get a shared kotlin-typescript data model working
---
.../factoriowebmap/configurations/type.kt | 15 ++
.../configurations/typescript.kt | 20 +++
.../build.gradle.kts | 132 ++++--------------
.../factorioevents/model/FactorioEvent.kt | 56 --------
.../factorioevents/model/FactorioEvent.kt | 13 --
.../factorioevents/model/builtinTypes.kt | 0
.../factorioevents/model/factorioEvents.kt | 9 +-
.../dev/adamko/factorioevents/model/kt2ts.kt} | 30 +++-
modules/mod/build.gradle.kts | 31 ++++
.../main/typescript/generated/data-model.ts | 45 ++++++
10 files changed, 173 insertions(+), 178 deletions(-)
create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt
create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt
delete mode 100644 modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt
delete mode 100644 modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt
rename modules/factorio-events-data-model/src/{jvmMain => main}/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt (100%)
rename modules/factorio-events-data-model/src/{jvmMain => main}/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt (85%)
rename modules/factorio-events-data-model/src/{jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt => main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt} (66%)
create mode 100644 modules/mod/src/main/typescript/generated/data-model.ts
diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt
new file mode 100644
index 0000000..272b7ce
--- /dev/null
+++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt
@@ -0,0 +1,15 @@
+package dev.adamko.factoriowebmap.configurations
+
+import org.gradle.api.artifacts.Configuration
+
+fun Configuration.asProvider() {
+ isVisible = false
+ isCanBeResolved = false
+ isCanBeConsumed = true
+}
+
+fun Configuration.asConsumer() {
+ isVisible = false
+ isCanBeResolved = true
+ isCanBeConsumed = false
+}
diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt
new file mode 100644
index 0000000..2020f16
--- /dev/null
+++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt
@@ -0,0 +1,20 @@
+package dev.adamko.factoriowebmap.configurations
+
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.attributes.AttributeContainer
+import org.gradle.api.attributes.Bundling
+import org.gradle.api.attributes.Category
+import org.gradle.api.attributes.LibraryElements
+import org.gradle.api.attributes.Usage
+import org.gradle.api.model.ObjectFactory
+import org.gradle.kotlin.dsl.named
+
+fun Configuration.typescriptAttributes(objects: ObjectFactory) =
+ attributes { typescript(objects) }
+
+fun AttributeContainer.typescript(objects: ObjectFactory) {
+ attribute(Usage.USAGE_ATTRIBUTE, objects.named("typescript"))
+ attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
+ attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.OBJECTS))
+ attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
+}
diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts
index 48aae2d..f422934 100644
--- a/modules/factorio-events-data-model/build.gradle.kts
+++ b/modules/factorio-events-data-model/build.gradle.kts
@@ -1,120 +1,46 @@
-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
-
+import dev.adamko.factoriowebmap.configurations.asProvider
+import dev.adamko.factoriowebmap.configurations.typescriptAttributes
plugins {
- id("dev.adamko.factoriowebmap.archetype.kotlin-multiplatform")
+ id("dev.adamko.factoriowebmap.archetype.kotlin-jvm")
kotlin("plugin.serialization")
}
val projectId: String by project.extra
val buildDir: Directory = layout.buildDirectory.dir(projectId).get()
-kotlin {
+dependencies {
+ val kotlinXSerializationVersion = "1.3.0"
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinXSerializationVersion")
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinXSerializationVersion")
- //
- jvm {
- compilations.configureEach {
- kotlinOptions {
- jvmTarget = "11"
- apiVersion = "1.6"
- languageVersion = "1.6"
- }
- }
- }
+ implementation("com.github.ntrrgc:ts-generator:1.1.2")
+ implementation("org.jetbrains.kotlin:kotlin-reflect")
+}
- sourceSets {
- val jvmMain by getting {
- dependencies {
- implementation("com.github.ntrrgc:ts-generator:1.1.1")
- implementation("org.jetbrains.kotlin:kotlin-reflect")
+val generateTypescript by tasks.registering(JavaExec::class) {
+ group = project.name
- 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 {
- }
- }
+ val generatedFileName = "$temporaryDir/data-model.ts"
+ inputs.property("generatedFileName", generatedFileName)
+ outputs.file(generatedFileName)
- //
+ classpath(sourceSets.main.map { it.runtimeClasspath })
+ mainClass.set("dev.adamko.factorioevents.model.Kt2tsKt")
+ args(generatedFileName)
- //
- js(IR) {
- moduleName = "data-model"
- browser { }
- binaries.executable()
- }
-
- sourceSets {
- 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 {
- dependencies {
- implementation(kotlin("test-js"))
- }
- }
- }
- //
-
- sourceSets.all {
- languageSettings.apply {
- languageVersion = "1.6"
-// 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
- }
+ doFirst {
+ delete(temporaryDir)
+ mkdir(temporaryDir)
}
}
-
-afterEvaluate {
-
- 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"))
-
- }
-
+val typescriptModelGenerated by configurations.registering {
+ asProvider()
+ typescriptAttributes(objects)
+ outgoing.artifact(
+ generateTypescript.map {
+ it.outputs.files.singleFile
+ }
+ )
}
-
-
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
deleted file mode 100644
index 25ff622..0000000
--- a/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-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
deleted file mode 100644
index 2e0cc08..0000000
--- a/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-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/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt
similarity index 100%
rename from modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt
rename to modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt
diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt
similarity index 85%
rename from modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt
rename to modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt
index bb5d928..4f7865e 100644
--- a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt
+++ b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt
@@ -7,8 +7,11 @@ import kotlinx.serialization.json.JsonClassDiscriminator
@Serializable
data class FactorioEvent(
+ /** Schema versioning */
val modVersion: String,
+ /** game time */
val tick: UInt,
+ /** the initial Factorio event ({defines.events}) trigger */
val eventType: String,
val data: FactorioObjectData,
)
@@ -33,10 +36,10 @@ data class EntityData(
val active: Boolean,
val healthRatio: Float,
val health: Float?,
- val surface_index: Int,
- val unit_number: UInt?,
+ val surfaceIndex: Int,
+ val unitNumber: UInt?,
val position: PositionData,
- val player_index: UInt?,
+ val playerIndex: UInt?,
) : FactorioObjectData
data class SurfaceData(
diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt
similarity index 66%
rename from modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt
rename to modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt
index 84248ae..e6fe4e9 100644
--- a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt
+++ b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt
@@ -1,13 +1,14 @@
package dev.adamko.factorioevents.model
+import java.io.File
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import me.ntrrgc.tsGenerator.ClassTransformer
import me.ntrrgc.tsGenerator.TypeScriptGenerator
import me.ntrrgc.tsGenerator.camelCaseToSnakeCase
+import org.intellij.lang.annotations.Language
-
-fun main() {
+fun main(args: Array) {
val gen =
TypeScriptGenerator(
@@ -32,9 +33,32 @@ fun main() {
)
)
- println(gen.definitionsText)
+ val definitions = gen.definitionsText
+
+ when (val filename = args.firstOrNull()) {
+ null -> {
+ println(definitions)
+ }
+ else -> {
+ val out = File(filename)
+ out.parentFile.mkdirs()
+ out.printWriter().use {
+ it.print(header)
+ it.print(definitions)
+ }
+ println("Generated file: $out")
+ }
+ }
}
+@Language("TypeScript")
+val header = """
+
+ // Generated code - do edit this file manually
+
+
+""".trimIndent()
+
object PropertyNameTransformer : ClassTransformer {
override fun transformPropertyName(
propertyName: String,
diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts
index e120d00..3590ace 100644
--- a/modules/mod/build.gradle.kts
+++ b/modules/mod/build.gradle.kts
@@ -1,4 +1,6 @@
import com.github.gradle.node.npm.task.NpmTask
+import dev.adamko.factoriowebmap.configurations.asConsumer
+import dev.adamko.factoriowebmap.configurations.typescriptAttributes
import org.apache.tools.ant.filters.ReplaceTokens
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
@@ -53,6 +55,35 @@ val tstlTask = tasks.register("typescriptToLua") {
}
+val dataModelTs: Configuration by configurations.creating {
+ asConsumer()
+ typescriptAttributes(objects)
+}
+
+dependencies {
+ dataModelTs(projects.modules.factorioEventsDataModel)
+}
+
+val updateDataModel by tasks.registering(Sync::class) {
+ group = project.name
+
+ dependsOn(dataModelTs)
+
+ from(
+ dataModelTs.incoming
+ .artifactView { lenient(true) }
+ .artifacts
+ .artifactFiles
+ .filter { it.exists() }
+ )
+
+ into(layout.projectDirectory.dir("src/main/typescript/generated"))
+}
+
+tasks.assemble { dependsOn(updateDataModel) }
+
+
+
idea {
module {
sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile))
diff --git a/modules/mod/src/main/typescript/generated/data-model.ts b/modules/mod/src/main/typescript/generated/data-model.ts
new file mode 100644
index 0000000..cf85b17
--- /dev/null
+++ b/modules/mod/src/main/typescript/generated/data-model.ts
@@ -0,0 +1,45 @@
+
+// Generated code - do edit this file manually
+
+interface FactorioObjectData {
+ object_name: string;
+}
+
+interface FactorioEvent {
+ data: FactorioObjectData;
+ event_type: string;
+ mod_version: string;
+ tick: uint;
+}
+
+interface PositionData {
+ x: int;
+ y: int;
+}
+
+interface PlayerData extends FactorioObjectData {
+ associated_character_unit_numbers: uint[];
+ character_unit_number: uint;
+ object_name: string;
+ position_data: PositionData;
+}
+
+interface EntityData extends FactorioObjectData {
+ active: boolean;
+ health: float | null;
+ health_ratio: float;
+ name: string;
+ object_name: string;
+ player_index: uint | null;
+ position: PositionData;
+ surface_index: int;
+ type: string;
+ unit_number: uint | null;
+}
+
+interface SurfaceData extends FactorioObjectData {
+ daytime: float;
+ index: uint;
+ name: string;
+ object_name: string;
+}
\ No newline at end of file