FutureMind/koru

Consider supporting wrapper inheriting from abstract class wrapper

micHar opened this issue · 1 comments

Working with something like KaMPKit reveals a limitation of Koru.

commonMain:

@ToNativeClass
expect abstract class ViewModel() {
    val viewModelScope: CoroutineScope
    open fun onCleared()
}

@ToNativeClass
class BreedViewModel : ViewModel() {
    val mutableBreedState: MutableStateFlow<String> = MutableStateFlow("")
}

+iosMain

actual abstract class ViewModel {
    actual val viewModelScope = MainScope()

    actual open fun onCleared() {
    }

    fun clear() {
        onCleared()
        viewModelScope.cancel()
    }
}

Will result in:

public abstract class ViewModelNative(
  private val wrapped: ViewModel,
  private val scopeProvider: ScopeProvider?,
) {
  public val viewModelScope: CoroutineScope
    get() = wrapped.viewModelScope

  public constructor(wrapped: ViewModel) : this(wrapped,null)

  public open fun onCleared(): Unit = wrapped.onCleared()
}

public class BreedViewModelNative(
  private val wrapped: BreedViewModel,
  private val scopeProvider: ScopeProvider?,
) {
  public val mutableBreedState: FlowWrapper<String>
    get() = com.futuremind.koru.FlowWrapper(scopeProvider, false, wrapped.mutableBreedState)

  public constructor(wrapped: BreedViewModel) : this(wrapped,null)
}

What we lack is BreedViewModelNative extending ViewModelNative. And @ToNativeInterface will not be enough here, since we need the wrapper to actually call the wrapped functions of the abstract class.

But it's tricky and might just not make sense, because the whole idea behind Kampkit's viewmodel is to give ios a similar abstraction to android's with viewmodelscope and scope clearing. They are handled automatically by the scopeProvider here. Will look into different scenarios though.