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