Delegates.observable -> Support for sub classes?


#1

Hi,

I’m fairly new to Kolin and I’m trying to convert a small Java application to Koltlin, mainly as an exercise. I want to implement the State pattern. For this I have the following setup (simplified):

interface State {
    fun selectState(context: Context)
}

object State1 : State {
    override fun selectState(context: Context) {
        if (...) {
            context.currentState = State2
            context.updateState()
        }
    }
}

object State2 : State {
    override fun selectState(context: Context) {
        if (...) {
            context.currentState = State1
            context.updateState()
        }
    }
}

class Context {
    var currentState: State = State1

    fun updateState() {
        currentState.selectState(this)
    }
}

I want to get rid of the updateState() calls inside the states and call this whenever the currentState of the context is changed. So I thought that I can use an Observable for this:

var currentState: State by Delegates.observable(State1) { _, _, _ -> 
    updateState()
}

But this results in an error message:

Error:(22, 32) Kotlin: Property delegate must have a 'setValue(Context, KProperty<*>, State)' method. None of the following functions is suitable: 
public abstract operator fun setValue(thisRef: Any?, property: KProperty<*>, value: State1): Unit      defined in kotlin.properties.ReadWriteProperty

I think the problem is that ObservableProperty and ReadWriteProperty do not use generic constraints.

Is there another way to do this?


#2

“Delegates.observable(State1)” assumes the type of the variable to be “State1” and not “State”.
Try this:

var currentState: State by Delegates.observable<State>(State1) { _, _, _ ->
    updateState()
}

#3

Just tested this and it’s working! Thank you :grinning:

Forgot how you can explicitly tell generic methods what type you want…