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