Compare commits

..

4 commits

Author SHA1 Message Date
Joe Kearney
0827bdc7b4 Fixed compile errors. 2025-09-14 14:41:12 -05:00
Joe Kearney
527ad08c28 Merge branch 'main' into config_handshake 2025-09-04 19:18:12 -05:00
74fc19c64d Added setParameter function that handles dirt flags 2025-06-18 20:52:32 -05:00
67426165b7 Added dirty flags to Device class 2025-06-18 20:15:40 -05:00
5 changed files with 143 additions and 32 deletions

View file

@ -2,14 +2,60 @@ package club.clubk.ktag.konfigurator
import java.util.UUID
const val EDIT_DELAY_TIME: Long = 3L
sealed class DeviceState {
data object Configurable : DeviceState()
data object Ready : DeviceState()
data object Playing : DeviceState()
data object WrapUp : DeviceState()
}
sealed class DeviceConfigureState {
data object Discovered: DeviceConfigureState()
data object Configuring: DeviceConfigureState()
data object Success: DeviceConfigureState()
data object Failure: DeviceConfigureState()
}
enum class DeviceParameter {
PLAYER_ID, TEAM, SECONDARY_COLOR, MAX_HEALTH, SPECIAL_WEAPONS
}
data class Device(val uuid: UUID = UUID.randomUUID(),
var name: String = "Unknown Device",
var address: String = "FF:FF:FF:FF:FF:FF",
var deviceType : Int? = null,
var team : Int? = null,
var playerID : Int? = null,
var deviceState: DeviceState? = null
var address: String = "00:00:00:00:00:00",
var deviceType: Int? = null,
var deviceState: DeviceState? = null,
// All configurable variables
private var _playerID: Int? = null,
private var _team: Int? = null,
private var _secondaryColor: Int? = null,
private var _maxHealth: Int? = null,
private var _specialWeapons: Int? = null
) {
var deviceConfigureState: DeviceConfigureState = DeviceConfigureState.Discovered
private set
var dirtyPlayerID: Boolean = false
private set
var dirtyTeam: Boolean = false
private set
var dirtySecondaryColor: Boolean = false
private set
var dirtyMaxHealth: Boolean = false
private set
var dirtySpecialWeapons: Boolean = false
private set
var lastEditTime: Long = 0L
private set
val playerID: Int? get() = _playerID
val team: Int? get() = _team
val secondaryColor: Int? get() = _secondaryColor
val maxHealth: Int? get() = _maxHealth
val specialWeapons: Int? get() = _specialWeapons
fun deviceTypeName(): String {
return when(deviceType) {
@ -20,5 +66,67 @@ data class Device(val uuid: UUID = UUID.randomUUID(),
else -> "Unknown Device Type"
}
}
}
fun deviceTypeDrawable() {
return
}
fun isDirty(): Boolean {
return dirtyPlayerID || dirtyTeam || dirtySecondaryColor
|| dirtyMaxHealth || dirtySpecialWeapons
}
fun isPastEditTime(): Boolean {
return System.nanoTime() - lastEditTime!! >= EDIT_DELAY_TIME
}
fun setParameter(parameter: DeviceParameter, value: Any) {
lastEditTime = System.nanoTime()
when (parameter) {
DeviceParameter.PLAYER_ID -> {
_playerID = value as Int
dirtyPlayerID = true
}
DeviceParameter.TEAM -> {
_team = value as Int
dirtyTeam = true
}
DeviceParameter.SECONDARY_COLOR -> {
_secondaryColor = value as Int
dirtySecondaryColor = true
}
DeviceParameter.MAX_HEALTH -> {
_maxHealth = value as Int
dirtyMaxHealth = true
}
DeviceParameter.SPECIAL_WEAPONS -> {
_specialWeapons = value as Int
dirtySpecialWeapons = true
}
}
}
fun checkForDirt() {
if (isDirty() && isPastEditTime()) {
return
}
}
fun getDirtyParameters(): List<DeviceParameter> {
val changed = mutableListOf<DeviceParameter>()
if (dirtyPlayerID) changed.add(DeviceParameter.PLAYER_ID)
if (dirtyTeam) changed.add(DeviceParameter.TEAM)
if (dirtySecondaryColor) changed.add(DeviceParameter.SECONDARY_COLOR)
if (dirtyMaxHealth) changed.add(DeviceParameter.MAX_HEALTH)
if (dirtySpecialWeapons) changed.add(DeviceParameter.SPECIAL_WEAPONS)
return changed
}
fun clearDirt() {
dirtyPlayerID = false
dirtyTeam = false
dirtySecondaryColor = false
dirtyMaxHealth = false
dirtySpecialWeapons = false
}
}

View file

@ -1,8 +0,0 @@
package club.clubk.ktag.konfigurator
sealed class DeviceState {
object Configurable : DeviceState()
object Ready : DeviceState()
object Playing : DeviceState()
object WrapUp : DeviceState()
}

View file

@ -5,5 +5,5 @@ data class GameConfig(var name: String = "Default",
var pregameLength: Int = 60000,
var numRounds: Int = 2,
var maxHealth: Int = 10,
var numBombs: Int = 1 // Special Weapons Received on Game Reentry
var specialWeapons: Int = 1 // Special Weapons Received on Game Reentry
)

View file

@ -1,8 +1,6 @@
package club.clubk.ktag.konfigurator
import android.Manifest
import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
@ -23,7 +21,6 @@ import androidx.core.content.ContextCompat
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
@ -253,7 +250,7 @@ fun GameConfigEditor(oldGameConfig: GameConfig,
var pregameLength by rememberSaveable(oldGameConfig.pregameLength) { mutableStateOf(oldGameConfig.pregameLength.toString()) }
var numRounds by rememberSaveable(oldGameConfig.numRounds) { mutableStateOf(oldGameConfig.numRounds.toString()) }
var maxHealth by rememberSaveable(oldGameConfig.maxHealth) { mutableStateOf(oldGameConfig.maxHealth.toString()) }
var numBombs by rememberSaveable(oldGameConfig.numBombs) { mutableStateOf(oldGameConfig.numBombs.toString()) }
var numBombs by rememberSaveable(oldGameConfig.specialWeapons) { mutableStateOf(oldGameConfig.specialWeapons.toString()) }
// For tracking validation errors
var gameLengthError by rememberSaveable { mutableStateOf(false) }
@ -283,7 +280,7 @@ fun GameConfigEditor(oldGameConfig: GameConfig,
pregameLength = pregameLength.toIntOrNull() ?: oldGameConfig.pregameLength,
numRounds = numRounds.toIntOrNull() ?: oldGameConfig.numRounds,
maxHealth = maxHealth.toIntOrNull() ?: oldGameConfig.maxHealth,
numBombs = numBombs.toIntOrNull() ?: oldGameConfig.numBombs
specialWeapons = numBombs.toIntOrNull() ?: oldGameConfig.specialWeapons
)
onSave(newGameConfig)
}

View file

@ -69,10 +69,12 @@ class StateMachineViewModel(context: Context) : ViewModel() {
when (packet) {
is HelloPacket -> {
// Log.d(TAG_BLE_SCAN, "HelloPacket scanned")
scannedDevice.name = packet.deviceName
scannedDevice.deviceType = packet.deviceType
scannedDevice.team = packet.teamId
scannedDevice.deviceState = DeviceState.Configurable
val scannedDevice = Device(
name = packet.deviceName,
address = result.device.address,
deviceType = packet.deviceType,
deviceState = DeviceState.Configurable)
scannedDevice.setParameter(DeviceParameter.TEAM, packet.teamId)
addOrRefreshDevice(scannedDevice)
}
is ConsolePacket -> {
@ -148,9 +150,13 @@ class StateMachineViewModel(context: Context) : ViewModel() {
var oldDevice = currentDevices[index]
newDevice.name = oldDevice.name
newDevice.deviceType = oldDevice.deviceType ?: newDevice.deviceType
newDevice.team = oldDevice.team ?: newDevice.team
newDevice.playerID = oldDevice.playerID ?: newDevice.playerID
newDevice.deviceState = newDevice.deviceState ?: oldDevice.deviceState
oldDevice.team?.let { teamValue ->
newDevice.setParameter(DeviceParameter.TEAM, teamValue)
}
oldDevice.playerID?.let { playerIDValue ->
newDevice.setParameter(DeviceParameter.PLAYER_ID, playerIDValue)
}
currentDevices[index] = newDevice
}
_devices.value = currentDevices
@ -165,18 +171,26 @@ class StateMachineViewModel(context: Context) : ViewModel() {
if (index == -1) { return }
var oldDevice = currentDevices[index]
newDevice.deviceType = newDevice.deviceType ?: oldDevice.deviceType
newDevice.team = newDevice.team ?: oldDevice.team
newDevice.playerID = newDevice.playerID ?: oldDevice.playerID
oldDevice.team?.let { teamValue ->
newDevice.setParameter(DeviceParameter.TEAM, teamValue)
}
oldDevice.playerID?.let { playerIDValue ->
newDevice.setParameter(DeviceParameter.PLAYER_ID, playerIDValue)
}
currentDevices[index] = newDevice
_devices.value = currentDevices
_allDevicesReady.value = allDevicesReady()
}
fun updateDeviceTeam(deviceAddress: String, newTeam: Int) {
fun updateDeviceTeam(deviceAddress: String, newTeam: Int?) {
_devices.update { currentList ->
currentList.map { device ->
if (device.address == deviceAddress) {
device.copy(team = newTeam) // Creates a new Device instance
val updatedDevice = device.copy()
if (newTeam != null) {
updatedDevice.setParameter(DeviceParameter.TEAM, newTeam)
}
updatedDevice // Return the modified device
} else {
device
}
@ -187,7 +201,7 @@ class StateMachineViewModel(context: Context) : ViewModel() {
fun cycleDeviceTeam(device: Device) {
Log.d("STATEMACHINE", "cycling device team")
var newTeam = device.team ?: -1
var newTeam: Int = (device.team?.toInt() ?: -1)
newTeam++
if (newTeam > 2) {
newTeam = 0
@ -244,7 +258,7 @@ class StateMachineViewModel(context: Context) : ViewModel() {
parameterPacketGenerator.generatePacket(
targetAddress = device.address,
subtype = 2, // Request Parameter Change
key1 = 1, value1 = teamId, // Key 1 is Team ID
key1 = 1, value1 = teamId.toInt(), // Key 1 is Team ID
key2 = 4, value2 = gameCfg.maxHealth // Key 2 is Max Health
)
// If a device for some reason can't be configured (e.g. missing address),