diff --git a/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/CodeHost.kt b/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/CodeHost.kt
index 823a4b4bf0..461610cd76 100644
--- a/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/CodeHost.kt
+++ b/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/CodeHost.kt
@@ -44,12 +44,15 @@ import kotlinx.coroutines.launch
* * From `Starting` to `Running` when a `Zipline` finishes loading.
* * From `Running` to `Crashed` when a `Zipline` fails.
* * From `Running` to `Running` when the `Zipline` is replaced by a hot-reload.
+ *
+ * @param codeUpdatesFlow Returns a flow that emits a new [CodeSession] each time we should load fresh code.
*/
-internal abstract class CodeHost(
+internal open class CodeHost(
private val dispatchers: TreehouseDispatchers,
private val appScope: CoroutineScope,
private val frameClockFactory: FrameClock.Factory,
val stateStore: StateStore,
+ private val codeUpdatesFlow: Flow>,
) {
/** Contents that this app is currently responsible for. */
private val listeners = mutableListOf>()
@@ -76,9 +79,6 @@ internal abstract class CodeHost(
val codeSession: CodeSession?
get() = state.codeSession
- /** Returns a flow that emits a new [CodeSession] each time we should load fresh code. */
- abstract fun codeUpdatesFlow(): Flow>
-
fun start() {
dispatchers.checkUi()
@@ -136,7 +136,7 @@ internal abstract class CodeHost(
private fun CoroutineScope.collectCodeUpdates() {
launch(dispatchers.zipline) {
- codeUpdatesFlow().collect {
+ codeUpdatesFlow.collect {
codeSessionLoaded(it)
}
}
diff --git a/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/TreehouseApp.kt b/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/TreehouseApp.kt
index ca16e22a27..744d7b643c 100644
--- a/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/TreehouseApp.kt
+++ b/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/TreehouseApp.kt
@@ -47,7 +47,7 @@ public class TreehouseApp private constructor(
* Continuously polls for updated code, and emits a new [LoadResult] instance when new code is
* found.
*/
- private fun ziplineFlow(): Flow {
+ private val ziplineFlow: Flow = run {
var loader = ZiplineLoader(
dispatcher = dispatchers.zipline,
manifestVerifier = factory.manifestVerifier,
@@ -76,7 +76,7 @@ public class TreehouseApp private constructor(
}
}
- return loader.load(
+ loader.load(
applicationName = spec.name,
manifestUrlFlow = spec.manifestUrl,
serializersModule = spec.serializersModule,
@@ -85,25 +85,22 @@ public class TreehouseApp private constructor(
}
}
- private val codeHost = object : CodeHost(
+ private val codeHost = CodeHost(
dispatchers = dispatchers,
appScope = appScope,
frameClockFactory = factory.frameClockFactory,
stateStore = factory.stateStore,
- ) {
- override fun codeUpdatesFlow(): Flow> {
- return ziplineFlow().mapNotNull { loadResult ->
- when (loadResult) {
- is LoadResult.Failure -> {
- null // EventListener already notified.
- }
- is LoadResult.Success -> {
- createCodeSession(loadResult.zipline)
- }
+ codeUpdatesFlow = ziplineFlow.mapNotNull { loadResult ->
+ when (loadResult) {
+ is LoadResult.Failure -> {
+ null // EventListener already notified.
+ }
+ is LoadResult.Success -> {
+ createCodeSession(loadResult.zipline)
}
}
}
- }
+ )
/**
* Returns the current zipline attached to this host, or null if Zipline hasn't loaded yet. The
@@ -167,7 +164,7 @@ public class TreehouseApp private constructor(
private fun createCodeSession(zipline: Zipline): ZiplineCodeSession {
val appService = spec.create(zipline)
- // Extract the RealEventPublisher() created in ziplineFlow().
+ // Extract the RealEventPublisher() created in ziplineFlow.
val eventListener = zipline.eventListener as RealEventPublisher.ZiplineEventListener
val eventPublisher = eventListener.eventPublisher