From 4b2dbc7a9c720e3d86446db380e46523e9f63935 Mon Sep 17 00:00:00 2001 From: blaze-developer Date: Thu, 8 Jan 2026 11:37:19 -0800 Subject: [PATCH 1/3] Add NormalizedRGBA Logging --- .../java/com/blazedeveloper/chrono/Logger.kt | 2 ++ .../chrono/structure/LogTable.kt | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/chrono/src/main/java/com/blazedeveloper/chrono/Logger.kt b/chrono/src/main/java/com/blazedeveloper/chrono/Logger.kt index f89cc32..092c4ef 100644 --- a/chrono/src/main/java/com/blazedeveloper/chrono/Logger.kt +++ b/chrono/src/main/java/com/blazedeveloper/chrono/Logger.kt @@ -5,6 +5,7 @@ import com.blazedeveloper.chrono.dataflow.ReplaySource import com.blazedeveloper.chrono.output.ConsoleLogger import com.blazedeveloper.chrono.structure.LogTable import com.blazedeveloper.chrono.structure.LoggableInputs +import com.qualcomm.robotcore.hardware.NormalizedRGBA import kotlin.system.exitProcess import kotlin.time.Duration import kotlin.time.Duration.Companion.nanoseconds @@ -140,6 +141,7 @@ object Logger { @JvmStatic fun output(key: String, value: DoubleArray) = ifRunning { outputsTable.put(key, value) } @JvmStatic fun > output(key: String, value: E) = ifRunning { outputsTable.put(key, value) } @JvmStatic fun > output(key: String, value: Array) = ifRunning { outputsTable.put(key, value) } + @JvmStatic fun output(key: String, value: NormalizedRGBA) = ifRunning { outputsTable.put(key, value) } /** Sends data to receivers. Runs after user code. **/ internal fun postUser() = ifRunning { diff --git a/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt b/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt index 059c4bc..bdf14b2 100644 --- a/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt +++ b/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt @@ -1,6 +1,8 @@ package com.blazedeveloper.chrono.structure +import android.graphics.Color import com.blazedeveloper.chrono.structure.LogValue.Companion.asLogValue +import com.qualcomm.robotcore.hardware.NormalizedRGBA import kotlin.time.Duration class LogTable @JvmOverloads constructor( @@ -89,6 +91,9 @@ class LogTable @JvmOverloads constructor( /** Puts an enum array [value] represented by a string into the table at a specified [key] */ fun > put(key: String, value: Array) = put(key, value.map { it.name }.toTypedArray()) + /** Puts a NormalizedRGBA color represented by a hex string into the table at a specified key */ + fun put(key: String, value: NormalizedRGBA) = put(key, "#%x".format(value.toColor())) + /** * Gets a raw LogValue from the table at the specified [key]. * If the data does not exist or is of the wrong type, @@ -218,4 +223,18 @@ class LogTable @JvmOverloads constructor( */ inline fun > get(key: String, default: Array) = get(key, default.map { it.name }.toTypedArray()).map { enumValueOf(it) }.toTypedArray() + + /** + * Gets a color object from the table at the specified [key], + * If the data does not exist or is of the wrong type, + * the [default] is returned. + */ + fun get(key: String, default: NormalizedRGBA): NormalizedRGBA = + NormalizedRGBA().apply { + val color = Color.valueOf(Color.parseColor(get(key, "#%x".format(default.toColor())))) + alpha = color.alpha() + red = color.red() + green = color.green() + blue = color.blue() + } } \ No newline at end of file From 3aa32d20fba33baf84d2c8107ea4274824a44c17 Mon Sep 17 00:00:00 2001 From: blaze-developer Date: Thu, 8 Jan 2026 11:56:29 -0800 Subject: [PATCH 2/3] Color --- .../chrono/structure/LogTable.kt | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt b/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt index bdf14b2..4236136 100644 --- a/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt +++ b/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt @@ -3,6 +3,7 @@ package com.blazedeveloper.chrono.structure import android.graphics.Color import com.blazedeveloper.chrono.structure.LogValue.Companion.asLogValue import com.qualcomm.robotcore.hardware.NormalizedRGBA +import kotlin.math.roundToInt import kotlin.time.Duration class LogTable @JvmOverloads constructor( @@ -91,8 +92,8 @@ class LogTable @JvmOverloads constructor( /** Puts an enum array [value] represented by a string into the table at a specified [key] */ fun > put(key: String, value: Array) = put(key, value.map { it.name }.toTypedArray()) - /** Puts a NormalizedRGBA color represented by a hex string into the table at a specified key */ - fun put(key: String, value: NormalizedRGBA) = put(key, "#%x".format(value.toColor())) + /** Puts a NormalizedRGBA color represented by a hex triplet (WITHOUT ALPHA) into the table at a specified key */ + fun put(key: String, value: NormalizedRGBA) = put(key, value.toHexTriplet()) /** * Gets a raw LogValue from the table at the specified [key]. @@ -231,10 +232,18 @@ class LogTable @JvmOverloads constructor( */ fun get(key: String, default: NormalizedRGBA): NormalizedRGBA = NormalizedRGBA().apply { - val color = Color.valueOf(Color.parseColor(get(key, "#%x".format(default.toColor())))) - alpha = color.alpha() - red = color.red() - green = color.green() - blue = color.blue() + val color = Color.parseColor(get(key, default.toHexTriplet())) + alpha = 1f + red = Color.red(color) / 255f + green = Color.green(color) / 255f + blue = Color.blue(color) / 255f } + + fun NormalizedRGBA.toHexTriplet(): String { + val r = (red * 255f).roundToInt().coerceIn(0, 255) + val g = (green * 255f).roundToInt().coerceIn(0, 255) + val b = (blue * 255f).roundToInt().coerceIn(0, 255) + + return "#%02X%02X%02X".format(r, g, b) + } } \ No newline at end of file From 15f0443d6274bafeb36bf3570a519a74a07f69e5 Mon Sep 17 00:00:00 2001 From: blaze-developer Date: Thu, 8 Jan 2026 12:28:49 -0800 Subject: [PATCH 3/3] Use float array format for lossless table conversions --- .../chrono/structure/LogTable.kt | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt b/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt index 4236136..af89d63 100644 --- a/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt +++ b/chrono/src/main/java/com/blazedeveloper/chrono/structure/LogTable.kt @@ -1,9 +1,8 @@ package com.blazedeveloper.chrono.structure -import android.graphics.Color import com.blazedeveloper.chrono.structure.LogValue.Companion.asLogValue import com.qualcomm.robotcore.hardware.NormalizedRGBA -import kotlin.math.roundToInt +import kotlin.math.abs import kotlin.time.Duration class LogTable @JvmOverloads constructor( @@ -90,10 +89,12 @@ class LogTable @JvmOverloads constructor( fun > put(key: String, value: E) = put(key, value.name) /** Puts an enum array [value] represented by a string into the table at a specified [key] */ - fun > put(key: String, value: Array) = put(key, value.map { it.name }.toTypedArray()) + fun > put(key: String, value: Array) = + put(key, value.map { it.name }.toTypedArray()) - /** Puts a NormalizedRGBA color represented by a hex triplet (WITHOUT ALPHA) into the table at a specified key */ - fun put(key: String, value: NormalizedRGBA) = put(key, value.toHexTriplet()) + /** Puts a normalized color represented by a float array (ARGB order) into the table at a specified key */ + fun put(key: String, value: NormalizedRGBA) = + put(key, floatArrayOf(value.alpha, value.red, value.green, value.blue)) /** * Gets a raw LogValue from the table at the specified [key]. @@ -222,7 +223,7 @@ class LogTable @JvmOverloads constructor( * If the data does not exist or is of the wrong type, * the [default] is returned. */ - inline fun > get(key: String, default: Array) = + inline fun > get(key: String, default: Array) = get(key, default.map { it.name }.toTypedArray()).map { enumValueOf(it) }.toTypedArray() /** @@ -230,20 +231,13 @@ class LogTable @JvmOverloads constructor( * If the data does not exist or is of the wrong type, * the [default] is returned. */ - fun get(key: String, default: NormalizedRGBA): NormalizedRGBA = - NormalizedRGBA().apply { - val color = Color.parseColor(get(key, default.toHexTriplet())) - alpha = 1f - red = Color.red(color) / 255f - green = Color.green(color) / 255f - blue = Color.blue(color) / 255f + fun get(key: String, default: NormalizedRGBA): NormalizedRGBA { + val array = get(key, floatArrayOf(default.alpha, default.red, default.green, default.blue)) + return NormalizedRGBA().apply { + alpha = array[0] + red = array[1] + green = array[2] + blue = array[3] } - - fun NormalizedRGBA.toHexTriplet(): String { - val r = (red * 255f).roundToInt().coerceIn(0, 255) - val g = (green * 255f).roundToInt().coerceIn(0, 255) - val b = (blue * 255f).roundToInt().coerceIn(0, 255) - - return "#%02X%02X%02X".format(r, g, b) } } \ No newline at end of file