Can I use object properties as a mutableState in kotlin compose?

Viewed 43

The code has been changed and reduced for this question!

I have a class called "Game" and I want to show in compose the dices value. And I want to update the composable with the new value every time a new turn is started and when that turn ends.

class Game (val board: Board, var player1: Player, var player2: Player) {
    var dices = Dices()
} 
class Dices (var first: Int = 0, var second: Int = 0) {
    fun rollDices() {
        first = rollDice()    //Returns a value between 1 and 6
        second = rollDice()
    }
    fun resetDices() {
        first = 0
        second = 0
    }
    fun areEqual() = first == second
} 

I have the composable function "gameView" which calls "diceView", that is a composable function, which makes 2 boxes and puts the dices value on them. Because "dices" is an object it doesn't get a new reference, neither does it update itself and neither can I change the value because it is inside the function.

@Composable
fun gameView(game: Game) {
    paintBoard(game.board)

    val dices by remember {mutableStateOf(game.dices)}

    diceView(dices = dices, onClick = { game.newTurn()})
}

Any ideas on how to solve this?

1 Answers

If you update class with MutableState your Composables that listen these values will trigger recomposition any of these values change

class Dices(first: Int = 0, second: Int = 0) {

    var firstDice by mutableStateOf(first)
    var secondDice by mutableStateOf(first)

    fun rollDices() {
        firstDice = rollDice()    //Returns a value between 1 and 6
        secondDice = rollDice()
    }

    fun resetDices() {
        firstDice = 0
        secondDice = 0
    }

    fun areEqual() = firstDice == secondDice
}

Example

Column(modifier = Modifier.fillMaxSize()) {
    val dices = remember { Dices(1, 1) }
    Text("Dice1: ${dices.firstDice}")
    Text("Dice2: ${dices.secondDice}")

    Button(onClick = { dices.rollDices() }) {
        Text("Roll")
    }

    Button(onClick = { dices.resetDices() }) {
        Text("Reset")
    }
}
Related