diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..2689b33 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +hydrozoa_api.json linguist-generated=true diff --git a/.idea/gradle.xml b/.idea/gradle.xml index a451d16..c7cfdca 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -7,6 +7,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -19,7 +44,8 @@ \ No newline at end of file diff --git a/bindings-generator/build.gradle.kts b/bindings-generator/build.gradle.kts new file mode 100644 index 0000000..475bc4a --- /dev/null +++ b/bindings-generator/build.gradle.kts @@ -0,0 +1,35 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Gradle plugin project to get you started. + * For more details on writing Custom Plugins, please refer to https://docs.gradle.org/8.10/userguide/custom_plugins.html in the Gradle documentation. + * This project uses @Incubating APIs which are subject to change. + */ + +plugins { + // Apply the Java Gradle plugin development plugin to add support for developing Gradle plugins + `java-gradle-plugin` + +// // Apply the Kotlin JVM plugin to add support for Kotlin. + kotlin("jvm") version libs.versions.kotlin + kotlin("plugin.serialization") version libs.versions.kotlin +} + +repositories { + // Use Maven Central for resolving dependencies. + mavenCentral() +} + +dependencies { + implementation("com.github.javaparser:javaparser-core:3.26.4") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1") + implementation("com.google.guava:guava:33.4.8-jre") +} + +gradlePlugin { + // Define the plugin + val bindingsGen by plugins.creating { + id = "dev.vexide.hydrozoa.plugin.bindings" + implementationClass = "dev.vexide.hydrozoa.plugin.bindings.BindingsGeneratorPlugin" + } +} diff --git a/bindings-generator/settings.gradle.kts b/bindings-generator/settings.gradle.kts new file mode 100644 index 0000000..fa8bc74 --- /dev/null +++ b/bindings-generator/settings.gradle.kts @@ -0,0 +1,7 @@ +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} \ No newline at end of file diff --git a/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/BindingsGeneratorPlugin.kt b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/BindingsGeneratorPlugin.kt new file mode 100644 index 0000000..798ce60 --- /dev/null +++ b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/BindingsGeneratorPlugin.kt @@ -0,0 +1,19 @@ +/* + * This source file was generated by the Gradle 'init' task + */ +package dev.vexide.hydrozoa.plugin.bindings + +import dev.vexide.hydrozoa.plugin.bindings.tasks.GenerateBindingsTask +import org.gradle.api.Project +import org.gradle.api.Plugin + +@Suppress("unused") +class BindingsGeneratorPlugin : Plugin { + override fun apply(project: Project) { + project.tasks.register("generateBindings", GenerateBindingsTask::class.java) { task -> + task.group = "build" + task.description = "Generates bindings for the Hydrozoa SDK" + } + } +} + diff --git a/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/Deserialization.kt b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/Deserialization.kt new file mode 100644 index 0000000..5421441 --- /dev/null +++ b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/Deserialization.kt @@ -0,0 +1,67 @@ +package dev.vexide.hydrozoa.plugin.bindings + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class SdkModule( + val name: String, + val items: List, + val enums: List, +) + +@Serializable +data class SdkItem( + val name: String, + val params: List, + val returns: Type?, +) { + @Serializable + data class Param( + val name: String, + val type: Type, + ) + + @Serializable + sealed class Type { + @Serializable + @SerialName("Bool") + object Bool : Type() + + @Serializable + @SerialName("Int") + object Int : Type() + + @Serializable + @SerialName("Long") + object Long : Type() + + @Serializable + @SerialName("Float") + object Float : Type() + + @Serializable + @SerialName("Double") + object Double : Type() + + @Serializable + @SerialName("StringPtr") + object StringPtr : Type() + + @Serializable + @SerialName("Named") + data class Named(val name: String) : Type() + + @Serializable + @SerialName("Pointer") + data class Pointer(val destination: Type) : Type() + } +} + +@Serializable +data class SdkEnum( + val name: String, + @SerialName("underlying_type") + val underlyingType: SdkItem.Type, + val variants: Map, +) \ No newline at end of file diff --git a/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/Utils.kt b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/Utils.kt new file mode 100644 index 0000000..529ccf4 --- /dev/null +++ b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/Utils.kt @@ -0,0 +1,47 @@ +package dev.vexide.hydrozoa.plugin.bindings + +import com.github.javaparser.ast.CompilationUnit +import com.github.javaparser.ast.Modifier +import com.github.javaparser.ast.Modifier.Keyword +import com.github.javaparser.ast.Node +import com.github.javaparser.ast.NodeList +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration +import com.github.javaparser.ast.expr.StringLiteralExpr +import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations + +fun CompilationUnit.addHydrozoaGeneratedComment(): CompilationUnit { + this.setBlockComment(" This file was automatically @generated by the Hydrozoa bindings generator. Do not edit this manually!\n" + + " Instead, update the Hydrozoa SDK at and re-run the generator. ") + return this +} + +fun NodeWithAnnotations.addHydrozoaGeneratedAnnotation(): N { + return this.addSingleMemberAnnotation( + javax.annotation.processing.Generated::class.java, + StringLiteralExpr("dev.vexide.hydrozoa.plugin.bindings.BindingsGeneratorPlugin") + ) +} + +fun ClassOrInterfaceDeclaration.addStaticInitAnnotation(): ClassOrInterfaceDeclaration { + return this.addMarkerAnnotation("org.teavm.interop.StaticInit") +} + +fun, N: Node> T.addNotNullAnnotation(add: Boolean = true): T { + if (add) { + addMarkerAnnotation("org.jetbrains.annotations.NotNull") + } + return this +} + +fun ClassOrInterfaceDeclaration.addPrivateConstructor(): ClassOrInterfaceDeclaration { + this.addConstructor(Keyword.PRIVATE) + return this +} + +fun nodeListOf(vararg items: T): NodeList { + return NodeList.nodeList(*items) +} + +fun modifierListOf(vararg modifiers: Keyword): NodeList { + return Modifier.createModifierList(*modifiers) +} \ No newline at end of file diff --git a/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkEnum.kt b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkEnum.kt new file mode 100644 index 0000000..0bc4208 --- /dev/null +++ b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkEnum.kt @@ -0,0 +1,129 @@ +package dev.vexide.hydrozoa.plugin.bindings.sdk + +import com.github.javaparser.ast.Modifier +import com.github.javaparser.ast.body.RecordDeclaration +import com.github.javaparser.ast.expr.CastExpr +import com.github.javaparser.ast.expr.DoubleLiteralExpr +import com.github.javaparser.ast.expr.Expression +import com.github.javaparser.ast.expr.IntegerLiteralExpr +import com.github.javaparser.ast.expr.NameExpr +import com.github.javaparser.ast.expr.ObjectCreationExpr +import com.github.javaparser.ast.stmt.BlockStmt +import com.github.javaparser.ast.stmt.ReturnStmt +import com.github.javaparser.ast.type.ClassOrInterfaceType +import com.github.javaparser.utils.SourceRoot +import com.google.common.base.CaseFormat +import dev.vexide.hydrozoa.plugin.bindings.SdkEnum +import dev.vexide.hydrozoa.plugin.bindings.addHydrozoaGeneratedAnnotation +import dev.vexide.hydrozoa.plugin.bindings.addHydrozoaGeneratedComment +import dev.vexide.hydrozoa.plugin.bindings.modifierListOf +import dev.vexide.hydrozoa.plugin.bindings.nodeListOf +import kotlin.collections.iterator + +class JavaSdkEnum(val sdk: SdkEnum, val module: JavaSdkModule) { + fun generate(sourceRoot: SourceRoot) { + val name = generateEnumName(sdk.name, module.sdk.name) + + val cu = makeCompilationUnit(name, sourceRoot) + .addHydrozoaGeneratedComment() + + val underlyingType = module.javaTypeFor(sdk.underlyingType) + val record = RecordDeclaration( + modifierListOf(Modifier.Keyword.PUBLIC), + name, + ) + .apply { cu.addType(this) } + .addHydrozoaGeneratedAnnotation() + .setJavadocComment(sdk.name) + .addParameter(underlyingType, "value") + + val recordType = ClassOrInterfaceType(null, record.name, null) + + for ((variantName, variantValue) in sdk.variants) { + val literal: Expression = if (variantValue % 1.0 == 0.0) { + IntegerLiteralExpr(variantValue.toInt().toString()) + } else { + DoubleLiteralExpr(variantValue) + } + + record.addFieldWithInitializer( + underlyingType, + variantName, + CastExpr(underlyingType, literal), + Modifier.Keyword.PUBLIC, + Modifier.Keyword.STATIC, + Modifier.Keyword.FINAL, + ) + + record + .addFieldWithInitializer( + recordType, + generateMemberName(variantName, name), + ObjectCreationExpr(null, recordType, nodeListOf(NameExpr(variantName))), + Modifier.Keyword.PUBLIC, + Modifier.Keyword.STATIC, + Modifier.Keyword.FINAL, + ) + .setJavadocComment(variantName) + } + + record.addMethod("getRawValue", Modifier.Keyword.PUBLIC) + .setType(underlyingType) + .setBody( + BlockStmt( + nodeListOf(ReturnStmt(NameExpr("value"))) + ) + ) + } + + companion object { + fun generateEnumName(name: String, moduleName: String): String { + val name = name + .removePrefix("V5_") + .removePrefix("V5") + + val components = ArrayDeque( + CaseFormat.LOWER_CAMEL + .to(CaseFormat.LOWER_UNDERSCORE, name) + .split('_') + ) + + components.addFirst(moduleName) + + return CaseFormat.LOWER_UNDERSCORE + .to(CaseFormat.UPPER_CAMEL, components.joinToString("_")) + } + + fun generateMemberName(name: String, enumName: String): String { + val components = ArrayDeque( + CaseFormat.LOWER_CAMEL + .to(CaseFormat.LOWER_UNDERSCORE, name) + .split('_')) + val enumComponents = ArrayDeque( + CaseFormat.LOWER_CAMEL + .to(CaseFormat.LOWER_UNDERSCORE, enumName) + .split('_')) + + // Remove module prefix from enum name + enumComponents.removeFirst() + + for (redundantComponent in arrayOf("k", "v5")) { + if (components.firstOrNull() == redundantComponent) { + components.removeFirst() + } else { + break + } + } + + for (typeNameComponent in enumComponents) { + if (components.firstOrNull() == typeNameComponent) { + components.removeFirst() + } else { + break + } + } + + return components.joinToString("_").uppercase() + } + } +} \ No newline at end of file diff --git a/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkItem.kt b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkItem.kt new file mode 100644 index 0000000..a152767 --- /dev/null +++ b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkItem.kt @@ -0,0 +1,110 @@ +package dev.vexide.hydrozoa.plugin.bindings.sdk + +import com.github.javaparser.ast.Modifier +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration +import com.github.javaparser.ast.body.MethodDeclaration +import com.github.javaparser.ast.expr.Expression +import com.github.javaparser.ast.expr.MethodCallExpr +import com.github.javaparser.ast.expr.NameExpr +import com.github.javaparser.ast.expr.ObjectCreationExpr +import com.github.javaparser.ast.expr.StringLiteralExpr +import com.github.javaparser.ast.stmt.ExpressionStmt +import com.github.javaparser.ast.stmt.ReturnStmt +import com.github.javaparser.ast.type.ClassOrInterfaceType +import com.google.common.base.CaseFormat +import dev.vexide.hydrozoa.plugin.bindings.SdkItem +import dev.vexide.hydrozoa.plugin.bindings.SdkModule +import dev.vexide.hydrozoa.plugin.bindings.nodeListOf + +class JavaSdkItem(val sdk: SdkItem, val module: JavaSdkModule, val methodName: String = sdk.name) { + fun generate(bindingsClass: ClassOrInterfaceDeclaration) { + val rawMethod = bindingsClass + .addMethod(sdk.name + "_raw", Modifier.Keyword.PRIVATE, Modifier.Keyword.STATIC, Modifier.Keyword.NATIVE) + .setType(module.javaTypeFor(sdk.returns, useRawTypes = true, annotations = true)) + .removeBody() + + rawMethod.addAndGetAnnotation("org.teavm.interop.Import") + .addPair("module", StringLiteralExpr(module.sdk.name)) + .addPair("name", StringLiteralExpr(sdk.name)) + + generateParams(sdk.params, rawMethod, true) + + val method = bindingsClass + .addMethod(methodName, Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC) + .setType(module.javaTypeFor(sdk.returns, annotations = true)) + .setJavadocComment(sdk.name) + + generateParams(sdk.params, method) + generateBody(method, rawMethod) + } + + private fun generateParams( + params: Iterable, + method: MethodDeclaration, + useUnderlyingTypes: Boolean = false + ) { + for (param in params) { + val paramType = module.javaTypeFor(param.type, useUnderlyingTypes) + method.addAndGetParameter(paramType, param.name) + } + } + + private fun generateBody(method: MethodDeclaration, rawMethod: MethodDeclaration) { + val body = method.createBody() + + val nativeMethodCall = MethodCallExpr(null, rawMethod.name) + for (param in sdk.params) { + var arg: Expression = NameExpr(param.name) + + if (module.hasRawType(param.type)) { + arg = MethodCallExpr(arg, "getRawValue") + } + + nativeMethodCall.addArgument(arg) + } + + var expr: Expression = nativeMethodCall + + if (sdk.returns != null && module.hasRawType(sdk.returns)) { + val wrapper = module.javaTypeFor(sdk.returns) as ClassOrInterfaceType + expr = ObjectCreationExpr(null, wrapper, nodeListOf(nativeMethodCall)) + } + + body.addStatement( + if (method.type.isVoidType) { + ExpressionStmt(expr) + } else { + ReturnStmt(expr) + } + ) + } + + companion object { + private var actionVerbs = + setOf("get", "set", "request", "update", "reset", "fill", "draw", "clear", "disable", "enable") + + fun generateMethodName(item: SdkItem, module: SdkModule): Pair { + val nameComponents = ArrayDeque( + CaseFormat.LOWER_CAMEL + .to(CaseFormat.LOWER_UNDERSCORE, item.name) + .removePrefix(module.name + "_") + .split('_') + ) + + val moduleName = nameComponents.removeFirst() + + // Move verbs to front of method name + val lastComponent = nameComponents.lastOrNull() + if (actionVerbs.contains(lastComponent)) { + nameComponents.add(0, nameComponents.removeLast()) + } + + val submoduleName = CaseFormat.LOWER_UNDERSCORE + .to(CaseFormat.UPPER_CAMEL, moduleName) + val trimmedMethodName = CaseFormat.LOWER_UNDERSCORE + .to(CaseFormat.LOWER_CAMEL, nameComponents.joinToString("_")) + + return Pair(submoduleName, trimmedMethodName) + } + } +} \ No newline at end of file diff --git a/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkModule.kt b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkModule.kt new file mode 100644 index 0000000..2103a82 --- /dev/null +++ b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkModule.kt @@ -0,0 +1,107 @@ +package dev.vexide.hydrozoa.plugin.bindings.sdk + +import com.github.javaparser.StaticJavaParser +import com.github.javaparser.ast.CompilationUnit +import com.github.javaparser.ast.Modifier +import com.github.javaparser.ast.type.ClassOrInterfaceType +import com.github.javaparser.ast.type.PrimitiveType +import com.github.javaparser.ast.type.Type +import com.github.javaparser.ast.type.VoidType +import com.github.javaparser.utils.SourceRoot +import com.google.common.base.CaseFormat +import dev.vexide.hydrozoa.plugin.bindings.SdkEnum +import dev.vexide.hydrozoa.plugin.bindings.SdkItem +import dev.vexide.hydrozoa.plugin.bindings.SdkModule +import dev.vexide.hydrozoa.plugin.bindings.addHydrozoaGeneratedAnnotation +import dev.vexide.hydrozoa.plugin.bindings.addHydrozoaGeneratedComment +import dev.vexide.hydrozoa.plugin.bindings.addNotNullAnnotation +import dev.vexide.hydrozoa.plugin.bindings.addPrivateConstructor +import dev.vexide.hydrozoa.plugin.bindings.addStaticInitAnnotation +import kotlin.jvm.optionals.getOrNull + +class JavaSdkModule(val sdk: SdkModule) { + var enums: Map = sdk.enums.associateBy { it.name } + + fun generate(sourceRoot: SourceRoot): CompilationUnit { + val className = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, sdk.name) + "Sdk" + + val cu = makeCompilationUnit(className, sourceRoot) + .addHydrozoaGeneratedComment() + + val bindingsClass = cu.addClass(className, Modifier.Keyword.PUBLIC, Modifier.Keyword.FINAL) + .addHydrozoaGeneratedAnnotation() + .addStaticInitAnnotation() + .addPrivateConstructor() + + val submodules = mutableMapOf() + + for (item in sdk.items) { + val (submoduleName, trimmedMethodName) = JavaSdkItem.Companion.generateMethodName(item, sdk) + + val submodule = submodules.getOrPut(submoduleName) { + JavaSdkSubmodule(submoduleName) + } + submodule.items.add(JavaSdkItem(item, module = this, methodName = trimmedMethodName)) + } + + for (submodule in submodules.values) { + submodule.generate(bindingsClass) + } + + for (enum in sdk.enums) { + JavaSdkEnum(enum, module = this) + .generate(sourceRoot) + } + + return cu + } + + fun javaTypeFor(type: SdkItem.Type?, useRawTypes: Boolean = false, annotations: Boolean = false): Type { + return when (type) { + null -> VoidType() + is SdkItem.Type.Bool -> PrimitiveType(PrimitiveType.Primitive.BOOLEAN) + is SdkItem.Type.Int -> PrimitiveType(PrimitiveType.Primitive.INT) + is SdkItem.Type.Long -> PrimitiveType(PrimitiveType.Primitive.LONG) + is SdkItem.Type.Float -> PrimitiveType(PrimitiveType.Primitive.FLOAT) + is SdkItem.Type.Double -> PrimitiveType(PrimitiveType.Primitive.DOUBLE) + is SdkItem.Type.StringPtr -> StaticJavaParser.parseClassOrInterfaceType("String") + .addNotNullAnnotation(annotations) + is SdkItem.Type.Named -> { + if (useRawTypes) { + val underlyingType = enums[type.name]?.underlyingType + if (underlyingType != null) return javaTypeFor(underlyingType) + } + + ClassOrInterfaceType(null, JavaSdkEnum.Companion.generateEnumName(type.name, sdk.name)) + .addNotNullAnnotation(annotations) + } + is SdkItem.Type.Pointer -> { + ClassOrInterfaceType(null, "org.teavm.interop.Address") + .addNotNullAnnotation(annotations) + } + } + } + + fun hasRawType(type: SdkItem.Type): Boolean { + return when (type) { + is SdkItem.Type.Named -> enums[type.name]?.underlyingType != null + else -> false + } + } +} + +const val PACKAGE_NAME = "dev.vexide.hydrozoa.sdk" +fun makeCompilationUnit(className: String, sourceRoot: SourceRoot): CompilationUnit { + var filename = sourceRoot.root + for (component in PACKAGE_NAME.split(".")) { + filename = filename.resolve(component) + } + + val cu = CompilationUnit(PACKAGE_NAME) + .setStorage(filename.resolve("$className.java")) + print("Filename: ${cu.storage.getOrNull()?.path}") + + sourceRoot.add(cu) + + return cu +} \ No newline at end of file diff --git a/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkSubmodule.kt b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkSubmodule.kt new file mode 100644 index 0000000..2be64c3 --- /dev/null +++ b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/sdk/JavaSdkSubmodule.kt @@ -0,0 +1,27 @@ +package dev.vexide.hydrozoa.plugin.bindings.sdk + +import com.github.javaparser.ast.Modifier +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration +import dev.vexide.hydrozoa.plugin.bindings.addPrivateConstructor +import dev.vexide.hydrozoa.plugin.bindings.addStaticInitAnnotation +import dev.vexide.hydrozoa.plugin.bindings.modifierListOf + +class JavaSdkSubmodule(var submoduleName: String) { + var items = mutableListOf() + + fun generate(parentClass: ClassOrInterfaceDeclaration) { + val submoduleClass = ClassOrInterfaceDeclaration( + modifierListOf(Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC, Modifier.Keyword.FINAL), + false, + submoduleName + ) + .addStaticInitAnnotation() + .addPrivateConstructor() + + parentClass.addMember(submoduleClass) + + for (item in items) { + item.generate(submoduleClass) + } + } +} \ No newline at end of file diff --git a/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/tasks/GenerateBindingsTask.kt b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/tasks/GenerateBindingsTask.kt new file mode 100644 index 0000000..73f63e1 --- /dev/null +++ b/bindings-generator/src/main/kotlin/dev/vexide/hydrozoa/plugin/bindings/tasks/GenerateBindingsTask.kt @@ -0,0 +1,41 @@ +package dev.vexide.hydrozoa.plugin.bindings.tasks + +import com.github.javaparser.utils.SourceRoot +import dev.vexide.hydrozoa.plugin.bindings.sdk.JavaSdkModule +import dev.vexide.hydrozoa.plugin.bindings.SdkModule +import kotlinx.serialization.json.Json +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import kotlin.io.path.ExperimentalPathApi +import kotlin.io.path.createDirectory +import kotlin.io.path.deleteRecursively +import kotlin.io.readText + +abstract class GenerateBindingsTask : DefaultTask() { + @get:InputFile + abstract val apiFile: RegularFileProperty + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @OptIn(ExperimentalPathApi::class) + @TaskAction + fun generateBindings() { + val apiFile = apiFile.asFile.get() + val api = Json.decodeFromString(apiFile.readText()) + + val outDir = outputDirectory.asFile.get().toPath() + print("Out dir: $outDir") + + outDir.deleteRecursively() + outDir.createDirectory() + + val sourceRoot = SourceRoot(outDir) + JavaSdkModule(api).generate(sourceRoot) + sourceRoot.saveAll() + } +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index b04941a..7037adf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,9 +3,9 @@ plugins { `maven-publish` idea - id("org.teavm.library").version("0.10.2") + alias(libs.plugins.teavm) + alias(libs.plugins.jreleaser) id("dev.vexide.hydrozoa").apply(false) - id("org.jreleaser") version "1.15.0" } group = "dev.vexide" @@ -61,7 +61,13 @@ allprojects { withSourcesJar() withJavadocJar() - sourceCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_23 + targetCompatibility = JavaVersion.VERSION_23 + + toolchain { + languageVersion.set(JavaLanguageVersion.of(23)) + vendor.set(JvmVendorSpec.AMAZON) + } } repositories { @@ -72,7 +78,7 @@ allprojects { source = sourceSets.main.get().allJava options .windowTitle("Hydrozoa Docs") - .stylesheetFile(rootProject.layout.projectDirectory.file("docs.css").asFile) +// .stylesheetFile(rootProject.layout.projectDirectory.file("docs.css").asFile) } } @@ -109,6 +115,12 @@ tasks.javadoc { title = "Hydrozoa" } +tasks.jar { + manifest { + attributes("Automatic-Module-Name" to "dev.vexide.hydrozoa") + } +} + idea { module { isDownloadJavadoc = true diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts deleted file mode 100644 index 6efc6d2..0000000 --- a/examples/build.gradle.kts +++ /dev/null @@ -1,6 +0,0 @@ -subprojects { - dependencies { - // Add Hydrozoa SDK from project root - implementation(project(":")) - } -} diff --git a/examples/clawbot-kotlin/build.gradle.kts b/examples/clawbot-kotlin/build.gradle.kts index 4a102ef..9d620e3 100644 --- a/examples/clawbot-kotlin/build.gradle.kts +++ b/examples/clawbot-kotlin/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - kotlin("jvm") version "2.0.20" - id("dev.vexide.hydrozoa") + kotlin("jvm") version libs.versions.kotlin + id("dev.vexide.hydrozoa") } hydrozoa { diff --git a/examples/clawbot-kotlin/settings.gradle.kts b/examples/clawbot-kotlin/settings.gradle.kts new file mode 100644 index 0000000..eaf86e3 --- /dev/null +++ b/examples/clawbot-kotlin/settings.gradle.kts @@ -0,0 +1,7 @@ +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} \ No newline at end of file diff --git a/gradle-plugin/build.gradle.kts b/gradle-plugin/build.gradle.kts index d1691a5..000ac8f 100644 --- a/gradle-plugin/build.gradle.kts +++ b/gradle-plugin/build.gradle.kts @@ -1,6 +1,6 @@ plugins { `kotlin-dsl` - id("com.gradle.plugin-publish") version "1.2.1" + alias(libs.plugins.publish) } group = "dev.vexide" diff --git a/gradle-plugin/settings.gradle.kts b/gradle-plugin/settings.gradle.kts index 3e17473..5ff2f2f 100644 --- a/gradle-plugin/settings.gradle.kts +++ b/gradle-plugin/settings.gradle.kts @@ -1 +1,9 @@ rootProject.name = "hydrozoa" + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..54e4993 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.parallel=true +org.gradle.caching=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..18aaf70 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,9 @@ +[libraries] + +[plugins] +teavm = { id = "org.teavm", version = "0.10.2" } +jreleaser = { id = "org.jreleaser", version = "1.15.0" } +publish = { id = "com.gradle.plugin-publish", version = "1.2.1" } + +[versions] +kotlin = "2.1.21" \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b41..ca025c8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/hydrozoa_api.json b/hydrozoa_api.json new file mode 100644 index 0000000..1022f2e --- /dev/null +++ b/hydrozoa_api.json @@ -0,0 +1,1752 @@ +{ + "name": "vex", + "items": [ + { + "name": "vexDisplayForegroundColor", + "params": [ + { + "name": "col", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayBackgroundColor", + "params": [ + { + "name": "col", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayErase", + "params": [], + "returns": null + }, + { + "name": "vexDisplayScroll", + "params": [ + { + "name": "nStartLine", + "type": { + "type": "Int" + } + }, + { + "name": "nLines", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayScrollRect", + "params": [ + { + "name": "x1", + "type": { + "type": "Int" + } + }, + { + "name": "y1", + "type": { + "type": "Int" + } + }, + { + "name": "x2", + "type": { + "type": "Int" + } + }, + { + "name": "y2", + "type": { + "type": "Int" + } + }, + { + "name": "nLines", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayPixelSet", + "params": [ + { + "name": "x", + "type": { + "type": "Int" + } + }, + { + "name": "y", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayPixelClear", + "params": [ + { + "name": "x", + "type": { + "type": "Int" + } + }, + { + "name": "y", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayLineDraw", + "params": [ + { + "name": "x1", + "type": { + "type": "Int" + } + }, + { + "name": "y1", + "type": { + "type": "Int" + } + }, + { + "name": "x2", + "type": { + "type": "Int" + } + }, + { + "name": "y2", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayLineClear", + "params": [ + { + "name": "x1", + "type": { + "type": "Int" + } + }, + { + "name": "y1", + "type": { + "type": "Int" + } + }, + { + "name": "x2", + "type": { + "type": "Int" + } + }, + { + "name": "y2", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayRectDraw", + "params": [ + { + "name": "x1", + "type": { + "type": "Int" + } + }, + { + "name": "y1", + "type": { + "type": "Int" + } + }, + { + "name": "x2", + "type": { + "type": "Int" + } + }, + { + "name": "y2", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayRectClear", + "params": [ + { + "name": "x1", + "type": { + "type": "Int" + } + }, + { + "name": "y1", + "type": { + "type": "Int" + } + }, + { + "name": "x2", + "type": { + "type": "Int" + } + }, + { + "name": "y2", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayRectFill", + "params": [ + { + "name": "x1", + "type": { + "type": "Int" + } + }, + { + "name": "y1", + "type": { + "type": "Int" + } + }, + { + "name": "x2", + "type": { + "type": "Int" + } + }, + { + "name": "y2", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayCircleDraw", + "params": [ + { + "name": "xc", + "type": { + "type": "Int" + } + }, + { + "name": "yc", + "type": { + "type": "Int" + } + }, + { + "name": "radius", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayCircleClear", + "params": [ + { + "name": "xc", + "type": { + "type": "Int" + } + }, + { + "name": "yc", + "type": { + "type": "Int" + } + }, + { + "name": "radius", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayCircleFill", + "params": [ + { + "name": "xc", + "type": { + "type": "Int" + } + }, + { + "name": "yc", + "type": { + "type": "Int" + } + }, + { + "name": "radius", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayTextSize", + "params": [ + { + "name": "n", + "type": { + "type": "Int" + } + }, + { + "name": "d", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayForegroundColorGet", + "params": [], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDisplayBackgroundColorGet", + "params": [], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDisplayClipRegionSet", + "params": [ + { + "name": "x1", + "type": { + "type": "Int" + } + }, + { + "name": "y1", + "type": { + "type": "Int" + } + }, + { + "name": "x2", + "type": { + "type": "Int" + } + }, + { + "name": "y2", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayRender", + "params": [ + { + "name": "bVsyncWait", + "type": { + "type": "Bool" + } + }, + { + "name": "bRunScheduler", + "type": { + "type": "Bool" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayDoubleBufferDisable", + "params": [], + "returns": null + }, + { + "name": "vexDisplayClipRegionSetWithIndex", + "params": [ + { + "name": "index", + "type": { + "type": "Int" + } + }, + { + "name": "x1", + "type": { + "type": "Int" + } + }, + { + "name": "y1", + "type": { + "type": "Int" + } + }, + { + "name": "x2", + "type": { + "type": "Int" + } + }, + { + "name": "y2", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayPrintf", + "params": [ + { + "name": "xpos", + "type": { + "type": "Int" + } + }, + { + "name": "ypos", + "type": { + "type": "Int" + } + }, + { + "name": "bOpaque", + "type": { + "type": "Bool" + } + }, + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayString", + "params": [ + { + "name": "nLineNumber", + "type": { + "type": "Int" + } + }, + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayStringAt", + "params": [ + { + "name": "xpos", + "type": { + "type": "Int" + } + }, + { + "name": "ypos", + "type": { + "type": "Int" + } + }, + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayBigString", + "params": [ + { + "name": "nLineNumber", + "type": { + "type": "Int" + } + }, + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayBigStringAt", + "params": [ + { + "name": "xpos", + "type": { + "type": "Int" + } + }, + { + "name": "ypos", + "type": { + "type": "Int" + } + }, + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": null + }, + { + "name": "vexDisplaySmallStringAt", + "params": [ + { + "name": "xpos", + "type": { + "type": "Int" + } + }, + { + "name": "ypos", + "type": { + "type": "Int" + } + }, + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayCenteredString", + "params": [ + { + "name": "nLineNumber", + "type": { + "type": "Int" + } + }, + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayBigCenteredString", + "params": [ + { + "name": "nLineNumber", + "type": { + "type": "Int" + } + }, + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": null + }, + { + "name": "vexDisplayStringWidthGet", + "params": [ + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDisplayStringHeightGet", + "params": [ + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDisplayFontNamedSet", + "params": [ + { + "name": "string", + "type": { + "type": "StringPtr" + } + } + ], + "returns": null + }, + { + "name": "vexControllerGet", + "params": [ + { + "name": "id", + "type": { + "type": "Named", + "name": "V5_ControllerId" + } + }, + { + "name": "index", + "type": { + "type": "Named", + "name": "V5_ControllerIndex" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexControllerConnectionStatusGet", + "params": [ + { + "name": "id", + "type": { + "type": "Named", + "name": "V5_ControllerId" + } + } + ], + "returns": { + "type": "Named", + "name": "V5_ControllerStatus" + } + }, + { + "name": "vexDeviceGetByIndex", + "params": [ + { + "name": "index", + "type": { + "type": "Int" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorVelocitySet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "velocity", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorVelocityGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorActualVelocityGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Double" + } + }, + { + "name": "vexDeviceMotorDirectionGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorModeSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "mode", + "type": { + "type": "Named", + "name": "V5MotorControlMode" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorModeGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Named", + "name": "V5MotorControlMode" + } + }, + { + "name": "vexDeviceMotorPwmSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "pwm", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorPwmGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorCurrentLimitSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "limit", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorCurrentLimitGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorCurrentGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorPowerGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Double" + } + }, + { + "name": "vexDeviceMotorTorqueGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Double" + } + }, + { + "name": "vexDeviceMotorEfficiencyGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Double" + } + }, + { + "name": "vexDeviceMotorTemperatureGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Double" + } + }, + { + "name": "vexDeviceMotorOverTempFlagGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Bool" + } + }, + { + "name": "vexDeviceMotorCurrentLimitFlagGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Bool" + } + }, + { + "name": "vexDeviceMotorZeroVelocityFlagGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Bool" + } + }, + { + "name": "vexDeviceMotorZeroPositionFlagGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Bool" + } + }, + { + "name": "vexDeviceMotorReverseFlagSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "reverse", + "type": { + "type": "Bool" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorReverseFlagGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Bool" + } + }, + { + "name": "vexDeviceMotorEncoderUnitsSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "units", + "type": { + "type": "Named", + "name": "V5MotorEncoderUnits" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorEncoderUnitsGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Named", + "name": "V5MotorEncoderUnits" + } + }, + { + "name": "vexDeviceMotorBrakeModeSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "mode", + "type": { + "type": "Named", + "name": "V5MotorBrakeMode" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorBrakeModeGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Named", + "name": "V5MotorBrakeMode" + } + }, + { + "name": "vexDeviceMotorPositionSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "position", + "type": { + "type": "Double" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorPositionGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Double" + } + }, + { + "name": "vexDeviceMotorPositionReset", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorTargetGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Double" + } + }, + { + "name": "vexDeviceMotorServoTargetSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "position", + "type": { + "type": "Double" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorAbsoluteTargetSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "position", + "type": { + "type": "Double" + } + }, + { + "name": "veloctiy", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorRelativeTargetSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "position", + "type": { + "type": "Double" + } + }, + { + "name": "velocity", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorFaultsGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorFlagsGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorVoltageSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "voltage", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorVoltageGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorGearingSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "gearset", + "type": { + "type": "Named", + "name": "V5MotorGearset" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorGearingGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Named", + "name": "V5MotorGearset" + } + }, + { + "name": "vexDeviceMotorVoltageLimitSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "limit", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorVoltageLimitGet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexDeviceMotorVelocityUpdate", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "velocity", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceMotorExternalProfileSet", + "params": [ + { + "name": "device", + "type": { + "type": "Named", + "name": "V5_Device" + } + }, + { + "name": "position", + "type": { + "type": "Double" + } + }, + { + "name": "velocity", + "type": { + "type": "Int" + } + } + ], + "returns": null + }, + { + "name": "vexDeviceGetStatus", + "params": [ + { + "name": "devices", + "type": { + "type": "Pointer", + "destination": { + "type": "Named", + "name": "V5_DeviceType" + } + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexSerialWriteChar", + "params": [ + { + "name": "channel", + "type": { + "type": "Int" + } + }, + { + "name": "c", + "type": { + "type": "Int" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexSerialReadChar", + "params": [ + { + "name": "channel", + "type": { + "type": "Int" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexSerialPeekChar", + "params": [ + { + "name": "channel", + "type": { + "type": "Int" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexSerialWriteFree", + "params": [ + { + "name": "channel", + "type": { + "type": "Int" + } + } + ], + "returns": { + "type": "Int" + } + }, + { + "name": "vexSystemTimeGet", + "params": [], + "returns": { + "type": "Int" + } + }, + { + "name": "vexSystemExitRequest", + "params": [], + "returns": null + }, + { + "name": "vexSystemHighResTimeGet", + "params": [], + "returns": { + "type": "Long" + } + }, + { + "name": "vexSystemPowerupTimeGet", + "params": [], + "returns": { + "type": "Long" + } + }, + { + "name": "vexSystemLinkAddrGet", + "params": [], + "returns": { + "type": "Int" + } + }, + { + "name": "vexSystemVersion", + "params": [], + "returns": { + "type": "Int" + } + }, + { + "name": "vexStdlibVersion", + "params": [], + "returns": { + "type": "Int" + } + }, + { + "name": "vexTasksRun", + "params": [], + "returns": null + }, + { + "name": "vexCompetitionStatus", + "params": [], + "returns": { + "type": "Int" + } + } + ], + "enums": [ + { + "name": "V5_ControllerId", + "underlying_type": { + "type": "Int" + }, + "variants": { + "kControllerPartner": 1, + "kControllerMaster": 0 + } + }, + { + "name": "V5_ControllerStatus", + "underlying_type": { + "type": "Int" + }, + "variants": { + "kV5ControllerOffline": 0, + "kV5ControllerTethered": 1, + "kV5ControllerVexnet": 2 + } + }, + { + "name": "V5_ControllerIndex", + "underlying_type": { + "type": "Int" + }, + "variants": { + "Flags": 21, + "ButtonL2": 7, + "ButtonAll": 20, + "Button7L": 12, + "ButtonR2": 9, + "Axis3": 1, + "Button6U": 8, + "AnaRightX": 2, + "ButtonLeft": 12, + "ButtonRight": 13, + "ButtonX": 14, + "AnaLeftY": 1, + "Axis1": 2, + "ButtonA": 17, + "Axis4": 0, + "AnaLeftX": 0, + "Button6D": 9, + "Button7R": 13, + "ButtonY": 16, + "BatteryCapacity": 22, + "Button8L": 16, + "Button8D": 15, + "AnaSpare1": 4, + "Button7D": 11, + "ButtonSEL": 18, + "AnaSpare2": 5, + "Axis2": 3, + "Button5D": 7, + "Button8R": 17, + "ButtonL1": 6, + "ButtonUp": 10, + "AnaRightY": 3, + "Button8U": 14, + "Button5U": 6, + "BatteryLevel": 19, + "ButtonR1": 8, + "ButtonDown": 11, + "ButtonB": 15, + "Button7U": 10 + } + }, + { + "name": "V5MotorBrakeMode", + "underlying_type": { + "type": "Int" + }, + "variants": { + "kV5MotorBrakeModeHold": 2, + "kV5MotorBrakeModeCoast": 0, + "kV5MotorBrakeModeBrake": 1 + } + }, + { + "name": "V5MotorControlMode", + "underlying_type": { + "type": "Int" + }, + "variants": { + "kMotorControlModePROFILE": 4, + "kMotorControlModeBRAKE": 1, + "kMotorControlModeSERVO": 3, + "kMotorControlModeOFF": 0, + "kMotorControlModeUNDEFINED": 6, + "kMotorControlModeVELOCITY": 5, + "kMotorControlModeHOLD": 2 + } + }, + { + "name": "V5MotorEncoderUnits", + "underlying_type": { + "type": "Int" + }, + "variants": { + "kMotorEncoderCounts": 2, + "kMotorEncoderRotations": 1, + "kMotorEncoderDegrees": 0 + } + }, + { + "name": "V5MotorGearset", + "underlying_type": { + "type": "Int" + }, + "variants": { + "kMotorGearSet_06": 2, + "kMotorGearSet_18": 1, + "kMotorGearSet_36": 0 + } + }, + { + "name": "V5_Device", + "underlying_type": { + "type": "Int" + }, + "variants": {} + }, + { + "name": "V5_DeviceType", + "underlying_type": { + "type": "Int" + }, + "variants": { + "kDeviceTypeGyroSensor": 70, + "kDeviceTypeAdiSensor": 12, + "kDeviceTypeRadioSensor": 8, + "kDeviceTypeLedSensor": 3, + "kDeviceTypeTetherSensor": 9, + "kDeviceTypeRes3Sensor": 15, + "kDeviceTypeDistanceSensor": 7, + "kDeviceTypeAiVisionSensor": 29, + "kDeviceTypeNoSensor": 0, + "kDeviceTypeCrMotorSensor": 5, + "kDeviceTypeBumperSensor": 64, + "kDeviceTypeGenericSensor": 128, + "kDeviceTypeRes1Sensor": 13, + "kDeviceTypeImuSensor": 6, + "kDeviceTypeOpticalSensor": 16, + "kDeviceTypeAbsEncSensor": 4, + "kDeviceTypeGpsSensor": 20, + "kDeviceTypeBrainSensor": 10, + "kDeviceTypeMagnetSensor": 17, + "kDeviceTypePneumaticSensor": 30, + "kDeviceTypeGenericSerial": 129, + "kDeviceTypeLightTowerSensor": 27, + "kDeviceTypeSonarSensor": 71, + "kDeviceTypeAicameraSensor": 26, + "kDeviceTypeUndefinedSensor": 255, + "kDeviceTypeMotorSensor": 2, + "kDeviceTypeArmDevice": 28, + "kDeviceTypeVisionSensor": 11, + "kDeviceTypeRes2Sensor": 14 + } + } + ] +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 9c1e694..ecd4932 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,13 +4,17 @@ plugins { rootProject.name = "hydrozoa" includeBuild("gradle-plugin") +includeBuild("bindings-generator") include("vex-sdk") findProject("vex-sdk")?.name = "vex-sdk" -include("examples:clawbot") -findProject(":examples:clawbot")?.name = "clawbot" -include("examples:clawbot-kotlin") -findProject(":examples:clawbot-kotlin")?.name = "clawbot-kotlin" -include("examples:screen") -findProject(":examples:screen")?.name = "screen" +val examples = file("examples").listFiles() +for (exampleFile in examples) { + includeBuild(exampleFile) { + name = "examples.${exampleFile.name}" + dependencySubstitution { + substitute(module("dev.vexide.hydrozoa:hydrozoa")).using(project(":")) + } + } +} diff --git a/src/main/java/dev/vexide/hydrozoa/CompetitionRuntime.java b/src/main/java/dev/vexide/hydrozoa/CompetitionRuntime.java index 0421d17..cb39fc2 100644 --- a/src/main/java/dev/vexide/hydrozoa/CompetitionRuntime.java +++ b/src/main/java/dev/vexide/hydrozoa/CompetitionRuntime.java @@ -55,7 +55,7 @@ public static void start(@NotNull Function<@NotNull Peripherals, @NotNull Compet while (true) { var begin = Instant.now(); - VexSdk.vexTasksRun(); + VexSdk.Tasks.run(); var status = status(); @@ -106,7 +106,7 @@ public static void start(@NotNull Function<@NotNull Peripherals, @NotNull Compet */ @Contract(value = "-> new", pure = true) public static @NotNull Status status() { - return Status.fromBitflags(VexSdk.vexCompetitionStatus()); + return Status.fromBitflags(VexSdk.Competition.status()); } /** diff --git a/src/main/java/dev/vexide/hydrozoa/Peripherals.java b/src/main/java/dev/vexide/hydrozoa/Peripherals.java index abb09f3..8db21b0 100644 --- a/src/main/java/dev/vexide/hydrozoa/Peripherals.java +++ b/src/main/java/dev/vexide/hydrozoa/Peripherals.java @@ -10,28 +10,27 @@ import java.util.NoSuchElementException; import java.util.Optional; -/** - * A collection of all the peripherals that are available to the robot. - *

- * Peripherals instances can be used to initialize the robot's hardware by using the various {@code take*} methods. - * It is important to understand that peripherals may only be removed from the Peripherals instance once. This helps - * to prevent the accidental duplication of hardware resources. - *

- * For example, the following examples will throw exceptions because the port number 1 has already been used: - *

{@code
- * var peripherals = Peripherals.take().orElseThrow();
- *
- * Motor leftMotor = new Motor(peripherals.takePort(1), Motor.Gearset.GREEN, Motor.Direction.FORWARD);
- * Motor rightMotor = new Motor(peripherals.takePort(1), Motor.Gearset.GREEN, Motor.Direction.FORWARD);
- * }
- *
{@code
- * var peripherals = Peripherals.take().orElseThrow();
- *
- * var port = peripherals.takePort(1);
- * Motor leftMotor = new Motor(port, Motor.Gearset.GREEN, Motor.Direction.FORWARD);
- * Motor rightMotor = new Motor(port, Motor.Gearset.GREEN, Motor.Direction.FORWARD);
- * }
- */ +/// A collection of all the peripherals that are available to the robot. +/// +/// Peripherals instances can be used to initialize the robot's hardware by using the various {@code take*} methods. +/// It is important to understand that peripherals may only be removed from the Peripherals instance once. This helps +/// to prevent the accidental duplication of hardware resources. +/// +/// For example, the following examples will throw exceptions because the port number 1 has already been used: +/// ```java +/// var peripherals = Peripherals.take().orElseThrow(); +/// +/// Motor leftMotor = new Motor(peripherals.takePort(1), Motor.Gearset.GREEN, Motor.Direction.FORWARD); +/// Motor rightMotor = new Motor(peripherals.takePort(1), Motor.Gearset.GREEN, Motor.Direction.FORWARD); +/// ``` +/// +/// ```java +/// var peripherals = Peripherals.take().orElseThrow(); +/// +/// var port = peripherals.takePort(1); +/// Motor leftMotor = new Motor(port, Motor.Gearset.GREEN, Motor.Direction.FORWARD); +/// Motor rightMotor = new Motor(port, Motor.Gearset.GREEN, Motor.Direction.FORWARD); +/// ``` public class Peripherals { private static final Key key = new Key(); private static Peripherals instance = new Peripherals(); @@ -47,11 +46,9 @@ private Peripherals() { } } - /** - * Creates a new instance of the Peripherals class. This method may only be called once. - * - * @return a new instance of the Peripherals class, or an empty optional if this method has already been called - */ + /// Creates a new instance of the Peripherals class. This method may only be called once. + /// + /// @return a new instance of the Peripherals class, or an empty optional if this method has already been called public static Optional take() { if (instance == null) { return Optional.empty(); @@ -62,26 +59,24 @@ public static Optional take() { return Optional.of(peripherals); } - /** - * Infallibly creates a new instance of the Peripherals class. Using this method can make your program - * susceptible to mistakes such as accidentally creating two motors that use the same smart port. - *

Conditions

- *

- * This method may not be used to allow multiple instances of smart devices that use the same port to exist - * simultaneously. - * @return a new instance of the Peripherals class - */ + /// Infallibly creates a new instance of the Peripherals class. Using this method can make your program + /// susceptible to mistakes such as accidentally creating two motors that use the same smart port. + /// + /// #### Conditions + /// + /// This method may not be used to allow multiple instances of smart devices that use the same port to exist + /// simultaneously. + /// + /// @return a new instance of the Peripherals class public static @NotNull Peripherals unsafelyCreate() { return new Peripherals(); } - /** - * Takes a smart port from this collection. - * @param portNumber the port number to take, as labeled on the robot brain - * @return the smart port - * @throws IllegalArgumentException if the port number is not in the range [1, 21] - * @throws NoSuchElementException if the port has already been removed - */ + /// Takes a smart port from this collection. + /// @param portNumber the port number to take, as labeled on the robot brain + /// @return the smart port + /// @throws IllegalArgumentException if the port number is not in the range [1, 21] + /// @throws NoSuchElementException if the port has already been removed @Contract("_ -> new") public @NotNull SmartPort takePort(int portNumber) throws IllegalArgumentException, NoSuchElementException { if (portNumber <= 0 || portNumber > ports.length) { @@ -99,12 +94,10 @@ public static Optional take() { return port; } - /** - * Takes a controller from this collection. - * @param id the ID of the controller to take - * @return the controller - * @throws NoSuchElementException if the controller with this ID has already been removed - */ + /// Takes a controller from this collection. + /// @param id the ID of the controller to take + /// @return the controller + /// @throws NoSuchElementException if the controller with this ID has already been removed @Contract("_ -> new") public @NotNull Controller takeController(@NotNull Controller.Id id) throws NoSuchElementException { Controller controller; @@ -123,11 +116,9 @@ public static Optional take() { return controller; } - /** - * Takes the display from this collection. - * @return the display - * @throws NoSuchElementException if the display has already been removed - */ + /// Takes the display from this collection. + /// @return the display + /// @throws NoSuchElementException if the display has already been removed @Contract("-> new") public @NotNull Display takeDisplay() throws NoSuchElementException { var display = this.display; @@ -140,9 +131,8 @@ public static Optional take() { return display; } - /** - * A unique key that is used to prevent the creation of peripheral devices outside the Peripherals class. - */ + /// A unique key that is used to prevent the creation of peripheral devices outside the Peripherals class. + /// @hidden public static class Key { private Key() {} } diff --git a/src/main/java/dev/vexide/hydrozoa/Platform.java b/src/main/java/dev/vexide/hydrozoa/Platform.java index 673b2fe..19a510c 100644 --- a/src/main/java/dev/vexide/hydrozoa/Platform.java +++ b/src/main/java/dev/vexide/hydrozoa/Platform.java @@ -25,7 +25,7 @@ private Platform() { * flushed. */ public static void yield() { - VexSdk.vexTasksRun(); + VexSdk.Tasks.run(); } private static final Duration FLUSH_TIMEOUT = Duration.ofMillis(15); diff --git a/src/main/java/dev/vexide/hydrozoa/devices/Controller.java b/src/main/java/dev/vexide/hydrozoa/devices/Controller.java index 3dd6faf..00ce67a 100644 --- a/src/main/java/dev/vexide/hydrozoa/devices/Controller.java +++ b/src/main/java/dev/vexide/hydrozoa/devices/Controller.java @@ -2,9 +2,9 @@ import dev.vexide.hydrozoa.CompetitionRuntime; import dev.vexide.hydrozoa.Peripherals; -import dev.vexide.hydrozoa.sdk.V5_ControllerId; -import dev.vexide.hydrozoa.sdk.V5_ControllerIndex; -import dev.vexide.hydrozoa.sdk.V5_ControllerStatus; +import dev.vexide.hydrozoa.sdk.VexControllerId; +import dev.vexide.hydrozoa.sdk.VexControllerIndex; +import dev.vexide.hydrozoa.sdk.VexControllerStatus; import dev.vexide.hydrozoa.sdk.VexSdk; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; @@ -49,8 +49,8 @@ public Controller(@NotNull Peripherals.Key ignoredKey, @NotNull Id type) { * @return {@code true} if the controller is connected, {@code false} otherwise */ public boolean connected() { - var status = VexSdk.Controller.vexControllerConnectionStatusGet(id.raw()); - return !status.equals(V5_ControllerStatus.kV5ControllerOffline); + var status = VexSdk.Controller.getConnectionStatus(id.raw()); + return !status.equals(VexControllerStatus.OFFLINE); } /** @@ -62,7 +62,41 @@ public boolean connected() { if (!CompetitionRuntime.mode().equals(CompetitionRuntime.Mode.Driver) || !connected()) { return Optional.empty(); } - var state = new State(new JoystickState((byte) VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.AnaLeftX), (byte) VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.AnaLeftY)), new JoystickState((byte) VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.AnaRightX), (byte) VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.AnaRightY)), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonA) == 1, previousState.a().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonB) == 1, previousState.b().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonX) == 1, previousState.x().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonY) == 1, previousState.y().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonUp) == 1, previousState.up().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonDown) == 1, previousState.down().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonLeft) == 1, previousState.left().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonRight) == 1, previousState.right().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonL1) == 1, previousState.l1().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonL2) == 1, previousState.l2().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonR1) == 1, previousState.r1().pressed()), new ButtonState(VexSdk.Controller.vexControllerGet(id.raw(), V5_ControllerIndex.ButtonR2) == 1, previousState.r2().pressed())); + + var state = new State( + new JoystickState( + (byte) VexSdk.Controller.get(id.raw(), VexControllerIndex.ANA_LEFT_X), + (byte) VexSdk.Controller.get(id.raw(), VexControllerIndex.ANA_LEFT_Y)), + new JoystickState( + (byte) VexSdk.Controller.get(id.raw(), VexControllerIndex.ANA_RIGHT_X), + (byte) VexSdk.Controller.get(id.raw(), VexControllerIndex.ANA_RIGHT_Y)), + + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_A) == 1, + previousState.a().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_B) == 1, + previousState.b().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_X) == 1, + previousState.x().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_Y) == 1, + previousState.y().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_UP) == 1, + previousState.up().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_DOWN) == 1, + previousState.down().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_LEFT) == 1, + previousState.left().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_RIGHT) == 1, + previousState.right().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_L1) == 1, + previousState.l1().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_L2) == 1, + previousState.l2().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_R1) == 1, + previousState.r1().pressed()), + new ButtonState(VexSdk.Controller.get(id.raw(), VexControllerIndex.BUTTON_R2) == 1, + previousState.r2().pressed()) + ); + previousState = state; return Optional.of(state); } @@ -86,10 +120,10 @@ public enum Id { * * @return the raw controller ID value */ - @NotNull V5_ControllerId raw() { + @NotNull VexControllerId raw() { return switch (this) { - case Primary -> V5_ControllerId.kControllerMaster; - case Partner -> V5_ControllerId.kControllerPartner; + case Primary -> VexControllerId.MASTER; + case Partner -> VexControllerId.PARTNER; }; } } diff --git a/src/main/java/dev/vexide/hydrozoa/devices/smart/EncoderPosition.java b/src/main/java/dev/vexide/hydrozoa/devices/smart/EncoderPosition.java index ab57865..fd47852 100644 --- a/src/main/java/dev/vexide/hydrozoa/devices/smart/EncoderPosition.java +++ b/src/main/java/dev/vexide/hydrozoa/devices/smart/EncoderPosition.java @@ -3,197 +3,160 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -/** - * The position of an encoder. - * - * @param raw the number of ticks the encoder has counted - */ +/// The position of an encoder. +/// +/// @param raw the number of ticks the encoder has counted +//// public record EncoderPosition(long raw) { - /** - * The ticks per rotation ratio internally used by the {@code EncoderPosition} class. - */ + /// The ticks per rotation ratio internally used by the `EncoderPosition` class. public static final int INTERNAL_TPR = 4_608_000; - /** - * Creates a new encoder position using a number of ticks. - * - * @param ticks the number of ticks the encoder has counted - * @param tpr the number of ticks which represent one full rotation of the encoder - * @return the new encoder position - */ + /// Creates a new encoder position using a number of ticks. + /// + /// @param ticks the number of ticks the encoder has counted + /// @param tpr the number of ticks which represent one full rotation of the encoder + /// @return the new encoder position @Contract(value = "_, _ -> new", pure = true) public static @NotNull EncoderPosition ofTicks(long ticks, int tpr) { return new EncoderPosition(ticks * ((long) INTERNAL_TPR / (long) tpr)); } - /** - * Creates a new encoder position using a number of degrees. - * - * @param degrees the number of degrees the encoder has rotated - * @return the new encoder position - */ + /// Creates a new encoder position using a number of degrees. + /// + /// @param degrees the number of degrees the encoder has rotated + /// @return the new encoder position @Contract(value = "_ -> new", pure = true) public static @NotNull EncoderPosition ofDegrees(double degrees) { return new EncoderPosition((long) (degrees / 360.0 * INTERNAL_TPR)); } - /** - * Creates a new encoder position using a number of radians. - * - * @param radians the number of radians the encoder has rotated - * @return the new encoder position - */ + /// Creates a new encoder position using a number of radians. + /// + /// @param radians the number of radians the encoder has rotated + /// @return the new encoder position @Contract(value = "_ -> new", pure = true) public static @NotNull EncoderPosition ofRadians(double radians) { return new EncoderPosition((long) (radians / Math.TAU * INTERNAL_TPR)); } - /** - * Creates a new encoder position using a number of rotations. - * - * @param rotations the number of full rotations the encoder has completed - * @return the new encoder position - */ + /// Creates a new encoder position using a number of rotations. + /// + /// @param rotations the number of full rotations the encoder has completed + /// @return the new encoder position @Contract(value = "_ -> new", pure = true) public static @NotNull EncoderPosition ofRotations(double rotations) { return new EncoderPosition((long) (rotations * INTERNAL_TPR)); } - /** - * Converts the encoder position to a number of ticks at a given TPR ratio. - * - * @param tpr the number of ticks which represent one full rotation of the encoder - * @return the number of ticks the encoder has counted - */ + /// Converts the encoder position to a number of ticks at a given TPR ratio. + /// + /// @param tpr the number of ticks which represent one full rotation of the encoder + /// @return the number of ticks the encoder has counted @Contract(pure = true) public long ticks(int tpr) { return raw * tpr / INTERNAL_TPR; } - /** - * Converts the encoder position to a number of degrees. - * - * @return the number of degrees the encoder has rotated - */ + /// Converts the encoder position to a number of degrees. + /// + /// @return the number of degrees the encoder has rotated @Contract(pure = true) public double degrees() { return (double) raw / INTERNAL_TPR * 360.0; } - /** - * Converts the encoder position to a number of radians. - * - * @return the number of radians the encoder has rotated - */ + /// Converts the encoder position to a number of radians. + /// + /// @return the number of radians the encoder has rotated @Contract(pure = true) public double radians() { return (double) raw / INTERNAL_TPR * Math.TAU; } - /** - * Converts the encoder position to a number of full rotations. - * - * @return the number of full rotations the encoder has completed - */ + /// Converts the encoder position to a number of full rotations. + /// + /// @return the number of full rotations the encoder has completed @Contract(pure = true) public double rotations() { return (double) raw / INTERNAL_TPR; } - /** - * Adds two encoder positions together. - * - * @param other the other encoder position - * @return the sum of the two encoder positions - */ + /// Adds two encoder positions together. + /// + /// @param other the other encoder position + /// @return the sum of the two encoder positions @Contract(pure = true) public @NotNull EncoderPosition plus(@NotNull EncoderPosition other) { return new EncoderPosition(raw + other.raw); } - /** - * Subtracts one encoder position from another. - * - * @param other the other encoder position - * @return the difference of the two encoder positions - */ + /// Subtracts one encoder position from another. + /// + /// @param other the other encoder position + /// @return the difference of the two encoder positions @Contract(pure = true) public @NotNull EncoderPosition minus(@NotNull EncoderPosition other) { return new EncoderPosition(raw - other.raw); } - /** - * Multiplies an encoder position by a scalar. - * - * @param scalar the scalar to multiply by - * @return the product of the encoder position and the scalar - */ + /// Multiplies an encoder position by a scalar. + /// + /// @param scalar the scalar to multiply by + /// @return the product of the encoder position and the scalar @Contract(pure = true) public @NotNull EncoderPosition times(int scalar) { return new EncoderPosition(raw * scalar); } - /** - * Divides an encoder position by a scalar. - * - * @param scalar the scalar to divide by - * @return the quotient of the encoder position and the scalar - */ + /// Divides an encoder position by a scalar. + /// + /// @param scalar the scalar to divide by + /// @return the quotient of the encoder position and the scalar @Contract(pure = true) public @NotNull EncoderPosition div(int scalar) { return new EncoderPosition(raw / scalar); } - /** - * Computes the remainder of dividing an encoder position by a scalar. - * - * @param scalar the scalar to divide by - * @return the remainder of the division - */ + /// Computes the remainder of dividing an encoder position by a scalar. + /// + /// @param scalar the scalar to divide by + /// @return the remainder of the division @Contract(pure = true) public @NotNull EncoderPosition rem(int scalar) { return new EncoderPosition(raw % scalar); } - /** - * Computes the floor modulus of dividing an encoder position by a scalar. - * - * @param scalar the scalar to divide by - * @return the floor modulus of the division - * @see Math#floorMod(int, int) - */ + /// Computes the floor modulus of dividing an encoder position by a scalar. + /// + /// @param scalar the scalar to divide by + /// @return the floor modulus of the division + /// @see Math#floorMod(int, int) @Contract(pure = true) public @NotNull EncoderPosition mod(int scalar) { return new EncoderPosition(Math.floorMod(raw, scalar)); } - /** - * Computes the absolute value of the encoder position. - * - * @return the absolute value of the encoder position - */ + /// Computes the absolute value of the encoder position. + /// + /// @return the absolute value of the encoder position @Contract(pure = true) public @NotNull EncoderPosition abs() { return new EncoderPosition(Math.abs(raw)); } - /** - * Computes the negation of the encoder position. - * - * @return the negation of the encoder position - */ + /// Computes the negation of the encoder position. + /// + /// @return the negation of the encoder position @Contract(pure = true) public @NotNull EncoderPosition unaryMinus() { return new EncoderPosition(-raw); } - /** - * Compares two encoder positions numerically. - * - * @param other the other encoder position - * @return the value {@code 0} if {@code this = other}; a value less than {@code 0} if {@code this < other}; and a - * value greater than {@code 0} if {@code this > other} - */ + /// Compares two encoder positions numerically. + /// + /// @param other the other encoder position + /// @return the value {@code 0} if {@code this = other}; a value less than {@code 0} if {@code this < other}; and a + /// value greater than {@code 0} if {@code this > other} @Contract(pure = true) public int compareTo(@NotNull EncoderPosition other) { return Long.compare(raw, other.raw); diff --git a/src/main/java/dev/vexide/hydrozoa/devices/smart/Motor.java b/src/main/java/dev/vexide/hydrozoa/devices/smart/Motor.java index 33510ac..2f6147e 100644 --- a/src/main/java/dev/vexide/hydrozoa/devices/smart/Motor.java +++ b/src/main/java/dev/vexide/hydrozoa/devices/smart/Motor.java @@ -2,9 +2,9 @@ import dev.vexide.hydrozoa.CompetitionRuntime; import dev.vexide.hydrozoa.DeviceException; -import dev.vexide.hydrozoa.sdk.V5MotorBrakeMode; -import dev.vexide.hydrozoa.sdk.V5MotorEncoderUnits; -import dev.vexide.hydrozoa.sdk.V5MotorGearset; +import dev.vexide.hydrozoa.sdk.VexMotorBrakeMode; +import dev.vexide.hydrozoa.sdk.VexMotorEncoderUnits; +import dev.vexide.hydrozoa.sdk.VexMotorGearset; import dev.vexide.hydrozoa.sdk.VexSdk; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -35,9 +35,9 @@ public Motor(@NotNull SmartPort port, @NotNull Gearset gearset, @NotNull Directi this.direction = direction; var handle = this.port.deviceHandle(); - VexSdk.Motor.vexDeviceMotorEncoderUnitsSet(handle, V5MotorEncoderUnits.Counts); - VexSdk.Motor.vexDeviceMotorReverseFlagSet(handle, direction.equals(Direction.REVERSE)); - VexSdk.Motor.vexDeviceMotorGearingSet(handle, gearset.getRaw()); + VexSdk.Device.setMotorEncoderUnits(handle, VexMotorEncoderUnits.COUNTS); + VexSdk.Device.setMotorReverseFlag(handle, direction.equals(Direction.REVERSE)); + VexSdk.Device.setMotorGearing(handle, gearset.getRaw()); } @Override @@ -61,7 +61,7 @@ public Motor(@NotNull SmartPort port, @NotNull Gearset gearset, @NotNull Directi */ public void setGearset(@NotNull Gearset gearset) { this.gearset = gearset; - VexSdk.Motor.vexDeviceMotorGearingSet(port.deviceHandle(), gearset.getRaw()); + VexSdk.Device.setMotorGearing(port.deviceHandle(), gearset.getRaw()); } /** @@ -80,7 +80,7 @@ public void setGearset(@NotNull Gearset gearset) { */ public void setDirection(@NotNull Direction direction) { this.direction = direction; - VexSdk.Motor.vexDeviceMotorReverseFlagSet(port.deviceHandle(), direction.equals(Direction.REVERSE)); + VexSdk.Device.setMotorReverseFlag(port.deviceHandle(), direction.equals(Direction.REVERSE)); } /** @@ -158,7 +158,7 @@ public void setTarget(@NotNull MotorControl target) throws DeviceException { public @NotNull EncoderPosition getPosition() throws DeviceException { validateConnection(); - double pos = VexSdk.Motor.vexDeviceMotorPositionGet(port.deviceHandle()); + double pos = VexSdk.Device.getMotorPosition(port.deviceHandle()); return EncoderPosition.ofTicks((int) pos, gearset.getTicksPerRevolution()); } @@ -171,7 +171,7 @@ public void setTarget(@NotNull MotorControl target) throws DeviceException { public void setPosition(@NotNull EncoderPosition position) throws DeviceException { validateConnection(); - VexSdk.Motor.vexDeviceMotorPositionSet( + VexSdk.Device.setMotorPosition( port.deviceHandle(), position.ticks(gearset.getTicksPerRevolution()) ); @@ -184,19 +184,19 @@ public enum Gearset { /** * The red (100 RPM) gearset. */ - Red(V5MotorGearset.GearSet_06), + Red(VexMotorGearset.GEAR_SET_06), /** * The green (200 RPM) gearset. */ - Green(V5MotorGearset.GearSet_18), + Green(VexMotorGearset.GEAR_SET_18), /** * The blue (600 RPM) gearset. */ - Blue(V5MotorGearset.GearSet_36); + Blue(VexMotorGearset.GEAR_SET_36); - private final V5MotorGearset raw; + private final VexMotorGearset raw; - Gearset(V5MotorGearset raw) { + Gearset(VexMotorGearset raw) { this.raw = raw; } @@ -206,7 +206,7 @@ public enum Gearset { * @return the raw gearset value */ @Contract(pure = true) - public V5MotorGearset getRaw() { + public VexMotorGearset getRaw() { return raw; } @@ -273,19 +273,19 @@ public enum BrakeMode { /** * The motor does not actively brake, allowing it to coast to a stop. */ - COAST(V5MotorBrakeMode.Coast), + Coast(VexMotorBrakeMode.COAST), /** * The motor uses regenerative braking to slow down faster. */ - BRAKE(V5MotorBrakeMode.Brake), + Brake(VexMotorBrakeMode.BRAKE), /** * The motor uses its internal PID controller to hold its current position. */ - HOLD(V5MotorBrakeMode.Hold); + Hold(VexMotorBrakeMode.HOLD); - private final V5MotorBrakeMode raw; + private final VexMotorBrakeMode raw; - BrakeMode(V5MotorBrakeMode raw) { + BrakeMode(VexMotorBrakeMode raw) { this.raw = raw; } @@ -295,7 +295,7 @@ public enum BrakeMode { * @return the raw brake mode value */ @Contract(pure = true) - public V5MotorBrakeMode getRaw() { + public VexMotorBrakeMode getRaw() { return raw; } } diff --git a/src/main/java/dev/vexide/hydrozoa/devices/smart/MotorControl.java b/src/main/java/dev/vexide/hydrozoa/devices/smart/MotorControl.java index c164a19..f503687 100644 --- a/src/main/java/dev/vexide/hydrozoa/devices/smart/MotorControl.java +++ b/src/main/java/dev/vexide/hydrozoa/devices/smart/MotorControl.java @@ -1,6 +1,6 @@ package dev.vexide.hydrozoa.devices.smart; -import dev.vexide.hydrozoa.sdk.V5MotorBrakeMode; +import dev.vexide.hydrozoa.sdk.VexMotorBrakeMode; import dev.vexide.hydrozoa.sdk.VexSdk; import org.jetbrains.annotations.NotNull; @@ -9,8 +9,8 @@ * * @see Motor#setTarget(MotorControl) */ -public abstract class MotorControl { - MotorControl() { +public sealed abstract class MotorControl { + private MotorControl() { } abstract void apply(@NotNull Motor motor); @@ -47,8 +47,8 @@ void apply(@NotNull Motor motor) { // } var handle = motor.port.deviceHandle(); - VexSdk.Motor.vexDeviceMotorBrakeModeSet(handle, V5MotorBrakeMode.Coast); - VexSdk.Motor.vexDeviceMotorVoltageSet(handle, (int) (getVoltage() * 1000)); + VexSdk.Device.setMotorBrakeMode(handle, VexMotorBrakeMode.COAST); + VexSdk.Device.setMotorVoltage(handle, (int) (getVoltage() * 1000)); } } @@ -79,8 +79,8 @@ public int getRpm() { @Override void apply(@NotNull Motor motor) { var handle = motor.port.deviceHandle(); - VexSdk.Motor.vexDeviceMotorBrakeModeSet(handle, V5MotorBrakeMode.Coast); - VexSdk.Motor.vexDeviceMotorVelocitySet(handle, getRpm()); + VexSdk.Device.setMotorBrakeMode(handle, VexMotorBrakeMode.COAST); + VexSdk.Device.setMotorVelocity(handle, getRpm()); } } @@ -123,8 +123,8 @@ public int getVelocity() { @Override void apply(@NotNull Motor motor) { var handle = motor.port.deviceHandle(); - VexSdk.Motor.vexDeviceMotorBrakeModeSet(handle, V5MotorBrakeMode.Coast); - VexSdk.Motor.vexDeviceMotorAbsoluteTargetSet( + VexSdk.Device.setMotorBrakeMode(handle, VexMotorBrakeMode.COAST); + VexSdk.Device.setMotorAbsoluteTarget( handle, getPosition().ticks(motor.getGearset().getTicksPerRevolution()), getVelocity() @@ -159,8 +159,8 @@ public Brake(@NotNull Motor.BrakeMode mode) { @Override void apply(@NotNull Motor motor) { var handle = motor.port.deviceHandle(); - VexSdk.Motor.vexDeviceMotorBrakeModeSet(handle, getMode().getRaw()); - VexSdk.Motor.vexDeviceMotorVelocitySet(handle, 0); + VexSdk.Device.setMotorBrakeMode(handle, getMode().getRaw()); + VexSdk.Device.setMotorVelocity(handle, 0); } } } diff --git a/src/main/java/dev/vexide/hydrozoa/devices/smart/SmartDevice.java b/src/main/java/dev/vexide/hydrozoa/devices/smart/SmartDevice.java index 0966225..e234573 100644 --- a/src/main/java/dev/vexide/hydrozoa/devices/smart/SmartDevice.java +++ b/src/main/java/dev/vexide/hydrozoa/devices/smart/SmartDevice.java @@ -1,7 +1,8 @@ package dev.vexide.hydrozoa.devices.smart; import dev.vexide.hydrozoa.DeviceException; -import dev.vexide.hydrozoa.sdk.V5_DeviceType; +import dev.vexide.hydrozoa.sdk.VexDevice; +import dev.vexide.hydrozoa.sdk.VexDeviceType; import org.jetbrains.annotations.NotNull; import java.time.Duration; @@ -91,67 +92,67 @@ public enum Type { /** * A VEX V5 Smart Motor. */ - MOTOR(V5_DeviceType.MotorSensor), + MOTOR(VexDeviceType.MOTOR_SENSOR), /** * A VEX Rotation Sensor. */ - ROTATION(V5_DeviceType.AbsEncSensor), + ROTATION(VexDeviceType.ABS_ENC_SENSOR), /** * A VEX Inertial Sensor. */ - IMU(V5_DeviceType.ImuSensor), + IMU(VexDeviceType.IMU_SENSOR), /** * A VEX Distance Sensor. */ - DISTANCE(V5_DeviceType.DistanceSensor), + DISTANCE(VexDeviceType.DISTANCE_SENSOR), /** * A VEX Vision Sensor. */ - VISION(V5_DeviceType.VisionSensor), + VISION(VexDeviceType.VISION_SENSOR), /** * A VEX AI Vision Sensor. */ - AI_VISION(V5_DeviceType.AiVisionSensor), + AI_VISION(VexDeviceType.AI_VISION_SENSOR), /** * A VEX Electromagnet. */ - ELECTROMAGNET(V5_DeviceType.MagnetSensor), + ELECTROMAGNET(VexDeviceType.MAGNET_SENSOR), /** * A VEX CTE Workcell Signal Tower. */ - LIGHT_TOWER(V5_DeviceType.LightTowerSensor), + LIGHT_TOWER(VexDeviceType.LIGHT_TOWER_SENSOR), /** * A VEX CTE Workcell 6-Axis Arm. */ - ARM(V5_DeviceType.ArmDevice), + ARM(VexDeviceType.ARM_DEVICE), /** * A VEX Optical Sensor. */ - OPTICAL(V5_DeviceType.OpticalSensor), + OPTICAL(VexDeviceType.OPTICAL_SENSOR), /** * A VEX V5 Game Positioning System Sensor. */ - GPS(V5_DeviceType.GpsSensor), + GPS(VexDeviceType.GPS_SENSOR), /** * A VEX V5 Robot Radio. */ - RADIO(V5_DeviceType.RadioSensor), + RADIO(VexDeviceType.RADIO_SENSOR), /** * A VEX Analog/Digital Input Sensor. */ - ADI(V5_DeviceType.AdiSensor), + ADI(VexDeviceType.ADI_SENSOR), /** * A generic, unbranded serial device. */ - GENERIC_SERIAL(V5_DeviceType.GenericSerial), + GENERIC_SERIAL(VexDeviceType.GENERIC_SERIAL), /** * An unknown device type. */ - UNKNOWN(V5_DeviceType.UndefinedSensor); + UNKNOWN(VexDeviceType.UNDEFINED_SENSOR); - private final V5_DeviceType raw; + private final VexDeviceType raw; - Type(V5_DeviceType raw) { + Type(VexDeviceType raw) { this.raw = raw; } @@ -161,23 +162,23 @@ public enum Type { * @param raw the raw device type * @return the high-level device type, or an empty optional if the raw type is not recognized */ - public static Optional fromRaw(@NotNull V5_DeviceType raw) { - return switch (raw.value()) { - case V5_DeviceType.kDeviceTypeNoSensor -> Optional.empty(); - case V5_DeviceType.kDeviceTypeMotorSensor -> Optional.of(MOTOR); - case V5_DeviceType.kDeviceTypeAbsEncSensor -> Optional.of(ROTATION); - case V5_DeviceType.kDeviceTypeImuSensor -> Optional.of(IMU); - case V5_DeviceType.kDeviceTypeDistanceSensor -> Optional.of(DISTANCE); - case V5_DeviceType.kDeviceTypeVisionSensor -> Optional.of(VISION); - case V5_DeviceType.kDeviceTypeAiVisionSensor -> Optional.of(AI_VISION); - case V5_DeviceType.kDeviceTypeMagnetSensor -> Optional.of(ELECTROMAGNET); - case V5_DeviceType.kDeviceTypeLightTowerSensor -> Optional.of(LIGHT_TOWER); - case V5_DeviceType.kDeviceTypeArmDevice -> Optional.of(ARM); - case V5_DeviceType.kDeviceTypeOpticalSensor -> Optional.of(OPTICAL); - case V5_DeviceType.kDeviceTypeGpsSensor -> Optional.of(GPS); - case V5_DeviceType.kDeviceTypeRadioSensor -> Optional.of(RADIO); - case V5_DeviceType.kDeviceTypeAdiSensor -> Optional.of(ADI); - case V5_DeviceType.kDeviceTypeGenericSerial -> Optional.of(GENERIC_SERIAL); + public static Optional fromRaw(@NotNull VexDeviceType raw) { + return switch (raw.getRawValue()) { + case VexDeviceType.kDeviceTypeNoSensor -> Optional.empty(); + case VexDeviceType.kDeviceTypeMotorSensor -> Optional.of(MOTOR); + case VexDeviceType.kDeviceTypeAbsEncSensor -> Optional.of(ROTATION); + case VexDeviceType.kDeviceTypeImuSensor -> Optional.of(IMU); + case VexDeviceType.kDeviceTypeDistanceSensor -> Optional.of(DISTANCE); + case VexDeviceType.kDeviceTypeVisionSensor -> Optional.of(VISION); + case VexDeviceType.kDeviceTypeAiVisionSensor -> Optional.of(AI_VISION); + case VexDeviceType.kDeviceTypeMagnetSensor -> Optional.of(ELECTROMAGNET); + case VexDeviceType.kDeviceTypeLightTowerSensor -> Optional.of(LIGHT_TOWER); + case VexDeviceType.kDeviceTypeArmDevice -> Optional.of(ARM); + case VexDeviceType.kDeviceTypeOpticalSensor -> Optional.of(OPTICAL); + case VexDeviceType.kDeviceTypeGpsSensor -> Optional.of(GPS); + case VexDeviceType.kDeviceTypeRadioSensor -> Optional.of(RADIO); + case VexDeviceType.kDeviceTypeAdiSensor -> Optional.of(ADI); + case VexDeviceType.kDeviceTypeGenericSerial -> Optional.of(GENERIC_SERIAL); default -> Optional.of(UNKNOWN); }; } @@ -187,7 +188,7 @@ public static Optional fromRaw(@NotNull V5_DeviceType raw) { * * @return the raw device type */ - public V5_DeviceType getRaw() { + public VexDeviceType getRaw() { return raw; } } diff --git a/src/main/java/dev/vexide/hydrozoa/devices/smart/SmartPort.java b/src/main/java/dev/vexide/hydrozoa/devices/smart/SmartPort.java index 3734f01..e3b8346 100644 --- a/src/main/java/dev/vexide/hydrozoa/devices/smart/SmartPort.java +++ b/src/main/java/dev/vexide/hydrozoa/devices/smart/SmartPort.java @@ -4,13 +4,14 @@ import dev.vexide.hydrozoa.Peripherals; import dev.vexide.hydrozoa.devices.DeviceDisconnectedException; import dev.vexide.hydrozoa.devices.IncorrectDeviceException; -import dev.vexide.hydrozoa.sdk.V5_Device; -import dev.vexide.hydrozoa.sdk.V5_DeviceType; +import dev.vexide.hydrozoa.sdk.VexDevice; +import dev.vexide.hydrozoa.sdk.VexDeviceType; import dev.vexide.hydrozoa.sdk.VexSdk; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.teavm.interop.Address; import java.util.Objects; import java.util.Optional; @@ -19,6 +20,8 @@ * A Smart Port on the VEX V5 Robot Brain. */ public final class SmartPort { + private static final int MAX_PORTS = 32; + private final int number; private @Nullable Peripherals.Key key; @@ -81,9 +84,9 @@ public int getIndex() { */ @Contract(" -> new") @NotNull - V5_Device deviceHandle() { + VexDevice deviceHandle() { validate(); - return VexSdk.Device.vexDeviceGetByIndex(getIndex()); + return new VexDevice(VexSdk.Device.getByIndex(getIndex())); } /** @@ -91,10 +94,9 @@ V5_Device deviceHandle() { * @return the device's type, if a device is connected */ public Optional deviceType() { - var deviceTypes = new byte[VexSdk.Device.V5_MAX_DEVICE_PORTS]; - VexSdk.Device.vexDeviceGetStatus(deviceTypes); - - return SmartDevice.Type.fromRaw(new V5_DeviceType(deviceTypes[getIndex()])); + var deviceTypes = new byte[MAX_PORTS]; + VexSdk.Device.getStatus(Address.ofData(deviceTypes)); + return SmartDevice.Type.fromRaw(new VexDeviceType(deviceTypes[getIndex()])); } /** diff --git a/src/main/java/dev/vexide/hydrozoa/display/Circle.java b/src/main/java/dev/vexide/hydrozoa/display/Circle.java index e8cde31..1a5a867 100644 --- a/src/main/java/dev/vexide/hydrozoa/display/Circle.java +++ b/src/main/java/dev/vexide/hydrozoa/display/Circle.java @@ -27,11 +27,11 @@ public record Circle(int x, int y, int radius) implements Shape { @Override public void draw(@NotNull Display display, @NotNull Color color, boolean fill) { - VexSdk.Display.vexDisplayForegroundColor(color.raw()); + VexSdk.Display.foregroundColor(color.raw()); if (fill) { - VexSdk.Display.vexDisplayCircleFill(x, y + Display.HEADER_HEIGHT, radius); + VexSdk.Display.fillCircle(x, y + Display.HEADER_HEIGHT, radius); } else { - VexSdk.Display.vexDisplayCircleDraw(x, y + Display.HEADER_HEIGHT, radius); + VexSdk.Display.drawCircle(x, y + Display.HEADER_HEIGHT, radius); } } } diff --git a/src/main/java/dev/vexide/hydrozoa/display/Display.java b/src/main/java/dev/vexide/hydrozoa/display/Display.java index 9d1ad24..18b2494 100644 --- a/src/main/java/dev/vexide/hydrozoa/display/Display.java +++ b/src/main/java/dev/vexide/hydrozoa/display/Display.java @@ -56,8 +56,8 @@ public Display(@NotNull Peripherals.Key ignoredKey) { */ public void setRenderMode(@NotNull RenderMode renderMode) { switch (renderMode) { - case IMMEDIATE -> VexSdk.Display.vexDisplayDoubleBufferDisable(); - case DOUBLE_BUFFERED -> VexSdk.Display.vexDisplayRender(false, false); + case IMMEDIATE -> VexSdk.Display.disableDoubleBuffer(); + case DOUBLE_BUFFERED -> VexSdk.Display.render(false, false); } this.renderMode = renderMode; } @@ -69,7 +69,7 @@ public void setRenderMode(@NotNull RenderMode renderMode) { */ public void render() { if (renderMode == RenderMode.DOUBLE_BUFFERED) { - VexSdk.Display.vexDisplayRender(false, false); + VexSdk.Display.render(false, false); } } diff --git a/src/main/java/dev/vexide/hydrozoa/display/Font.java b/src/main/java/dev/vexide/hydrozoa/display/Font.java index 805c0c8..7415261 100644 --- a/src/main/java/dev/vexide/hydrozoa/display/Font.java +++ b/src/main/java/dev/vexide/hydrozoa/display/Font.java @@ -18,8 +18,8 @@ public record Font(@NotNull Size size, @NotNull Family family) { public static final Font DEFAULT = new Font(Size.MEDIUM, Family.MONOSPACE); void apply() { - VexSdk.Display.vexDisplayFontNamedSet(family.fontName()); - VexSdk.Display.vexDisplayTextSize(size.numerator(), size.denominator()); + VexSdk.Display.setFontNamed(family.fontName()); + VexSdk.Display.textSize(size.numerator(), size.denominator()); } /** diff --git a/src/main/java/dev/vexide/hydrozoa/display/Rect.java b/src/main/java/dev/vexide/hydrozoa/display/Rect.java index ab2ce54..1d38f6d 100644 --- a/src/main/java/dev/vexide/hydrozoa/display/Rect.java +++ b/src/main/java/dev/vexide/hydrozoa/display/Rect.java @@ -43,11 +43,11 @@ public record Rect(int x1, int y1, int x2, int y2) implements Shape { @Override public void draw(@NotNull Display display, @NotNull Color color, boolean fill) { - VexSdk.Display.vexDisplayForegroundColor(color.raw()); + VexSdk.Display.foregroundColor(color.raw()); if (fill) { - VexSdk.Display.vexDisplayRectFill(x1, y1 + Display.HEADER_HEIGHT, x2, y2 + Display.HEADER_HEIGHT); + VexSdk.Display.fillRect(x1, y1 + Display.HEADER_HEIGHT, x2, y2 + Display.HEADER_HEIGHT); } else { - VexSdk.Display.vexDisplayRectDraw(x1, y1 + Display.HEADER_HEIGHT, x2, y2 + Display.HEADER_HEIGHT); + VexSdk.Display.drawRect(x1, y1 + Display.HEADER_HEIGHT, x2, y2 + Display.HEADER_HEIGHT); } } } diff --git a/src/main/java/dev/vexide/hydrozoa/display/Text.java b/src/main/java/dev/vexide/hydrozoa/display/Text.java index 3b4f835..c6a310d 100644 --- a/src/main/java/dev/vexide/hydrozoa/display/Text.java +++ b/src/main/java/dev/vexide/hydrozoa/display/Text.java @@ -71,7 +71,7 @@ public Text(@NotNull String text, int x, int y) { @Contract(pure = true) public int height() { font.apply(); - return VexSdk.Display.vexDisplayStringHeightGet(text); + return VexSdk.Display.getStringHeight(text); } /** @@ -81,7 +81,7 @@ public int height() { @Contract(pure = true) public int width() { font.apply(); - return VexSdk.Display.vexDisplayStringWidthGet(text); + return VexSdk.Display.getStringWidth(text); } /** @@ -92,9 +92,9 @@ public int width() { * @param bgColor the color to draw the text's background in, or {@code null} for transparency */ public void draw(@NotNull Display display, @NotNull Color fgColor, @Nullable Color bgColor) { - VexSdk.Display.vexDisplayForegroundColor(fgColor.raw()); + VexSdk.Display.foregroundColor(fgColor.raw()); if (bgColor != null) { - VexSdk.Display.vexDisplayBackgroundColor(bgColor.raw()); + VexSdk.Display.backgroundColor(bgColor.raw()); } var x = switch (hAlign) { @@ -110,7 +110,7 @@ public void draw(@NotNull Display display, @NotNull Color fgColor, @Nullable Col } + Display.HEADER_HEIGHT; font.apply(); - VexSdk.Display.vexDisplayPrintf(x, y, bgColor != null, text); + VexSdk.Display.printf(x, y, bgColor != null, text); } /** diff --git a/src/main/java/dev/vexide/hydrozoa/package-info.java b/src/main/java/dev/vexide/hydrozoa/package-info.java index cdae9fc..05530e7 100644 --- a/src/main/java/dev/vexide/hydrozoa/package-info.java +++ b/src/main/java/dev/vexide/hydrozoa/package-info.java @@ -1,4 +1,5 @@ /** + * The Hydrozoa Java SDK is a software library that allows Java and Kotlin programs to control VEX V5 robots. * The main package for the Hydrozoa project, which contains the basics for configuring and running a robot. */ package dev.vexide.hydrozoa; diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java deleted file mode 100644 index 29157cd..0000000 --- a/src/main/java/module-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/** - * The Hydrozoa Java SDK is a software library that allows Java and Kotlin programs to control VEX V5 robots. - */ -module dev.vexide.hydrozoa { - requires org.jetbrains.annotations; - requires dev.vexide.hydrozoa.sdk; - - exports dev.vexide.hydrozoa; - exports dev.vexide.hydrozoa.display; - exports dev.vexide.hydrozoa.devices.smart; - exports dev.vexide.hydrozoa.devices; -} diff --git a/vex-sdk/build.gradle.kts b/vex-sdk/build.gradle.kts index 1752bb9..0ecf502 100644 --- a/vex-sdk/build.gradle.kts +++ b/vex-sdk/build.gradle.kts @@ -2,9 +2,9 @@ plugins { `java-library` `maven-publish` id("org.teavm.library") + id("dev.vexide.hydrozoa.plugin.bindings") } - tasks.jar { manifest { attributes("Automatic-Module-Name" to "dev.vexide.hydrozoa.sdk") @@ -51,4 +51,27 @@ dependencies { tasks.javadoc { title = "VEX SDK" + options { + // Allow missing doc comments - most of the library is autogenerated + // and the source dataset current doesn't contain any SDK documentation info. + // There is no particular reason for this, it just hasn't been done yet. + with(this as CoreJavadocOptions) { + addBooleanOption("Xdoclint:html,syntax,accessibility,reference", true) + } + } +} + +tasks.generateBindings { + apiFile = rootProject.projectDir.resolve("hydrozoa_api.json") + outputDirectory = layout.buildDirectory.dir("generated/sources/bindings") +} + +tasks.assemble { + dependsOn(tasks.generateBindings) +} + +sourceSets.main { + java { + srcDir { tasks.generateBindings.get().outputDirectory } + } } diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorBrakeMode.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorBrakeMode.java deleted file mode 100644 index 501e078..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorBrakeMode.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -@SuppressWarnings("HungarianNotationConstants") -public record V5MotorBrakeMode(byte value) { - public static final byte kV5MotorBrakeModeCoast = 0; - public static final V5MotorBrakeMode Coast = new V5MotorBrakeMode(kV5MotorBrakeModeCoast); - - public static final byte kV5MotorBrakeModeBrake = 1; - public static final V5MotorBrakeMode Brake = new V5MotorBrakeMode(kV5MotorBrakeModeBrake); - - public static final byte kV5MotorBrakeModeHold = 2; - public static final V5MotorBrakeMode Hold = new V5MotorBrakeMode(kV5MotorBrakeModeHold); -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorControlMode.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorControlMode.java deleted file mode 100644 index 16f30cf..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorControlMode.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -@SuppressWarnings("HungarianNotationConstants") -public record V5MotorControlMode(byte value) { - public static final byte kMotorControlModeOFF = 0; - public static final V5MotorControlMode OFF = new V5MotorControlMode(kMotorControlModeOFF); - public static final byte kMotorControlModeBRAKE = 1; - public static final V5MotorControlMode BRAKE = new V5MotorControlMode(kMotorControlModeBRAKE); - public static final byte kMotorControlModeHOLD = 2; - public static final V5MotorControlMode HOLD = new V5MotorControlMode(kMotorControlModeHOLD); - public static final byte kMotorControlModeSERVO = 3; - public static final V5MotorControlMode SERVO = new V5MotorControlMode(kMotorControlModeSERVO); - public static final byte kMotorControlModePROFILE = 4; - public static final V5MotorControlMode PROFILE = new V5MotorControlMode(kMotorControlModePROFILE); - public static final byte kMotorControlModeVELOCITY = 5; - public static final V5MotorControlMode VELOCITY = new V5MotorControlMode(kMotorControlModeVELOCITY); - public static final byte kMotorControlModeUNDEFINED = 6; - public static final V5MotorControlMode UNDEFINED = new V5MotorControlMode(kMotorControlModeUNDEFINED); -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorEncoderUnits.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorEncoderUnits.java deleted file mode 100644 index c3c6f0f..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorEncoderUnits.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -@SuppressWarnings("HungarianNotationConstants") -public record V5MotorEncoderUnits(byte value) { - public static final byte kMotorEncoderDegrees = 0; - public static final V5MotorEncoderUnits Degrees = new V5MotorEncoderUnits(kMotorEncoderDegrees); - - public static final byte kMotorEncoderRotations = 1; - public static final V5MotorEncoderUnits Rotations = new V5MotorEncoderUnits(kMotorEncoderRotations); - - public static final byte kMotorEncoderCounts = 2; - public static final V5MotorEncoderUnits Counts = new V5MotorEncoderUnits(kMotorEncoderCounts); -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorGearset.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorGearset.java deleted file mode 100644 index 29005e2..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5MotorGearset.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -@SuppressWarnings("HungarianNotationConstants") -public record V5MotorGearset(byte value) { - public static final byte kMotorGearSet_36 = 0; - public static final byte kMotorGearSet_18 = 1; - public static final byte kMotorGearSet_06 = 2; - public static final V5MotorGearset GearSet_36 = new V5MotorGearset(kMotorGearSet_36); - public static final V5MotorGearset GearSet_18 = new V5MotorGearset(kMotorGearSet_18); - public static final V5MotorGearset GearSet_06 = new V5MotorGearset(kMotorGearSet_06); -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_ControllerId.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_ControllerId.java deleted file mode 100644 index c81ba8b..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_ControllerId.java +++ /dev/null @@ -1,7 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -@SuppressWarnings("HungarianNotationConstants") -public record V5_ControllerId(byte value) { - public static final V5_ControllerId kControllerMaster = new V5_ControllerId((byte) 0); - public static final V5_ControllerId kControllerPartner = new V5_ControllerId((byte) 1); -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_ControllerIndex.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_ControllerIndex.java deleted file mode 100644 index 018cbb6..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_ControllerIndex.java +++ /dev/null @@ -1,44 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -public record V5_ControllerIndex(byte value) { - public static final V5_ControllerIndex AnaLeftX = new V5_ControllerIndex((byte) 0); - public static final V5_ControllerIndex AnaLeftY = new V5_ControllerIndex((byte) 1); - public static final V5_ControllerIndex AnaRightX = new V5_ControllerIndex((byte) 2); - public static final V5_ControllerIndex AnaRightY = new V5_ControllerIndex((byte) 3); - public static final V5_ControllerIndex AnaSpare1 = new V5_ControllerIndex((byte) 4); - public static final V5_ControllerIndex AnaSpare2 = new V5_ControllerIndex((byte) 5); - public static final V5_ControllerIndex Button5U = new V5_ControllerIndex((byte) 6); - public static final V5_ControllerIndex Button5D = new V5_ControllerIndex((byte) 7); - public static final V5_ControllerIndex Button6U = new V5_ControllerIndex((byte) 8); - public static final V5_ControllerIndex Button6D = new V5_ControllerIndex((byte) 9); - public static final V5_ControllerIndex Button7U = new V5_ControllerIndex((byte) 10); - public static final V5_ControllerIndex Button7D = new V5_ControllerIndex((byte) 11); - public static final V5_ControllerIndex Button7L = new V5_ControllerIndex((byte) 12); - public static final V5_ControllerIndex Button7R = new V5_ControllerIndex((byte) 13); - public static final V5_ControllerIndex Button8U = new V5_ControllerIndex((byte) 14); - public static final V5_ControllerIndex Button8D = new V5_ControllerIndex((byte) 15); - public static final V5_ControllerIndex Button8L = new V5_ControllerIndex((byte) 16); - public static final V5_ControllerIndex Button8R = new V5_ControllerIndex((byte) 17); - public static final V5_ControllerIndex ButtonSEL = new V5_ControllerIndex((byte) 18); - public static final V5_ControllerIndex BatteryLevel = new V5_ControllerIndex((byte) 19); - public static final V5_ControllerIndex ButtonAll = new V5_ControllerIndex((byte) 20); - public static final V5_ControllerIndex Flags = new V5_ControllerIndex((byte) 21); - public static final V5_ControllerIndex BatteryCapacity = new V5_ControllerIndex((byte) 22); - - public static final V5_ControllerIndex Axis1 = AnaRightX; - public static final V5_ControllerIndex Axis2 = AnaRightY; - public static final V5_ControllerIndex Axis3 = AnaLeftY; - public static final V5_ControllerIndex Axis4 = AnaLeftX; - public static final V5_ControllerIndex ButtonL1 = Button5U; - public static final V5_ControllerIndex ButtonL2 = Button5D; - public static final V5_ControllerIndex ButtonR1 = Button6U; - public static final V5_ControllerIndex ButtonR2 = Button6D; - public static final V5_ControllerIndex ButtonUp = Button7U; - public static final V5_ControllerIndex ButtonDown = Button7D; - public static final V5_ControllerIndex ButtonLeft = Button7L; - public static final V5_ControllerIndex ButtonRight = Button7R; - public static final V5_ControllerIndex ButtonX = Button8U; - public static final V5_ControllerIndex ButtonB = Button8D; - public static final V5_ControllerIndex ButtonY = Button8L; - public static final V5_ControllerIndex ButtonA = Button8R; -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_ControllerStatus.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_ControllerStatus.java deleted file mode 100644 index 5451945..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_ControllerStatus.java +++ /dev/null @@ -1,8 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -@SuppressWarnings("HungarianNotationConstants") -public record V5_ControllerStatus(byte value) { - public static final V5_ControllerStatus kV5ControllerOffline = new V5_ControllerStatus((byte) 0); - public static final V5_ControllerStatus kV5ControllerTethered = new V5_ControllerStatus((byte) 1); - public static final V5_ControllerStatus kV5ControllerVexnet = new V5_ControllerStatus((byte) 2); -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_Device.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_Device.java deleted file mode 100644 index 07be41d..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_Device.java +++ /dev/null @@ -1,4 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -public record V5_Device(int raw) { -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_DeviceType.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_DeviceType.java deleted file mode 100644 index 5660276..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/V5_DeviceType.java +++ /dev/null @@ -1,92 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -@SuppressWarnings("HungarianNotationConstants") -public record V5_DeviceType(byte value) { - public static final byte kDeviceTypeNoSensor = 0; - public static final V5_DeviceType NoSensor = new V5_DeviceType(kDeviceTypeNoSensor); - - public static final byte kDeviceTypeMotorSensor = 2; - public static final V5_DeviceType MotorSensor = new V5_DeviceType(kDeviceTypeMotorSensor); - - public static final byte kDeviceTypeLedSensor = 3; - public static final V5_DeviceType LedSensor = new V5_DeviceType(kDeviceTypeLedSensor); - - public static final byte kDeviceTypeAbsEncSensor = 4; - public static final V5_DeviceType AbsEncSensor = new V5_DeviceType(kDeviceTypeAbsEncSensor); - - public static final byte kDeviceTypeCrMotorSensor = 5; - public static final V5_DeviceType CrMotorSensor = new V5_DeviceType(kDeviceTypeCrMotorSensor); - - public static final byte kDeviceTypeImuSensor = 6; - public static final V5_DeviceType ImuSensor = new V5_DeviceType(kDeviceTypeImuSensor); - - public static final byte kDeviceTypeDistanceSensor = 7; - public static final V5_DeviceType DistanceSensor = new V5_DeviceType(kDeviceTypeDistanceSensor); - - public static final byte kDeviceTypeRadioSensor = 8; - public static final V5_DeviceType RadioSensor = new V5_DeviceType(kDeviceTypeRadioSensor); - - public static final byte kDeviceTypeTetherSensor = 9; - public static final V5_DeviceType TetherSensor = new V5_DeviceType(kDeviceTypeTetherSensor); - - public static final byte kDeviceTypeBrainSensor = 10; - public static final V5_DeviceType BrainSensor = new V5_DeviceType(kDeviceTypeBrainSensor); - - public static final byte kDeviceTypeVisionSensor = 11; - public static final V5_DeviceType VisionSensor = new V5_DeviceType(kDeviceTypeVisionSensor); - - public static final byte kDeviceTypeAdiSensor = 12; - public static final V5_DeviceType AdiSensor = new V5_DeviceType(kDeviceTypeAdiSensor); - - public static final byte kDeviceTypeRes1Sensor = 13; - public static final V5_DeviceType Res1Sensor = new V5_DeviceType(kDeviceTypeRes1Sensor); - - public static final byte kDeviceTypeRes2Sensor = 14; - public static final V5_DeviceType Res2Sensor = new V5_DeviceType(kDeviceTypeRes2Sensor); - - public static final byte kDeviceTypeRes3Sensor = 15; - public static final V5_DeviceType Res3Sensor = new V5_DeviceType(kDeviceTypeRes3Sensor); - - public static final byte kDeviceTypeOpticalSensor = 16; - public static final V5_DeviceType OpticalSensor = new V5_DeviceType(kDeviceTypeOpticalSensor); - - public static final byte kDeviceTypeMagnetSensor = 17; - public static final V5_DeviceType MagnetSensor = new V5_DeviceType(kDeviceTypeMagnetSensor); - - public static final byte kDeviceTypeGpsSensor = 20; - public static final V5_DeviceType GpsSensor = new V5_DeviceType(kDeviceTypeGpsSensor); - - public static final byte kDeviceTypeAicameraSensor = 26; - public static final V5_DeviceType AicameraSensor = new V5_DeviceType(kDeviceTypeAicameraSensor); - - public static final byte kDeviceTypeLightTowerSensor = 27; - public static final V5_DeviceType LightTowerSensor = new V5_DeviceType(kDeviceTypeLightTowerSensor); - - public static final byte kDeviceTypeArmDevice = 28; - public static final V5_DeviceType ArmDevice = new V5_DeviceType(kDeviceTypeArmDevice); - - public static final byte kDeviceTypeAiVisionSensor = 29; - public static final V5_DeviceType AiVisionSensor = new V5_DeviceType(kDeviceTypeAiVisionSensor); - - public static final byte kDeviceTypePneumaticSensor = 30; - public static final V5_DeviceType PneumaticSensor = new V5_DeviceType(kDeviceTypePneumaticSensor); - - public static final byte kDeviceTypeBumperSensor = 0x40; - public static final V5_DeviceType BumperSensor = new V5_DeviceType(kDeviceTypeBumperSensor); - - public static final byte kDeviceTypeGyroSensor = 0x46; - public static final V5_DeviceType GyroSensor = new V5_DeviceType(kDeviceTypeGyroSensor); - - public static final byte kDeviceTypeSonarSensor = 0x47; - public static final V5_DeviceType SonarSensor = new V5_DeviceType(kDeviceTypeSonarSensor); - - public static final byte kDeviceTypeGenericSensor = (byte) 128; - public static final V5_DeviceType GenericSensor = new V5_DeviceType(kDeviceTypeGenericSensor); - - public static final byte kDeviceTypeGenericSerial = (byte) 129; - public static final V5_DeviceType GenericSerial = new V5_DeviceType(kDeviceTypeGenericSerial); - - public static final byte kDeviceTypeUndefinedSensor = (byte) 255; - public static final V5_DeviceType UndefinedSensor = new V5_DeviceType(kDeviceTypeUndefinedSensor); - -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/VexSdk.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/VexSdk.java deleted file mode 100644 index 5725e8f..0000000 --- a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/VexSdk.java +++ /dev/null @@ -1,443 +0,0 @@ -package dev.vexide.hydrozoa.sdk; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.teavm.interop.Import; -import org.teavm.interop.StaticInit; - -@SuppressWarnings("MissingJavadoc") -@StaticInit -public final class VexSdk { - private VexSdk() { - } - - @Import(module = "vex", name = "vexTasksRun") - public static native void vexTasksRun(); - - @Import(module = "vex", name = "vexCompetitionStatus") - public static native int vexCompetitionStatus(); - - @StaticInit - public static final class Display { - private Display() { - } - - @Import(module = "vex", name = "vexDisplayRender") - public static native void vexDisplayRender(boolean bVsyncWait, boolean bRunScheduler); - - @Import(module = "vex", name = "vexDisplayDoubleBufferDisable") - public static native void vexDisplayDoubleBufferDisable(); - - @Import(module = "vex", name = "vexDisplayForegroundColor") - public static native void vexDisplayForegroundColor(int color); - - @Import(module = "vex", name = "vexDisplayBackgroundColor") - public static native void vexDisplayBackgroundColor(int color); - - @Import(module = "vex", name = "vexDisplayRectFill") - public static native void vexDisplayRectFill(int x1, int y1, int x2, int y2); - - @Import(module = "vex", name = "vexDisplayRectDraw") - public static native void vexDisplayRectDraw(int x1, int y1, int x2, int y2); - - @Import(module = "vex", name = "vexDisplayCircleFill") - public static native void vexDisplayCircleFill(int xc, int yc, int radius); - - @Import(module = "vex", name = "vexDisplayCircleDraw") - public static native void vexDisplayCircleDraw(int xc, int yc, int radius); - - // Text functions - - @Import(module = "vex", name = "vexDisplayTextSize") - public static native void vexDisplayTextSize(int n, int d); - - @Import(module = "vex", name = "vexDisplayFontNamedSet") - public static native void vexDisplayFontNamedSet(@NotNull String pFontName); - - @Import(module = "vex", name = "vexDisplayStringWidthGet") - public static native int vexDisplayStringWidthGet(@NotNull String text); - - @Import(module = "vex", name = "vexDisplayStringHeightGet") - public static native int vexDisplayStringHeightGet(@NotNull String text); - - @Import(module = "vex", name = "vexDisplayPrintf") - public static native void vexDisplayPrintf(int xpos, int ypos, boolean bOpaque, @NotNull String text); - - @Import(module = "vex", name = "vexDisplayString") - public static native void vexDisplayString(int nLineNumber, @NotNull String text); - - @Import(module = "vex", name = "vexDisplayStringAt") - public static native void vexDisplayStringAt(int xpos, int ypos, @NotNull String text); - - @Import(module = "vex", name = "vexDisplayBigString") - public static native void vexDisplayBigString(int nLineNumber, @NotNull String text); - - @Import(module = "vex", name = "vexDisplayBigStringAt") - public static native void vexDisplayBigStringAt(int xpos, int ypos, @NotNull String text); - - @Import(module = "vex", name = "vexDisplaySmallStringAt") - public static native void vexDisplaySmallStringAt(int xpos, int ypos, @NotNull String text); - - @Import(module = "vex", name = "vexDisplayCenteredString") - public static native void vexDisplayCenteredString(int nLineNumber, @NotNull String text); - - @Import(module = "vex", name = "vexDisplayBigCenteredString") - public static native void vexDisplayBigCenteredString(int nLineNumber, @NotNull String text); - } - - @StaticInit - public static final class Controller { - private Controller() { - } - - /** - * Get the value of a controller's data channel. - */ - public static int vexControllerGet(@NotNull V5_ControllerId id, @NotNull V5_ControllerIndex index) { - return vexControllerGetRaw(id.value(), index.value()); - } - - @Import(module = "vex", name = "vexControllerGet") - private static native int vexControllerGetRaw(byte id, byte index); - - /** - * Returns `1` if the controller on the given ID is connected, or `0` if not. - */ - public static @NotNull V5_ControllerStatus vexControllerConnectionStatusGet(@NotNull V5_ControllerId id) { - return new V5_ControllerStatus(vexControllerConnectionStatusGetRaw(id.value())); - } - - @Import(module = "vex", name = "vexControllerConnectionStatusGet") - private static native byte vexControllerConnectionStatusGetRaw(byte id); - } - - @StaticInit - public static final class Device { - private Device() { - } - - public static final int V5_MAX_DEVICE_PORTS = 32; - - @Import(module = "vex", name = "vexControllerConnectionStatusGet") - public static native int vexDevicesGetNumber(); - - public static int vexDevicesGetNumberByType(@NotNull V5_DeviceType deviceType) { - return vexDevicesGetNumberByTypeRaw(deviceType.value()); - } - - @Import(module = "vex", name = "vexDevicesGetNumberByType") - private static native int vexDevicesGetNumberByTypeRaw(int deviceType); - - @Import(module = "vex", name = "vexDeviceGetStatus") - public static native int vexDeviceGetStatus(byte[] devices); - - @Contract("_ -> new") - public static @NotNull V5_Device vexDeviceGetByIndex(int index) { - return new V5_Device(vexDeviceGetByIndexRaw(index)); - } - - @Import(module = "vex", name = "vexDeviceGetByIndex") - private static native int vexDeviceGetByIndexRaw(int index); - } - - @StaticInit - public static final class Motor { - private Motor() { - } - - public static void vexDeviceMotorVelocitySet(@NotNull V5_Device device, int velocity) { - vexDeviceMotorVelocitySetRaw(device.raw(), velocity); - } - - @Import(module = "vex", name = "vexDeviceMotorVelocitySet") - private static native void vexDeviceMotorVelocitySetRaw(int device, int velocity); - - public static int vexDeviceMotorVelocityGet(@NotNull V5_Device device) { - return vexDeviceMotorVelocityGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorVelocityGet") - private static native int vexDeviceMotorVelocityGetRaw(int device); - - public static int vexDeviceMotorActualVelocityGet(@NotNull V5_Device device) { - return vexDeviceMotorActualVelocityGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorActualVelocityGet") - private static native int vexDeviceMotorActualVelocityGetRaw(int device); - - public static int vexDeviceMotorDirectionGet(@NotNull V5_Device device) { - return vexDeviceMotorDirectionGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorDirectionGet") - private static native int vexDeviceMotorDirectionGetRaw(int device); - - public static void vexDeviceMotorBrakeModeSet(@NotNull V5_Device device, @NotNull V5MotorBrakeMode mode) { - vexDeviceMotorBrakeModeSetRaw(device.raw(), mode.value()); - } - @Import(module = "vex", name = "vexDeviceMotorBrakeModeSet") - private static native void vexDeviceMotorBrakeModeSetRaw(int device, byte mode); - - public static void vexDeviceMotorModeSet(@NotNull V5_Device device, @NotNull V5MotorControlMode mode) { - vexDeviceMotorModeSetRaw(device.raw(), mode.value()); - } - - @Import(module = "vex", name = "vexDeviceMotorModeSet") - private static native void vexDeviceMotorModeSetRaw(int device, byte mode); - - public static @NotNull V5MotorControlMode vexDeviceMotorModeGet(@NotNull V5_Device device) { - return new V5MotorControlMode(vexDeviceMotorModeGetRaw(device.raw())); - } - - @Import(module = "vex", name = "vexDeviceMotorModeGet") - private static native byte vexDeviceMotorModeGetRaw(int device); - - public static void vexDeviceMotorPwmSet(@NotNull V5_Device device, int pwm) { - vexDeviceMotorPwmSetRaw(device.raw(), pwm); - } - - @Import(module = "vex", name = "vexDeviceMotorPwmSet") - private static native void vexDeviceMotorPwmSetRaw(int device, int pwm); - - public static int vexDeviceMotorPwmGet(@NotNull V5_Device device) { - return vexDeviceMotorPwmGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorPwmGet") - private static native int vexDeviceMotorPwmGetRaw(int device); - - public static void vexDeviceMotorCurrentLimitSet(@NotNull V5_Device device, int limit) { - vexDeviceMotorCurrentLimitSetRaw(device.raw(), limit); - } - - @Import(module = "vex", name = "vexDeviceMotorCurrentLimitSet") - private static native void vexDeviceMotorCurrentLimitSetRaw(int device, int limit); - - public static int vexDeviceMotorCurrentLimitGet(@NotNull V5_Device device) { - return vexDeviceMotorCurrentLimitGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorCurrentLimitGet") - private static native int vexDeviceMotorCurrentLimitGetRaw(int device); - - public static int vexDeviceMotorCurrentGet(@NotNull V5_Device device) { - return vexDeviceMotorCurrentGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorCurrentGet") - private static native int vexDeviceMotorCurrentGetRaw(int device); - - public static double vexDeviceMotorPowerGet(@NotNull V5_Device device) { - return vexDeviceMotorPowerGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorPowerGet") - private static native double vexDeviceMotorPowerGetRaw(int device); - - public static double vexDeviceMotorTorqueGet(@NotNull V5_Device device) { - return vexDeviceMotorTorqueGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorTorqueGet") - private static native double vexDeviceMotorTorqueGetRaw(int device); - - public static double vexDeviceMotorEfficiencyGet(@NotNull V5_Device device) { - return vexDeviceMotorEfficiencyGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorEfficiencyGet") - private static native double vexDeviceMotorEfficiencyGetRaw(int device); - - public static double vexDeviceMotorTemperatureGet(@NotNull V5_Device device) { - return vexDeviceMotorTemperatureGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorTemperatureGet") - private static native double vexDeviceMotorTemperatureGetRaw(int device); - - public static boolean vexDeviceMotorOverTempFlagGet(@NotNull V5_Device device) { - return vexDeviceMotorOverTempFlagGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorOverTempFlagGet") - private static native boolean vexDeviceMotorOverTempFlagGetRaw(int device); - - public static boolean vexDeviceMotorCurrentLimitFlagGet(@NotNull V5_Device device) { - return vexDeviceMotorCurrentLimitFlagGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorCurrentLimitFlagGet") - private static native boolean vexDeviceMotorCurrentLimitFlagGetRaw(int device); - - public static boolean vexDeviceMotorZeroVelocityFlagGet(@NotNull V5_Device device) { - return vexDeviceMotorZeroVelocityFlagGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorZeroVelocityFlagGet") - private static native boolean vexDeviceMotorZeroVelocityFlagGetRaw(int device); - - public static boolean vexDeviceMotorZeroPositionFlagGet(@NotNull V5_Device device) { - return vexDeviceMotorZeroPositionFlagGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorZeroPositionFlagGet") - private static native boolean vexDeviceMotorZeroPositionFlagGetRaw(int device); - - public static void vexDeviceMotorGearingSet(@NotNull V5_Device device, @NotNull V5MotorGearset gearset) { - vexDeviceMotorGearingSetRaw(device.raw(), gearset.value()); - } - - @Import(module = "vex", name = "vexDeviceMotorGearingSet") - private static native void vexDeviceMotorGearingSetRaw(int device, byte gearset); - - public static void vexDeviceMotorAbsoluteTargetSet(@NotNull V5_Device device, double position, int velocity) { - vexDeviceMotorAbsoluteTargetSetRaw(device.raw(), position, velocity); - } - @Import(module = "vex", name = "vexDeviceMotorAbsoluteTargetSet") - private static native void vexDeviceMotorAbsoluteTargetSetRaw(int device, double position, int velocity); - - public static void vexDeviceMotorReverseFlagSet(@NotNull V5_Device device, boolean flag) { - vexDeviceMotorReverseFlagSetRaw(device.raw(), flag); - } - - @Import(module = "vex", name = "vexDeviceMotorReverseFlagSet") - private static native void vexDeviceMotorReverseFlagSetRaw(int device, boolean flag); - - public static void vexDeviceMotorEncoderUnitsSet(@NotNull V5_Device device, @NotNull V5MotorEncoderUnits units) { - vexDeviceMotorEncoderUnitsSetRaw(device.raw(), units.value()); - } - @Import(module = "vex", name = "vexDeviceMotorEncoderUnitsSet") - private static native void vexDeviceMotorEncoderUnitsSetRaw(int device, byte units); - - public static void vexDeviceMotorVoltageSet(@NotNull V5_Device device, int voltage) { - vexDeviceMotorVoltageSetRaw(device.raw(), voltage); - } - - @Import(module = "vex", name = "vexDeviceMotorVoltageSet") - private static native void vexDeviceMotorVoltageSetRaw(int device, int voltage); - - public static void vexDeviceMotorVoltageGet(@NotNull V5_Device device, int voltage) { - vexDeviceMotorVoltageGetRaw(device.raw(), voltage); - } - - @Import(module = "vex", name = "vexDeviceMotorVoltageGet") - private static native void vexDeviceMotorVoltageGetRaw(int device, int voltage); - // TODO: - // vexDeviceMotorPositionGet(device: V5_DeviceT) -> c_double, - // vexDeviceMotorPositionRawGet( - // device: V5_DeviceT, - // timestamp: *mut u32, - // ) -> i32, - // vexDeviceMotorPositionReset(device: V5_DeviceT), - // vexDeviceMotorTargetGet(device: V5_DeviceT) -> c_double, - // vexDeviceMotorServoTargetSet(device: V5_DeviceT, position: c_double), - // vexDeviceMotorAbsoluteTargetSet( - // device: V5_DeviceT, - // position: c_double, - // veloctiy: i32, - // ), - // vexDeviceMotorRelativeTargetSet( - // device: V5_DeviceT, - // position: c_double, - // velocity: i32, - // ), - // vexDeviceMotorFaultsGet(device: V5_DeviceT) -> u32, - // vexDeviceMotorFlagsGet(device: V5_DeviceT) -> u32, - // vexDeviceMotorVoltageSet(device: V5_DeviceT, voltage: i32), - // vexDeviceMotorVoltageGet(device: V5_DeviceT) -> i32, - // vexDeviceMotorGearingSet(device: V5_DeviceT, gearset: V5MotorGearset), - // vexDeviceMotorGearingGet(device: V5_DeviceT) -> V5MotorGearset, - // vexDeviceMotorVoltageLimitSet(device: V5_DeviceT, limit: i32), - // vexDeviceMotorVoltageLimitGet(device: V5_DeviceT) -> i32, - // vexDeviceMotorVelocityUpdate(device: V5_DeviceT, velocity: i32), - // vexDeviceMotorPositionPidSet(device: V5_DeviceT, pid: *mut V5_DeviceMotorPid), - // vexDeviceMotorVelocityPidSet(device: V5_DeviceT, pid: *mut V5_DeviceMotorPid), - // vexDeviceMotorExternalProfileSet( - // device: V5_DeviceT, - // position: c_double, - // velocity: i32, - // ), - - - public static boolean vexDeviceMotorReverseFlagGet(@NotNull V5_Device device) { - return vexDeviceMotorReverseFlagGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorReverseFlagGet") - private static native boolean vexDeviceMotorReverseFlagGetRaw(int device); - - public static @NotNull V5MotorEncoderUnits vexDeviceMotorEncoderUnitsGet(@NotNull V5_Device device) { - return new V5MotorEncoderUnits(vexDeviceMotorEncoderUnitsGetRaw(device.raw())); - } - - @Import(module = "vex", name = "vexDeviceMotorEncoderUnitsGet") - private static native byte vexDeviceMotorEncoderUnitsGetRaw(int device); - - public static @NotNull V5MotorBrakeMode vexDeviceMotorBrakeModeGet(@NotNull V5_Device device) { - return new V5MotorBrakeMode(vexDeviceMotorBrakeModeGetRaw(device.raw())); - } - - @Import(module = "vex", name = "vexDeviceMotorBrakeModeGet") - private static native byte vexDeviceMotorBrakeModeGetRaw(int device); - - public static void vexDeviceMotorPositionSet(@NotNull V5_Device device, double position) { - vexDeviceMotorPositionSetRaw(device.raw(), position); - } - - @Import(module = "vex", name = "vexDeviceMotorPositionSet") - private static native void vexDeviceMotorPositionSetRaw(int device, double position); - - public static double vexDeviceMotorPositionGet(@NotNull V5_Device device) { - return vexDeviceMotorPositionGetRaw(device.raw()); - } - - @Import(module = "vex", name = "vexDeviceMotorPositionGet") - private static native double vexDeviceMotorPositionGetRaw(int device); - } - - @StaticInit - public static final class Serial { - private Serial() { - } - - @Import(module = "vex", name = "vexSerialWriteChar") - public static native int vexSerialWriteChar(int channel, byte c); - - @Import(module = "vex", name = "vexSerialReadChar") - public static native int vexSerialReadChar(int channel); - - @Import(module = "vex", name = "vexSerialPeekChar") - public static native int vexSerialPeekChar(int channel); - - @Import(module = "vex", name = "vexSerialWriteFree") - public static native int vexSerialWriteFree(int channel); - } - - @StaticInit - public static final class System { - private System() { - } - - @Import(module = "vex", name = "vexSystemTimeGet") - public static native int vexSystemTimeGet(); - - @Import(module = "vex", name = "vexSystemExitRequest") - public static native void vexSystemExitRequest(); - - @Import(module = "vex", name = "vexSystemHighResTimeGet") - public static native long vexSystemHighResTimeGet(); - - @Import(module = "vex", name = "vexSystemPowerupTimeGet") - public static native long vexSystemPowerupTimeGet(); - - @Import(module = "vex", name = "vexSystemLinkAddrGet") - public static native int vexSystemLinkAddrGet(); - - @Import(module = "vex", name = "vexSystemVersion") - public static native int vexSystemVersion(); - - @Import(module = "vex", name = "vexStdlibVersion") - public static native int vexStdlibVersion(); - } -} diff --git a/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/package-info.java b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/package-info.java new file mode 100644 index 0000000..482f77a --- /dev/null +++ b/vex-sdk/src/main/java/dev/vexide/hydrozoa/sdk/package-info.java @@ -0,0 +1,2 @@ +/// Raw bindings to VEX V5 system calls. +package dev.vexide.hydrozoa.sdk;