Skip to content

Commit

Permalink
Scope all events to a code session
Browse files Browse the repository at this point in the history
This gives us a code version to attribute failures to.

This is a backwards-incompatible change; we need to pass
an EventListener.Factory instead of an EventListener when
creating a TreehouseApp.

This drops the appStart() and appCanceled() events. These
are roughly approximated by the scoped codeLoadStart()
and codeUnloaded() functions.
  • Loading branch information
squarejesse committed Nov 1, 2023
1 parent 58f652b commit 452ef54
Show file tree
Hide file tree
Showing 17 changed files with 117 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public fun TreehouseAppFactory(
context: Context,
httpClient: OkHttpClient,
manifestVerifier: ManifestVerifier,
eventListener: EventListener = EventListener(),
eventListenerFactory: EventListener.Factory = EventListener.NONE,
embeddedDir: Path? = null,
embeddedFileSystem: FileSystem? = null,
cacheName: String = "zipline",
Expand All @@ -36,7 +36,7 @@ public fun TreehouseAppFactory(
): TreehouseApp.Factory = TreehouseApp.Factory(
platform = AndroidTreehousePlatform(context),
dispatchers = AndroidTreehouseDispatchers(),
eventListener = eventListener,
eventListenerFactory = eventListenerFactory,
httpClient = httpClient.asZiplineHttpClient(),
frameClockFactory = AndroidChoreographerFrameClock.Factory(),
manifestVerifier = manifestVerifier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import kotlinx.serialization.json.Json

/** The host state for a single code load. We get a new session each time we get new code. */
internal interface CodeSession<A : AppService> {
val eventPublisher: EventPublisher

val appService: A

val json: Json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import app.cash.redwood.protocol.Id
import app.cash.redwood.protocol.ModifierTag
import app.cash.redwood.protocol.PropertyTag
import app.cash.redwood.protocol.WidgetTag
import app.cash.redwood.treehouse.EventListener.Factory
import app.cash.zipline.Call
import app.cash.zipline.CallResult
import app.cash.zipline.Zipline
Expand All @@ -30,37 +31,14 @@ import kotlin.native.ObjCName

@ObjCName("EventListener", exact = true)
public open class EventListener {
/**
* Invoked each time a [TreehouseApp] is created. When this is triggered the app may not yet have
* any code loaded; but it will always attempt to load code.
*/
public open fun appStart(
app: TreehouseApp<*>,
) {
}

/**
* Invoked with [TreehouseApp.cancel] when the application is shut down.
*
* This is different from [codeUnloaded] which occurs during hot reloads; this only occurs if the
* app itself is explicitly closed.
*/
public open fun appCanceled(
app: TreehouseApp<*>,
) {
}

/**
* Invoked for each attempt at loading code. This will be followed by a [codeLoadSuccess],
* [codeLoadFailed], or [codeLoadSkipped] if the code is unchanged.
*
* @return any object. This value will be passed back to one of the above functions. The base
* function always returns null.
*/
public open fun codeLoadStart(
app: TreehouseApp<*>,
manifestUrl: String?,
): Any? = null
public open fun codeLoadStart(): Any? = null

/**
* Invoked when code is successfully downloaded and initialized.
Expand All @@ -69,8 +47,6 @@ public open class EventListener {
* is null unless [codeLoadStart] is overridden to return something else.
*/
public open fun codeLoadSuccess(
app: TreehouseApp<*>,
manifestUrl: String?,
manifest: ZiplineManifest,
zipline: Zipline,
startValue: Any?,
Expand All @@ -84,8 +60,6 @@ public open class EventListener {
* is null unless [codeLoadStart] is overridden to return something else.
*/
public open fun codeLoadSkipped(
app: TreehouseApp<*>,
manifestUrl: String?,
startValue: Any?,
) {
}
Expand All @@ -97,8 +71,6 @@ public open class EventListener {
* is null unless [codeLoadStart] is overridden to return something else.
*/
public open fun codeLoadFailed(
app: TreehouseApp<*>,
manifestUrl: String?,
exception: Exception,
startValue: Any?,
) {
Expand All @@ -108,17 +80,13 @@ public open class EventListener {
* Invoked when code is unloaded because it is no longer needed. Typically this occurs when a hot
* code update is applied.
*/
public open fun codeUnloaded(
app: TreehouseApp<*>,
zipline: Zipline,
) {
public open fun codeUnloaded() {
}

/**
* Invoked on a request to create an unknown widget [kind].
*/
public open fun onUnknownWidget(
app: TreehouseApp<*>,
tag: WidgetTag,
) {
}
Expand All @@ -127,7 +95,6 @@ public open class EventListener {
* Invoked on a request to create an unknown modifier [tag].
*/
public open fun onUnknownModifier(
app: TreehouseApp<*>,
tag: ModifierTag,
) {
}
Expand All @@ -136,7 +103,6 @@ public open class EventListener {
* Invoked on a request to manipulate unknown children [tag] for the specified widget [kind].
*/
public open fun onUnknownChildren(
app: TreehouseApp<*>,
widgetTag: WidgetTag,
tag: ChildrenTag,
) {
Expand All @@ -146,23 +112,20 @@ public open class EventListener {
* Invoked on a request to set an unknown property [tag] for the specified widget [kind].
*/
public open fun onUnknownProperty(
app: TreehouseApp<*>,
widgetTag: WidgetTag,
tag: PropertyTag,
) {
}

/** Invoked on a request to process an unknown event [tag] for the specified widget [widgetTag]. */
public open fun onUnknownEvent(
app: TreehouseApp<*>,
widgetTag: WidgetTag,
tag: EventTag,
) {
}

/** Invoked for an event whose node [id] is unknown. */
public open fun onUnknownEventNode(
app: TreehouseApp<*>,
id: Id,
tag: EventTag,
) {
Expand All @@ -176,7 +139,6 @@ public open class EventListener {
* function always returns null.
*/
public open fun downloadStart(
app: TreehouseApp<*>,
url: String,
): Any? = null

Expand All @@ -187,7 +149,6 @@ public open class EventListener {
* is null unless [downloadStart] is overridden to return something else.
*/
public open fun downloadSuccess(
app: TreehouseApp<*>,
url: String,
startValue: Any?,
) {
Expand All @@ -200,7 +161,6 @@ public open class EventListener {
* is null unless [downloadStart] is overridden to return something else.
*/
public open fun downloadFailed(
app: TreehouseApp<*>,
url: String,
exception: Exception,
startValue: Any?,
Expand All @@ -212,8 +172,6 @@ public open class EventListener {
* failures are signaled with [codeLoadFailed].
*/
public open fun manifestVerified(
app: TreehouseApp<*>,
manifestUrl: String?,
manifest: ZiplineManifest,
verifiedKey: String,
) {
Expand All @@ -226,8 +184,6 @@ public open class EventListener {
* completed. The base function always returns null.
*/
public open fun moduleLoadStart(
app: TreehouseApp<*>,
zipline: Zipline,
moduleId: String,
): Any? {
return null
Expand All @@ -240,8 +196,6 @@ public open class EventListener {
* null unless [moduleLoadStart] is overridden to return something else.
*/
public open fun moduleLoadEnd(
app: TreehouseApp<*>,
zipline: Zipline,
moduleId: String,
startValue: Any?,
) {
Expand All @@ -254,8 +208,6 @@ public open class EventListener {
* completed. The base function always returns null.
*/
public open fun initializerStart(
app: TreehouseApp<*>,
zipline: Zipline,
applicationName: String,
): Any? {
return null
Expand All @@ -268,8 +220,6 @@ public open class EventListener {
* null unless [initializerStart] is overridden to return something else.
*/
public open fun initializerEnd(
app: TreehouseApp<*>,
zipline: Zipline,
applicationName: String,
startValue: Any?,
) {
Expand All @@ -282,8 +232,6 @@ public open class EventListener {
* completed. The base function always returns null.
*/
public open fun mainFunctionStart(
app: TreehouseApp<*>,
zipline: Zipline,
applicationName: String,
): Any? {
return null
Expand All @@ -296,8 +244,6 @@ public open class EventListener {
* null unless [mainFunctionStart] is overridden to return something else.
*/
public open fun mainFunctionEnd(
app: TreehouseApp<*>,
zipline: Zipline,
applicationName: String,
startValue: Any?,
) {
Expand All @@ -308,8 +254,6 @@ public open class EventListener {
* a captive portal on the network.
*/
public open fun manifestParseFailed(
app: TreehouseApp<*>,
url: String?,
exception: Exception,
) {
}
Expand All @@ -318,7 +262,6 @@ public open class EventListener {
* Invoked when something calls [Zipline.bind], or a service is sent via an API.
*/
public open fun bindService(
app: TreehouseApp<*>,
name: String,
service: ZiplineService,
) {
Expand All @@ -328,7 +271,6 @@ public open class EventListener {
* Invoked when something calls [Zipline.take], or a service is received via an API.
*/
public open fun takeService(
app: TreehouseApp<*>,
name: String,
service: ZiplineService,
) {
Expand All @@ -342,7 +284,6 @@ public open class EventListener {
* base function always returns null.
*/
public open fun callStart(
app: TreehouseApp<*>,
call: Call,
): Any? = null

Expand All @@ -353,7 +294,6 @@ public open class EventListener {
* unless [callStart] is overridden to return something else.
*/
public open fun callEnd(
app: TreehouseApp<*>,
call: Call,
result: CallResult,
startValue: Any?,
Expand All @@ -366,7 +306,6 @@ public open class EventListener {
* Note that this method may be invoked after [codeUnloaded].
*/
public open fun serviceLeaked(
app: TreehouseApp<*>,
name: String,
) {
}
Expand All @@ -382,8 +321,25 @@ public open class EventListener {
* execute. A new [Zipline] will start when new code available, or when the app is restarted.
*/
public open fun uncaughtException(
app: TreehouseApp<*>,
exception: Throwable,
) {
}

public fun interface Factory {
/**
* Returns an event listener that receives the events of a specific code session. Each code
* session includes a single [Zipline] instance, unless code loading fails, in which case there
* will be no [Zipline] instance.
*/
public fun create(
app: TreehouseApp<*>,
manifestUrl: String?,
): EventListener
}

public companion object {
public val NONE: Factory = Factory { app, manifestUrl ->
EventListener()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ internal interface EventPublisher {

val widgetProtocolMismatchHandler: ProtocolMismatchHandler

fun appStart()

fun appCanceled()

fun onUnknownEvent(widgetTag: WidgetTag, tag: EventTag)

fun onUnknownEventNode(id: Id, tag: EventTag)
Expand Down
Loading

0 comments on commit 452ef54

Please sign in to comment.