Skip to content

Instantly share code, notes, and snippets.

@cjbrooks12
Created February 7, 2023 17:49
Show Gist options
  • Save cjbrooks12/07738ae3a29c56a9eafa63ac0c8eafb2 to your computer and use it in GitHub Desktop.
Save cjbrooks12/07738ae3a29c56a9eafa63ac0c8eafb2 to your computer and use it in GitHub Desktop.
Ballast Repository Pattern
object Injector {
private val singletonCoroutineScope = CoroutineScope(Dispatchers.Default + SupervisorJob())
private val repository = Repository(
coroutineScope = singletonCoroutineScope,
config = BallastViewModelConfiguration.Builder()
.withViewModel(
inputHandler = RepositoryInputHandler(),
initialState = RepositoryContract.State(),
name = "Repository",
)
.build(),
eventHandler = eventHandler { },
)
public fun getUiViewModel(coroutineScope: CoroutineScope): UiViewModel {
return UiViewModel(
coroutineScope = coroutineScope,
config = BallastViewModelConfiguration.Builder()
.withViewModel(
inputHandler = UiInputHandler(repository),
initialState = UiContract.State(),
name = "UI",
)
.build(),
eventHandler = eventHandler { },
)
}
}
public object RepositoryContract {
data class State(
val isLoggedIn: Boolean = false,
val username: String? = null,
)
sealed class Inputs {
data class LogIn(val username: String) : Inputs()
data class LogOut(val username: String) : Inputs()
}
sealed class Events
}
class RepositoryInputHandler : InputHandler<
RepositoryContract.Inputs,
RepositoryContract.Events,
RepositoryContract.State> {
override suspend fun InputHandlerScope<
RepositoryContract.Inputs,
RepositoryContract.Events,
RepositoryContract.State>.handleInput(
input: RepositoryContract.Inputs
) = when (input) {
is RepositoryContract.Inputs.LogIn -> {
updateState { it.copy(isLoggedIn = true, username = input.username) }
}
is RepositoryContract.Inputs.LogOut -> {
updateState { it.copy(isLoggedIn = false, username = null) }
}
}
}
typealias Repository = BasicViewModel<
RepositoryContract.Inputs,
RepositoryContract.Events,
RepositoryContract.State>
public object UiContract {
data class State(
val repositoryState: RepositoryContract.State = RepositoryContract.State(),
)
sealed class Inputs {
object Initialize : Inputs()
data class RepositoryStateChanged(val state: RepositoryContract.State) : Inputs()
}
sealed class Events
}
class UiInputHandler(
private val repository: Repository,
) : InputHandler<
UiContract.Inputs,
UiContract.Events,
UiContract.State> {
override suspend fun InputHandlerScope<
UiContract.Inputs,
UiContract.Events,
UiContract.State>.handleInput(
input: UiContract.Inputs
) = when (input) {
is UiContract.Inputs.Initialize -> {
observeFlows(
"Observe Repository State",
repository
.observeStates()
.map { UiContract.Inputs.RepositoryStateChanged(it) },
)
}
is UiContract.Inputs.RepositoryStateChanged -> {
updateState { it.copy(repositoryState = input.state) }
}
}
}
typealias UiViewModel = BasicViewModel<
UiContract.Inputs,
UiContract.Events,
UiContract.State>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment