diff --git a/redwood-protocol-guest/api/redwood-protocol-guest.api b/redwood-protocol-guest/api/redwood-protocol-guest.api index 4a14797de5..4161cf6673 100644 --- a/redwood-protocol-guest/api/redwood-protocol-guest.api +++ b/redwood-protocol-guest/api/redwood-protocol-guest.api @@ -13,7 +13,6 @@ public final class app/cash/redwood/protocol/guest/DefaultGuestProtocolAdapter : public fun emitChanges ()V public fun getJson ()Lkotlinx/serialization/json/Json; public fun getRoot ()Lapp/cash/redwood/widget/Widget$Children; - public fun getSynthesizeSubtreeRemoval ()Z public fun getWidgetSystem ()Lapp/cash/redwood/widget/WidgetSystem; public fun initChangesSink (Lapp/cash/redwood/protocol/ChangesSink;)V public fun nextId-0HhLjSo ()I @@ -22,7 +21,9 @@ public final class app/cash/redwood/protocol/guest/DefaultGuestProtocolAdapter : public final fun takeChanges ()Ljava/util/List; } -public abstract interface class app/cash/redwood/protocol/guest/GuestProtocolAdapter : app/cash/redwood/protocol/EventSink { +public abstract class app/cash/redwood/protocol/guest/GuestProtocolAdapter : app/cash/redwood/protocol/EventSink { + public static final field $stable I + public synthetic fun (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public abstract fun appendAdd-ARs5Qwk (IIILapp/cash/redwood/protocol/guest/ProtocolWidget;)V public abstract fun appendCreate-kyz2zXs (II)V public abstract fun appendModifierChange-z3jyS0k (ILapp/cash/redwood/Modifier;)V @@ -31,11 +32,11 @@ public abstract interface class app/cash/redwood/protocol/guest/GuestProtocolAda public abstract fun appendPropertyChange-M7EZMwg (III)V public abstract fun appendPropertyChange-e3iP1vo (IIZ)V public abstract fun appendRemove-HpxY78w (IIIILjava/util/List;)V - public static synthetic fun appendRemove-HpxY78w$default (Lapp/cash/redwood/protocol/guest/GuestProtocolAdapter;IIIILjava/util/List;ILjava/lang/Object;)V public abstract fun emitChanges ()V + public final fun getChildrenVisitor ()Lapp/cash/redwood/protocol/guest/ProtocolWidget$ChildrenVisitor; public abstract fun getJson ()Lkotlinx/serialization/json/Json; public abstract fun getRoot ()Lapp/cash/redwood/widget/Widget$Children; - public abstract fun getSynthesizeSubtreeRemoval ()Z + public final fun getSynthesizeSubtreeRemoval ()Z public abstract fun getWidgetSystem ()Lapp/cash/redwood/widget/WidgetSystem; public abstract fun initChangesSink (Lapp/cash/redwood/protocol/ChangesSink;)V public abstract fun nextId-0HhLjSo ()I @@ -58,7 +59,7 @@ public final class app/cash/redwood/protocol/guest/ProtocolRedwoodCompositionKt } public abstract interface class app/cash/redwood/protocol/guest/ProtocolWidget : app/cash/redwood/widget/Widget { - public abstract fun depthFirstWalk (Lkotlin/jvm/functions/Function3;)V + public abstract fun depthFirstWalk (Lapp/cash/redwood/protocol/guest/ProtocolWidget$ChildrenVisitor;)V public abstract fun getId-0HhLjSo ()I public abstract fun getTag-BlhN7y0 ()I public synthetic fun getValue ()Ljava/lang/Object; @@ -66,10 +67,14 @@ public abstract interface class app/cash/redwood/protocol/guest/ProtocolWidget : public abstract fun sendEvent (Lapp/cash/redwood/protocol/Event;)V } +public abstract interface class app/cash/redwood/protocol/guest/ProtocolWidget$ChildrenVisitor { + public abstract fun visit-KUkifdM (Lapp/cash/redwood/protocol/guest/ProtocolWidget;ILapp/cash/redwood/protocol/guest/ProtocolWidgetChildren;)V +} + public final class app/cash/redwood/protocol/guest/ProtocolWidgetChildren : app/cash/redwood/widget/Widget$Children { public static final field $stable I public synthetic fun (IILapp/cash/redwood/protocol/guest/GuestProtocolAdapter;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun depthFirstWalk (Lapp/cash/redwood/protocol/guest/ProtocolWidget;Lkotlin/jvm/functions/Function3;)V + public final fun depthFirstWalk (Lapp/cash/redwood/protocol/guest/ProtocolWidget;Lapp/cash/redwood/protocol/guest/ProtocolWidget$ChildrenVisitor;)V public fun detach ()V public fun getWidgets ()Ljava/util/List; public fun insert (ILapp/cash/redwood/widget/Widget;)V diff --git a/redwood-protocol-guest/api/redwood-protocol-guest.klib.api b/redwood-protocol-guest/api/redwood-protocol-guest.klib.api index 639566f456..98cbb26011 100644 --- a/redwood-protocol-guest/api/redwood-protocol-guest.klib.api +++ b/redwood-protocol-guest/api/redwood-protocol-guest.klib.api @@ -6,30 +6,6 @@ // - Show declarations: true // Library unique name: -abstract interface app.cash.redwood.protocol.guest/GuestProtocolAdapter : app.cash.redwood.protocol/EventSink { // app.cash.redwood.protocol.guest/GuestProtocolAdapter|null[0] - abstract val json // app.cash.redwood.protocol.guest/GuestProtocolAdapter.json|{}json[0] - abstract fun (): kotlinx.serialization.json/Json // app.cash.redwood.protocol.guest/GuestProtocolAdapter.json.|(){}[0] - abstract val root // app.cash.redwood.protocol.guest/GuestProtocolAdapter.root|{}root[0] - abstract fun (): app.cash.redwood.widget/Widget.Children // app.cash.redwood.protocol.guest/GuestProtocolAdapter.root.|(){}[0] - abstract val synthesizeSubtreeRemoval // app.cash.redwood.protocol.guest/GuestProtocolAdapter.synthesizeSubtreeRemoval|{}synthesizeSubtreeRemoval[0] - abstract fun (): kotlin/Boolean // app.cash.redwood.protocol.guest/GuestProtocolAdapter.synthesizeSubtreeRemoval.|(){}[0] - abstract val widgetSystem // app.cash.redwood.protocol.guest/GuestProtocolAdapter.widgetSystem|{}widgetSystem[0] - abstract fun (): app.cash.redwood.widget/WidgetSystem // app.cash.redwood.protocol.guest/GuestProtocolAdapter.widgetSystem.|(){}[0] - - abstract fun <#A1: kotlin/Any?> appendPropertyChange(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/PropertyTag, kotlinx.serialization/KSerializer<#A1>, #A1) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendPropertyChange|appendPropertyChange(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.PropertyTag;kotlinx.serialization.KSerializer<0:0>;0:0){0§}[0] - abstract fun appendAdd(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, app.cash.redwood.protocol.guest/ProtocolWidget) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendAdd|appendAdd(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;app.cash.redwood.protocol.guest.ProtocolWidget){}[0] - abstract fun appendCreate(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/WidgetTag) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendCreate|appendCreate(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.WidgetTag){}[0] - abstract fun appendModifierChange(app.cash.redwood.protocol/Id, app.cash.redwood/Modifier) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendModifierChange|appendModifierChange(app.cash.redwood.protocol.Id;app.cash.redwood.Modifier){}[0] - abstract fun appendMove(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, kotlin/Int, kotlin/Int) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendMove|appendMove(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;kotlin.Int;kotlin.Int){}[0] - abstract fun appendPropertyChange(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/PropertyTag, kotlin/Boolean) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendPropertyChange|appendPropertyChange(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.PropertyTag;kotlin.Boolean){}[0] - abstract fun appendPropertyChange(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/PropertyTag, kotlin/UInt) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendPropertyChange|appendPropertyChange(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.PropertyTag;kotlin.UInt){}[0] - abstract fun appendRemove(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, kotlin/Int, kotlin.collections/List = ...) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendRemove|appendRemove(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;kotlin.Int;kotlin.collections.List){}[0] - abstract fun emitChanges() // app.cash.redwood.protocol.guest/GuestProtocolAdapter.emitChanges|emitChanges(){}[0] - abstract fun initChangesSink(app.cash.redwood.protocol/ChangesSink) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.initChangesSink|initChangesSink(app.cash.redwood.protocol.ChangesSink){}[0] - abstract fun nextId(): app.cash.redwood.protocol/Id // app.cash.redwood.protocol.guest/GuestProtocolAdapter.nextId|nextId(){}[0] - abstract fun removeWidget(app.cash.redwood.protocol/Id) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.removeWidget|removeWidget(app.cash.redwood.protocol.Id){}[0] -} - abstract interface app.cash.redwood.protocol.guest/ProtocolMismatchHandler { // app.cash.redwood.protocol.guest/ProtocolMismatchHandler|null[0] abstract fun onUnknownEvent(app.cash.redwood.protocol/WidgetTag, app.cash.redwood.protocol/EventTag) // app.cash.redwood.protocol.guest/ProtocolMismatchHandler.onUnknownEvent|onUnknownEvent(app.cash.redwood.protocol.WidgetTag;app.cash.redwood.protocol.EventTag){}[0] abstract fun onUnknownEventNode(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/EventTag) // app.cash.redwood.protocol.guest/ProtocolMismatchHandler.onUnknownEventNode|onUnknownEventNode(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.EventTag){}[0] @@ -48,8 +24,12 @@ abstract interface app.cash.redwood.protocol.guest/ProtocolWidget : app.cash.red open val value // app.cash.redwood.protocol.guest/ProtocolWidget.value|{}value[0] open fun () // app.cash.redwood.protocol.guest/ProtocolWidget.value.|(){}[0] - abstract fun depthFirstWalk(kotlin/Function3) // app.cash.redwood.protocol.guest/ProtocolWidget.depthFirstWalk|depthFirstWalk(kotlin.Function3){}[0] + abstract fun depthFirstWalk(app.cash.redwood.protocol.guest/ProtocolWidget.ChildrenVisitor) // app.cash.redwood.protocol.guest/ProtocolWidget.depthFirstWalk|depthFirstWalk(app.cash.redwood.protocol.guest.ProtocolWidget.ChildrenVisitor){}[0] abstract fun sendEvent(app.cash.redwood.protocol/Event) // app.cash.redwood.protocol.guest/ProtocolWidget.sendEvent|sendEvent(app.cash.redwood.protocol.Event){}[0] + + abstract fun interface ChildrenVisitor { // app.cash.redwood.protocol.guest/ProtocolWidget.ChildrenVisitor|null[0] + abstract fun visit(app.cash.redwood.protocol.guest/ProtocolWidget, app.cash.redwood.protocol/ChildrenTag, app.cash.redwood.protocol.guest/ProtocolWidgetChildren) // app.cash.redwood.protocol.guest/ProtocolWidget.ChildrenVisitor.visit|visit(app.cash.redwood.protocol.guest.ProtocolWidget;app.cash.redwood.protocol.ChildrenTag;app.cash.redwood.protocol.guest.ProtocolWidgetChildren){}[0] + } } abstract interface app.cash.redwood.protocol.guest/ProtocolWidgetSystemFactory { // app.cash.redwood.protocol.guest/ProtocolWidgetSystemFactory|null[0] @@ -57,6 +37,34 @@ abstract interface app.cash.redwood.protocol.guest/ProtocolWidgetSystemFactory { abstract fun create(app.cash.redwood.protocol.guest/GuestProtocolAdapter, app.cash.redwood.protocol.guest/ProtocolMismatchHandler = ...): app.cash.redwood.widget/WidgetSystem // app.cash.redwood.protocol.guest/ProtocolWidgetSystemFactory.create|create(app.cash.redwood.protocol.guest.GuestProtocolAdapter;app.cash.redwood.protocol.guest.ProtocolMismatchHandler){}[0] } +abstract class app.cash.redwood.protocol.guest/GuestProtocolAdapter : app.cash.redwood.protocol/EventSink { // app.cash.redwood.protocol.guest/GuestProtocolAdapter|null[0] + constructor (app.cash.redwood.protocol/RedwoodVersion) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.|(app.cash.redwood.protocol.RedwoodVersion){}[0] + + abstract val json // app.cash.redwood.protocol.guest/GuestProtocolAdapter.json|{}json[0] + abstract fun (): kotlinx.serialization.json/Json // app.cash.redwood.protocol.guest/GuestProtocolAdapter.json.|(){}[0] + abstract val root // app.cash.redwood.protocol.guest/GuestProtocolAdapter.root|{}root[0] + abstract fun (): app.cash.redwood.widget/Widget.Children // app.cash.redwood.protocol.guest/GuestProtocolAdapter.root.|(){}[0] + abstract val widgetSystem // app.cash.redwood.protocol.guest/GuestProtocolAdapter.widgetSystem|{}widgetSystem[0] + abstract fun (): app.cash.redwood.widget/WidgetSystem // app.cash.redwood.protocol.guest/GuestProtocolAdapter.widgetSystem.|(){}[0] + final val childrenVisitor // app.cash.redwood.protocol.guest/GuestProtocolAdapter.childrenVisitor|{}childrenVisitor[0] + final fun (): app.cash.redwood.protocol.guest/ProtocolWidget.ChildrenVisitor // app.cash.redwood.protocol.guest/GuestProtocolAdapter.childrenVisitor.|(){}[0] + final val synthesizeSubtreeRemoval // app.cash.redwood.protocol.guest/GuestProtocolAdapter.synthesizeSubtreeRemoval|{}synthesizeSubtreeRemoval[0] + final fun (): kotlin/Boolean // app.cash.redwood.protocol.guest/GuestProtocolAdapter.synthesizeSubtreeRemoval.|(){}[0] + + abstract fun <#A1: kotlin/Any?> appendPropertyChange(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/PropertyTag, kotlinx.serialization/KSerializer<#A1>, #A1) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendPropertyChange|appendPropertyChange(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.PropertyTag;kotlinx.serialization.KSerializer<0:0>;0:0){0§}[0] + abstract fun appendAdd(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, app.cash.redwood.protocol.guest/ProtocolWidget) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendAdd|appendAdd(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;app.cash.redwood.protocol.guest.ProtocolWidget){}[0] + abstract fun appendCreate(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/WidgetTag) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendCreate|appendCreate(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.WidgetTag){}[0] + abstract fun appendModifierChange(app.cash.redwood.protocol/Id, app.cash.redwood/Modifier) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendModifierChange|appendModifierChange(app.cash.redwood.protocol.Id;app.cash.redwood.Modifier){}[0] + abstract fun appendMove(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, kotlin/Int, kotlin/Int) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendMove|appendMove(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;kotlin.Int;kotlin.Int){}[0] + abstract fun appendPropertyChange(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/PropertyTag, kotlin/Boolean) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendPropertyChange|appendPropertyChange(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.PropertyTag;kotlin.Boolean){}[0] + abstract fun appendPropertyChange(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/PropertyTag, kotlin/UInt) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendPropertyChange|appendPropertyChange(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.PropertyTag;kotlin.UInt){}[0] + abstract fun appendRemove(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, kotlin/Int, kotlin.collections/List) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.appendRemove|appendRemove(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;kotlin.Int;kotlin.collections.List){}[0] + abstract fun emitChanges() // app.cash.redwood.protocol.guest/GuestProtocolAdapter.emitChanges|emitChanges(){}[0] + abstract fun initChangesSink(app.cash.redwood.protocol/ChangesSink) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.initChangesSink|initChangesSink(app.cash.redwood.protocol.ChangesSink){}[0] + abstract fun nextId(): app.cash.redwood.protocol/Id // app.cash.redwood.protocol.guest/GuestProtocolAdapter.nextId|nextId(){}[0] + abstract fun removeWidget(app.cash.redwood.protocol/Id) // app.cash.redwood.protocol.guest/GuestProtocolAdapter.removeWidget|removeWidget(app.cash.redwood.protocol.Id){}[0] +} + final class app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter : app.cash.redwood.protocol.guest/GuestProtocolAdapter { // app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter|null[0] constructor (kotlinx.serialization.json/Json = ..., app.cash.redwood.protocol/RedwoodVersion, app.cash.redwood.protocol.guest/ProtocolWidgetSystemFactory, app.cash.redwood.protocol.guest/ProtocolMismatchHandler = ...) // app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter.|(kotlinx.serialization.json.Json;app.cash.redwood.protocol.RedwoodVersion;app.cash.redwood.protocol.guest.ProtocolWidgetSystemFactory;app.cash.redwood.protocol.guest.ProtocolMismatchHandler){}[0] @@ -64,8 +72,6 @@ final class app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter : app.ca final fun (): kotlinx.serialization.json/Json // app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter.json.|(){}[0] final val root // app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter.root|{}root[0] final fun (): app.cash.redwood.widget/Widget.Children // app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter.root.|(){}[0] - final val synthesizeSubtreeRemoval // app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter.synthesizeSubtreeRemoval|{}synthesizeSubtreeRemoval[0] - final fun (): kotlin/Boolean // app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter.synthesizeSubtreeRemoval.|(){}[0] final val widgetSystem // app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter.widgetSystem|{}widgetSystem[0] final fun (): app.cash.redwood.widget/WidgetSystem // app.cash.redwood.protocol.guest/DefaultGuestProtocolAdapter.widgetSystem.|(){}[0] @@ -91,7 +97,7 @@ final class app.cash.redwood.protocol.guest/ProtocolWidgetChildren : app.cash.re final val widgets // app.cash.redwood.protocol.guest/ProtocolWidgetChildren.widgets|{}widgets[0] final fun (): kotlin.collections/List // app.cash.redwood.protocol.guest/ProtocolWidgetChildren.widgets.|(){}[0] - final fun depthFirstWalk(app.cash.redwood.protocol.guest/ProtocolWidget, kotlin/Function3) // app.cash.redwood.protocol.guest/ProtocolWidgetChildren.depthFirstWalk|depthFirstWalk(app.cash.redwood.protocol.guest.ProtocolWidget;kotlin.Function3){}[0] + final fun depthFirstWalk(app.cash.redwood.protocol.guest/ProtocolWidget, app.cash.redwood.protocol.guest/ProtocolWidget.ChildrenVisitor) // app.cash.redwood.protocol.guest/ProtocolWidgetChildren.depthFirstWalk|depthFirstWalk(app.cash.redwood.protocol.guest.ProtocolWidget;app.cash.redwood.protocol.guest.ProtocolWidget.ChildrenVisitor){}[0] final fun detach() // app.cash.redwood.protocol.guest/ProtocolWidgetChildren.detach|detach(){}[0] final fun insert(kotlin/Int, app.cash.redwood.widget/Widget) // app.cash.redwood.protocol.guest/ProtocolWidgetChildren.insert|insert(kotlin.Int;app.cash.redwood.widget.Widget){}[0] final fun move(kotlin/Int, kotlin/Int, kotlin/Int) // app.cash.redwood.protocol.guest/ProtocolWidgetChildren.move|move(kotlin.Int;kotlin.Int;kotlin.Int){}[0] @@ -100,10 +106,12 @@ final class app.cash.redwood.protocol.guest/ProtocolWidgetChildren : app.cash.re } final val app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_DefaultGuestProtocolAdapter$stableprop // app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_DefaultGuestProtocolAdapter$stableprop|#static{}app_cash_redwood_protocol_guest_DefaultGuestProtocolAdapter$stableprop[0] +final val app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_GuestProtocolAdapter$stableprop // app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_GuestProtocolAdapter$stableprop|#static{}app_cash_redwood_protocol_guest_GuestProtocolAdapter$stableprop[0] final val app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_ProtocolWidgetChildren$stableprop // app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_ProtocolWidgetChildren$stableprop|#static{}app_cash_redwood_protocol_guest_ProtocolWidgetChildren$stableprop[0] final val app.cash.redwood.protocol.guest/guestRedwoodVersion // app.cash.redwood.protocol.guest/guestRedwoodVersion|{}guestRedwoodVersion[0] final fun (): app.cash.redwood.protocol/RedwoodVersion // app.cash.redwood.protocol.guest/guestRedwoodVersion.|(){}[0] final fun app.cash.redwood.protocol.guest/ProtocolRedwoodComposition(kotlinx.coroutines/CoroutineScope, app.cash.redwood.protocol.guest/GuestProtocolAdapter, kotlin/UInt, app.cash.redwood.ui/OnBackPressedDispatcher, androidx.compose.runtime.saveable/SaveableStateRegistry?, kotlinx.coroutines.flow/StateFlow, kotlin/Function0 = ...): app.cash.redwood.compose/RedwoodComposition // app.cash.redwood.protocol.guest/ProtocolRedwoodComposition|ProtocolRedwoodComposition(kotlinx.coroutines.CoroutineScope;app.cash.redwood.protocol.guest.GuestProtocolAdapter;kotlin.UInt;app.cash.redwood.ui.OnBackPressedDispatcher;androidx.compose.runtime.saveable.SaveableStateRegistry?;kotlinx.coroutines.flow.StateFlow;kotlin.Function0){}[0] final fun app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_DefaultGuestProtocolAdapter$stableprop_getter(): kotlin/Int // app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_DefaultGuestProtocolAdapter$stableprop_getter|app_cash_redwood_protocol_guest_DefaultGuestProtocolAdapter$stableprop_getter(){}[0] +final fun app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_GuestProtocolAdapter$stableprop_getter(): kotlin/Int // app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_GuestProtocolAdapter$stableprop_getter|app_cash_redwood_protocol_guest_GuestProtocolAdapter$stableprop_getter(){}[0] final fun app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_ProtocolWidgetChildren$stableprop_getter(): kotlin/Int // app.cash.redwood.protocol.guest/app_cash_redwood_protocol_guest_ProtocolWidgetChildren$stableprop_getter|app_cash_redwood_protocol_guest_ProtocolWidgetChildren$stableprop_getter(){}[0] diff --git a/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/DefaultGuestProtocolAdapter.kt b/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/DefaultGuestProtocolAdapter.kt index a5c5b70ced..022e28d004 100644 --- a/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/DefaultGuestProtocolAdapter.kt +++ b/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/DefaultGuestProtocolAdapter.kt @@ -44,7 +44,7 @@ public class DefaultGuestProtocolAdapter( hostVersion: RedwoodVersion, private val widgetSystemFactory: ProtocolWidgetSystemFactory, private val mismatchHandler: ProtocolMismatchHandler = ProtocolMismatchHandler.Throwing, -) : GuestProtocolAdapter { +) : GuestProtocolAdapter(hostVersion) { private var nextValue = Id.Root.value + 1 private val widgets = mutableMapOf() private val changes = mutableListOf() @@ -56,8 +56,6 @@ public class DefaultGuestProtocolAdapter( public override val root: Widget.Children = ProtocolWidgetChildren(Id.Root, ChildrenTag.Root, this) - public override val synthesizeSubtreeRemoval: Boolean = hostVersion < RedwoodVersion("0.10.0-SNAPSHOT") - override fun sendEvent(event: Event) { val node = widgets[event.id.value] if (node != null) { diff --git a/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/GuestProtocolAdapter.kt b/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/GuestProtocolAdapter.kt index 40300dbda1..7f76c8f3fb 100644 --- a/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/GuestProtocolAdapter.kt +++ b/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/GuestProtocolAdapter.kt @@ -22,6 +22,7 @@ import app.cash.redwood.protocol.ChildrenTag import app.cash.redwood.protocol.EventSink import app.cash.redwood.protocol.Id import app.cash.redwood.protocol.PropertyTag +import app.cash.redwood.protocol.RedwoodVersion import app.cash.redwood.protocol.WidgetTag import app.cash.redwood.widget.Widget import app.cash.redwood.widget.WidgetSystem @@ -36,9 +37,11 @@ import kotlinx.serialization.json.Json * * This interface is for generated code use only. */ -public interface GuestProtocolAdapter : EventSink { +public abstract class GuestProtocolAdapter( + hostVersion: RedwoodVersion, +) : EventSink { @RedwoodCodegenApi - public val json: Json + public abstract val json: Json /** * Host versions prior to 0.10.0 contained a bug where they did not recursively remove widgets @@ -46,36 +49,36 @@ public interface GuestProtocolAdapter : EventSink { * on the guest side by synthesizing removes for every node in the subtree. */ @RedwoodCodegenApi - public val synthesizeSubtreeRemoval: Boolean + public val synthesizeSubtreeRemoval: Boolean = hostVersion < RedwoodVersion("0.10.0-SNAPSHOT") /** * The provider of factories of widgets which record property changes and whose children changes * are also recorded. You **must** attach returned widgets to [root] or the children of a widget * in the tree beneath [root] in order for it to be tracked. */ - public val widgetSystem: WidgetSystem + public abstract val widgetSystem: WidgetSystem /** * The root of the widget tree onto which [widgetSystem]-produced widgets can be added. Changes to * this instance are recorded as changes to [Id.Root] and [ChildrenTag.Root]. */ - public val root: Widget.Children + public abstract val root: Widget.Children - public fun initChangesSink(changesSink: ChangesSink) + public abstract fun initChangesSink(changesSink: ChangesSink) - public fun emitChanges() + public abstract fun emitChanges() @RedwoodCodegenApi - public fun nextId(): Id + public abstract fun nextId(): Id @RedwoodCodegenApi - public fun appendCreate( + public abstract fun appendCreate( id: Id, tag: WidgetTag, ) @RedwoodCodegenApi - public fun appendPropertyChange( + public abstract fun appendPropertyChange( id: Id, tag: PropertyTag, serializer: KSerializer, @@ -83,7 +86,7 @@ public interface GuestProtocolAdapter : EventSink { ) @RedwoodCodegenApi - public fun appendPropertyChange( + public abstract fun appendPropertyChange( id: Id, tag: PropertyTag, value: Boolean, @@ -97,20 +100,20 @@ public interface GuestProtocolAdapter : EventSink { * https://github.com/Kotlin/kotlinx.serialization/issues/2713 */ @RedwoodCodegenApi - public fun appendPropertyChange( + public abstract fun appendPropertyChange( id: Id, tag: PropertyTag, value: UInt, ) @RedwoodCodegenApi - public fun appendModifierChange( + public abstract fun appendModifierChange( id: Id, value: Modifier, ) @RedwoodCodegenApi - public fun appendAdd( + public abstract fun appendAdd( id: Id, tag: ChildrenTag, index: Int, @@ -118,7 +121,7 @@ public interface GuestProtocolAdapter : EventSink { ) @RedwoodCodegenApi - public fun appendMove( + public abstract fun appendMove( id: Id, tag: ChildrenTag, fromIndex: Int, @@ -127,14 +130,44 @@ public interface GuestProtocolAdapter : EventSink { ) @RedwoodCodegenApi - public fun appendRemove( + public abstract fun appendRemove( id: Id, tag: ChildrenTag, index: Int, count: Int, - removedIds: List = listOf(), + removedIds: List, ) @RedwoodCodegenApi - public fun removeWidget(id: Id) + public abstract fun removeWidget(id: Id) + + @RedwoodCodegenApi + public val childrenVisitor: ProtocolWidget.ChildrenVisitor = if (synthesizeSubtreeRemoval) { + object : ProtocolWidget.ChildrenVisitor { + override fun visit( + parent: ProtocolWidget, + childrenTag: ChildrenTag, + children: ProtocolWidgetChildren, + ) { + // This boxes Id values. Don't bother optimizing since it only serves very old hosts. + val childIds = children.widgets.map(ProtocolWidget::id) + for (childId in childIds) { + removeWidget(childId) + } + appendRemove(parent.id, childrenTag, 0, childIds.size, childIds) + } + } + } else { + object : ProtocolWidget.ChildrenVisitor { + override fun visit( + parent: ProtocolWidget, + childrenTag: ChildrenTag, + children: ProtocolWidgetChildren, + ) { + for (childWidget in children.widgets) { + removeWidget(childWidget.id) + } + } + } + } } diff --git a/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/ProtocolWidget.kt b/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/ProtocolWidget.kt index eae496ceb5..e3c51ab756 100644 --- a/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/ProtocolWidget.kt +++ b/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/ProtocolWidget.kt @@ -57,17 +57,19 @@ public interface ProtocolWidget : Widget { * } * } * ``` - * You will see the following argument values passed to [block] if invoked on the `Split`: + * You will see the following argument values passed to [visitor] if invoked on the `Split`: * 1. parent: `Row`, childrenTag: 1, children: `[Text+Button]` * 2. parent: `Split`, childrenTag: 1, children: `[Row]` * 3. parent: `Column`, childrenTag: 1, children: `[Button+Text]` * 4. parent: `Split`, childrenTag: 2, children: `[Column]` */ - public fun depthFirstWalk( - block: ( + public fun depthFirstWalk(visitor: ChildrenVisitor) + + public fun interface ChildrenVisitor { + public fun visit( parent: ProtocolWidget, childrenTag: ChildrenTag, children: ProtocolWidgetChildren, - ) -> Unit, - ) + ) + } } diff --git a/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/ProtocolWidgetChildren.kt b/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/ProtocolWidgetChildren.kt index 8ebb49809b..8c9432679e 100644 --- a/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/ProtocolWidgetChildren.kt +++ b/redwood-protocol-guest/src/commonMain/kotlin/app/cash/redwood/protocol/guest/ProtocolWidgetChildren.kt @@ -38,32 +38,23 @@ public class ProtocolWidgetChildren( override fun remove(index: Int, count: Int) { if (guestAdapter.synthesizeSubtreeRemoval) { + // This boxes Id values. Don't bother optimizing since it only serves very old hosts. val removedIds = ArrayList(count) for (i in index until index + count) { val widget = _widgets[i] removedIds += widget.id guestAdapter.removeWidget(widget.id) - widget.depthFirstWalk { parent, childrenTag, children -> - val childIds = children.widgets.map(ProtocolWidget::id) - for (childId in childIds) { - guestAdapter.removeWidget(childId) - } - guestAdapter.appendRemove(parent.id, childrenTag, 0, childIds.size, childIds) - } + widget.depthFirstWalk(guestAdapter.childrenVisitor) } guestAdapter.appendRemove(id, tag, index, count, removedIds) } else { for (i in index until index + count) { val widget = _widgets[i] guestAdapter.removeWidget(widget.id) - widget.depthFirstWalk { _, _, children -> - for (childWidget in children.widgets) { - guestAdapter.removeWidget(childWidget.id) - } - } + widget.depthFirstWalk(guestAdapter.childrenVisitor) } - guestAdapter.appendRemove(id, tag, index, count) + guestAdapter.appendRemove(id, tag, index, count, emptyList()) } _widgets.remove(index, count) @@ -79,12 +70,12 @@ public class ProtocolWidgetChildren( public fun depthFirstWalk( parent: ProtocolWidget, - block: (ProtocolWidget, ChildrenTag, ProtocolWidgetChildren) -> Unit, + visitor: ProtocolWidget.ChildrenVisitor, ) { for (widget in widgets) { - widget.depthFirstWalk(block) + widget.depthFirstWalk(visitor) } - block(parent, tag, this) + visitor.visit(parent, tag, this) } override fun detach() { diff --git a/redwood-protocol/api/redwood-protocol.api b/redwood-protocol/api/redwood-protocol.api index 2a01e7f9a5..1f835c9bc7 100644 --- a/redwood-protocol/api/redwood-protocol.api +++ b/redwood-protocol/api/redwood-protocol.api @@ -40,6 +40,7 @@ public synthetic class app/cash/redwood/protocol/ChildrenChange$Add$$serializer } public final class app/cash/redwood/protocol/ChildrenChange$Add$Companion { + public final fun invoke-11bgaWM (IIII)Lapp/cash/redwood/protocol/ChildrenChange$Add; public final fun serializer ()Lkotlinx/serialization/KSerializer; } @@ -72,12 +73,12 @@ public synthetic class app/cash/redwood/protocol/ChildrenChange$Move$$serializer } public final class app/cash/redwood/protocol/ChildrenChange$Move$Companion { + public final fun invoke-HpxY78w (IIIII)Lapp/cash/redwood/protocol/ChildrenChange$Move; public final fun serializer ()Lkotlinx/serialization/KSerializer; } public final class app/cash/redwood/protocol/ChildrenChange$Remove : app/cash/redwood/protocol/ChildrenChange { public static final field Companion Lapp/cash/redwood/protocol/ChildrenChange$Remove$Companion; - public synthetic fun (IIIILjava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun (IIIILjava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun equals (Ljava/lang/Object;)Z public final fun getCount ()I @@ -101,6 +102,8 @@ public synthetic class app/cash/redwood/protocol/ChildrenChange$Remove$$serializ } public final class app/cash/redwood/protocol/ChildrenChange$Remove$Companion { + public final fun invoke-HpxY78w (IIIILjava/util/List;)Lapp/cash/redwood/protocol/ChildrenChange$Remove; + public static synthetic fun invoke-HpxY78w$default (Lapp/cash/redwood/protocol/ChildrenChange$Remove$Companion;IIIILjava/util/List;ILjava/lang/Object;)Lapp/cash/redwood/protocol/ChildrenChange$Remove; public final fun serializer ()Lkotlinx/serialization/KSerializer; } @@ -157,12 +160,12 @@ public synthetic class app/cash/redwood/protocol/Create$$serializer : kotlinx/se } public final class app/cash/redwood/protocol/Create$Companion { + public final fun invoke-kyz2zXs (II)Lapp/cash/redwood/protocol/Create; public final fun serializer ()Lkotlinx/serialization/KSerializer; } public final class app/cash/redwood/protocol/Event { public static final field Companion Lapp/cash/redwood/protocol/Event$Companion; - public synthetic fun (IILjava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun (IILjava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun equals (Ljava/lang/Object;)Z public final fun getArgs ()Ljava/util/List; @@ -184,6 +187,8 @@ public synthetic class app/cash/redwood/protocol/Event$$serializer : kotlinx/ser } public final class app/cash/redwood/protocol/Event$Companion { + public final fun invoke-OtSvs1c (IILjava/util/List;)Lapp/cash/redwood/protocol/Event; + public static synthetic fun invoke-OtSvs1c$default (Lapp/cash/redwood/protocol/Event$Companion;IILjava/util/List;ILjava/lang/Object;)Lapp/cash/redwood/protocol/Event; public final fun serializer ()Lkotlinx/serialization/KSerializer; } @@ -254,7 +259,6 @@ public final class app/cash/redwood/protocol/Id$Companion { public final class app/cash/redwood/protocol/ModifierChange : app/cash/redwood/protocol/ValueChange { public static final field Companion Lapp/cash/redwood/protocol/ModifierChange$Companion; - public synthetic fun (ILjava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun (ILjava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun equals (Ljava/lang/Object;)Z public final fun getElements ()Ljava/util/List; @@ -275,6 +279,8 @@ public synthetic class app/cash/redwood/protocol/ModifierChange$$serializer : ko } public final class app/cash/redwood/protocol/ModifierChange$Companion { + public final fun invoke-z3jyS0k (ILjava/util/List;)Lapp/cash/redwood/protocol/ModifierChange; + public static synthetic fun invoke-z3jyS0k$default (Lapp/cash/redwood/protocol/ModifierChange$Companion;ILjava/util/List;ILjava/lang/Object;)Lapp/cash/redwood/protocol/ModifierChange; public final fun serializer ()Lkotlinx/serialization/KSerializer; } @@ -320,7 +326,6 @@ public final class app/cash/redwood/protocol/ModifierTag$Companion { public final class app/cash/redwood/protocol/PropertyChange : app/cash/redwood/protocol/ValueChange { public static final field Companion Lapp/cash/redwood/protocol/PropertyChange$Companion; - public synthetic fun (IILkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun (IILkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun equals (Ljava/lang/Object;)Z public fun getId-0HhLjSo ()I @@ -342,6 +347,8 @@ public synthetic class app/cash/redwood/protocol/PropertyChange$$serializer : ko } public final class app/cash/redwood/protocol/PropertyChange$Companion { + public final fun invoke-e3iP1vo (IILkotlinx/serialization/json/JsonElement;)Lapp/cash/redwood/protocol/PropertyChange; + public static synthetic fun invoke-e3iP1vo$default (Lapp/cash/redwood/protocol/PropertyChange$Companion;IILkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lapp/cash/redwood/protocol/PropertyChange; public final fun serializer ()Lkotlinx/serialization/KSerializer; } diff --git a/redwood-protocol/api/redwood-protocol.klib.api b/redwood-protocol/api/redwood-protocol.klib.api index 9caf13558c..bb8f72c667 100644 --- a/redwood-protocol/api/redwood-protocol.klib.api +++ b/redwood-protocol/api/redwood-protocol.klib.api @@ -29,8 +29,6 @@ sealed interface app.cash.redwood.protocol/ChildrenChange : app.cash.redwood.pro abstract fun (): app.cash.redwood.protocol/ChildrenTag // app.cash.redwood.protocol/ChildrenChange.tag.|(){}[0] final class Add : app.cash.redwood.protocol/ChildrenChange { // app.cash.redwood.protocol/ChildrenChange.Add|null[0] - constructor (app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, app.cash.redwood.protocol/Id, kotlin/Int) // app.cash.redwood.protocol/ChildrenChange.Add.|(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;app.cash.redwood.protocol.Id;kotlin.Int){}[0] - final val childId // app.cash.redwood.protocol/ChildrenChange.Add.childId|{}childId[0] final fun (): app.cash.redwood.protocol/Id // app.cash.redwood.protocol/ChildrenChange.Add.childId.|(){}[0] final val id // app.cash.redwood.protocol/ChildrenChange.Add.id|{}id[0] @@ -54,13 +52,12 @@ sealed interface app.cash.redwood.protocol/ChildrenChange : app.cash.redwood.pro } final object Companion { // app.cash.redwood.protocol/ChildrenChange.Add.Companion|null[0] + final fun invoke(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, app.cash.redwood.protocol/Id, kotlin/Int): app.cash.redwood.protocol/ChildrenChange.Add // app.cash.redwood.protocol/ChildrenChange.Add.Companion.invoke|invoke(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;app.cash.redwood.protocol.Id;kotlin.Int){}[0] final fun serializer(): kotlinx.serialization/KSerializer // app.cash.redwood.protocol/ChildrenChange.Add.Companion.serializer|serializer(){}[0] } } final class Move : app.cash.redwood.protocol/ChildrenChange { // app.cash.redwood.protocol/ChildrenChange.Move|null[0] - constructor (app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, kotlin/Int, kotlin/Int) // app.cash.redwood.protocol/ChildrenChange.Move.|(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;kotlin.Int;kotlin.Int){}[0] - final val count // app.cash.redwood.protocol/ChildrenChange.Move.count|{}count[0] final fun (): kotlin/Int // app.cash.redwood.protocol/ChildrenChange.Move.count.|(){}[0] final val fromIndex // app.cash.redwood.protocol/ChildrenChange.Move.fromIndex|{}fromIndex[0] @@ -86,13 +83,12 @@ sealed interface app.cash.redwood.protocol/ChildrenChange : app.cash.redwood.pro } final object Companion { // app.cash.redwood.protocol/ChildrenChange.Move.Companion|null[0] + final fun invoke(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, kotlin/Int, kotlin/Int): app.cash.redwood.protocol/ChildrenChange.Move // app.cash.redwood.protocol/ChildrenChange.Move.Companion.invoke|invoke(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;kotlin.Int;kotlin.Int){}[0] final fun serializer(): kotlinx.serialization/KSerializer // app.cash.redwood.protocol/ChildrenChange.Move.Companion.serializer|serializer(){}[0] } } final class Remove : app.cash.redwood.protocol/ChildrenChange { // app.cash.redwood.protocol/ChildrenChange.Remove|null[0] - constructor (app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, kotlin/Int, kotlin.collections/List = ...) // app.cash.redwood.protocol/ChildrenChange.Remove.|(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;kotlin.Int;kotlin.collections.List){}[0] - final val count // app.cash.redwood.protocol/ChildrenChange.Remove.count|{}count[0] final fun (): kotlin/Int // app.cash.redwood.protocol/ChildrenChange.Remove.count.|(){}[0] final val id // app.cash.redwood.protocol/ChildrenChange.Remove.id|{}id[0] @@ -120,6 +116,7 @@ sealed interface app.cash.redwood.protocol/ChildrenChange : app.cash.redwood.pro final object Companion { // app.cash.redwood.protocol/ChildrenChange.Remove.Companion|null[0] final val $childSerializers // app.cash.redwood.protocol/ChildrenChange.Remove.Companion.$childSerializers|{}$childSerializers[0] + final fun invoke(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/ChildrenTag, kotlin/Int, kotlin/Int, kotlin.collections/List = ...): app.cash.redwood.protocol/ChildrenChange.Remove // app.cash.redwood.protocol/ChildrenChange.Remove.Companion.invoke|invoke(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.ChildrenTag;kotlin.Int;kotlin.Int;kotlin.collections.List){}[0] final fun serializer(): kotlinx.serialization/KSerializer // app.cash.redwood.protocol/ChildrenChange.Remove.Companion.serializer|serializer(){}[0] } } @@ -133,8 +130,6 @@ sealed interface app.cash.redwood.protocol/ChildrenChange : app.cash.redwood.pro sealed interface app.cash.redwood.protocol/ValueChange : app.cash.redwood.protocol/Change // app.cash.redwood.protocol/ValueChange|null[0] final class app.cash.redwood.protocol/Create : app.cash.redwood.protocol/Change { // app.cash.redwood.protocol/Create|null[0] - constructor (app.cash.redwood.protocol/Id, app.cash.redwood.protocol/WidgetTag) // app.cash.redwood.protocol/Create.|(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.WidgetTag){}[0] - final val id // app.cash.redwood.protocol/Create.id|{}id[0] final fun (): app.cash.redwood.protocol/Id // app.cash.redwood.protocol/Create.id.|(){}[0] final val tag // app.cash.redwood.protocol/Create.tag|{}tag[0] @@ -154,13 +149,12 @@ final class app.cash.redwood.protocol/Create : app.cash.redwood.protocol/Change } final object Companion { // app.cash.redwood.protocol/Create.Companion|null[0] + final fun invoke(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/WidgetTag): app.cash.redwood.protocol/Create // app.cash.redwood.protocol/Create.Companion.invoke|invoke(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.WidgetTag){}[0] final fun serializer(): kotlinx.serialization/KSerializer // app.cash.redwood.protocol/Create.Companion.serializer|serializer(){}[0] } } final class app.cash.redwood.protocol/Event { // app.cash.redwood.protocol/Event|null[0] - constructor (app.cash.redwood.protocol/Id, app.cash.redwood.protocol/EventTag, kotlin.collections/List = ...) // app.cash.redwood.protocol/Event.|(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.EventTag;kotlin.collections.List){}[0] - final val args // app.cash.redwood.protocol/Event.args|{}args[0] final fun (): kotlin.collections/List // app.cash.redwood.protocol/Event.args.|(){}[0] final val id // app.cash.redwood.protocol/Event.id|{}id[0] @@ -184,13 +178,12 @@ final class app.cash.redwood.protocol/Event { // app.cash.redwood.protocol/Event final object Companion { // app.cash.redwood.protocol/Event.Companion|null[0] final val $childSerializers // app.cash.redwood.protocol/Event.Companion.$childSerializers|{}$childSerializers[0] + final fun invoke(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/EventTag, kotlin.collections/List = ...): app.cash.redwood.protocol/Event // app.cash.redwood.protocol/Event.Companion.invoke|invoke(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.EventTag;kotlin.collections.List){}[0] final fun serializer(): kotlinx.serialization/KSerializer // app.cash.redwood.protocol/Event.Companion.serializer|serializer(){}[0] } } final class app.cash.redwood.protocol/ModifierChange : app.cash.redwood.protocol/ValueChange { // app.cash.redwood.protocol/ModifierChange|null[0] - constructor (app.cash.redwood.protocol/Id, kotlin.collections/List = ...) // app.cash.redwood.protocol/ModifierChange.|(app.cash.redwood.protocol.Id;kotlin.collections.List){}[0] - final val elements // app.cash.redwood.protocol/ModifierChange.elements|{}elements[0] final fun (): kotlin.collections/List // app.cash.redwood.protocol/ModifierChange.elements.|(){}[0] final val id // app.cash.redwood.protocol/ModifierChange.id|{}id[0] @@ -212,6 +205,7 @@ final class app.cash.redwood.protocol/ModifierChange : app.cash.redwood.protocol final object Companion { // app.cash.redwood.protocol/ModifierChange.Companion|null[0] final val $childSerializers // app.cash.redwood.protocol/ModifierChange.Companion.$childSerializers|{}$childSerializers[0] + final fun invoke(app.cash.redwood.protocol/Id, kotlin.collections/List = ...): app.cash.redwood.protocol/ModifierChange // app.cash.redwood.protocol/ModifierChange.Companion.invoke|invoke(app.cash.redwood.protocol.Id;kotlin.collections.List){}[0] final fun serializer(): kotlinx.serialization/KSerializer // app.cash.redwood.protocol/ModifierChange.Companion.serializer|serializer(){}[0] } } @@ -230,8 +224,6 @@ final class app.cash.redwood.protocol/ModifierElement { // app.cash.redwood.prot } final class app.cash.redwood.protocol/PropertyChange : app.cash.redwood.protocol/ValueChange { // app.cash.redwood.protocol/PropertyChange|null[0] - constructor (app.cash.redwood.protocol/Id, app.cash.redwood.protocol/PropertyTag, kotlinx.serialization.json/JsonElement = ...) // app.cash.redwood.protocol/PropertyChange.|(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.PropertyTag;kotlinx.serialization.json.JsonElement){}[0] - final val id // app.cash.redwood.protocol/PropertyChange.id|{}id[0] final fun (): app.cash.redwood.protocol/Id // app.cash.redwood.protocol/PropertyChange.id.|(){}[0] final val tag // app.cash.redwood.protocol/PropertyChange.tag|{}tag[0] @@ -253,6 +245,7 @@ final class app.cash.redwood.protocol/PropertyChange : app.cash.redwood.protocol } final object Companion { // app.cash.redwood.protocol/PropertyChange.Companion|null[0] + final fun invoke(app.cash.redwood.protocol/Id, app.cash.redwood.protocol/PropertyTag, kotlinx.serialization.json/JsonElement = ...): app.cash.redwood.protocol/PropertyChange // app.cash.redwood.protocol/PropertyChange.Companion.invoke|invoke(app.cash.redwood.protocol.Id;app.cash.redwood.protocol.PropertyTag;kotlinx.serialization.json.JsonElement){}[0] final fun serializer(): kotlinx.serialization/KSerializer // app.cash.redwood.protocol/PropertyChange.Companion.serializer|serializer(){}[0] } } diff --git a/redwood-protocol/src/commonMain/kotlin/app/cash/redwood/protocol/protocol.kt b/redwood-protocol/src/commonMain/kotlin/app/cash/redwood/protocol/protocol.kt index 062ba276ad..a9ed1836de 100644 --- a/redwood-protocol/src/commonMain/kotlin/app/cash/redwood/protocol/protocol.kt +++ b/redwood-protocol/src/commonMain/kotlin/app/cash/redwood/protocol/protocol.kt @@ -33,15 +33,35 @@ import kotlinx.serialization.json.buildJsonArray import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonPrimitive +/* +Note: The types in this file are written in a careful way such that their serializable properties +are scalars which can be serialized directly rather than using value classes are boxed within the +generated kotlinx.serialization code. +*/ + @Serializable @Poko -public class Event( +public class Event private constructor( + @SerialName("id") + private val _id: Int, + @SerialName("tag") + private val _tag: Int, + public val args: List = emptyList(), +) { /** Identifier for the widget from which this event originated. */ - public val id: Id, + public val id: Id get() = Id(_id) + /** Identifies which event occurred on the widget with [id]. */ - public val tag: EventTag, - public val args: List = emptyList(), -) + public val tag: EventTag get() = EventTag(_tag) + + public companion object { + public operator fun invoke( + id: Id, + tag: EventTag, + args: List = emptyList(), + ): Event = Event(id.value, tag.value, args) + } +} @Serializable public sealed interface Change { @@ -52,30 +72,67 @@ public sealed interface Change { @Serializable @SerialName("create") @Poko -public class Create( - override val id: Id, - public val tag: WidgetTag, -) : Change +public class Create private constructor( + @SerialName("id") + private val _id: Int, + @SerialName("tag") + private val _tag: Int, +) : Change { + override val id: Id get() = Id(_id) + public val tag: WidgetTag get() = WidgetTag(_tag) + + public companion object { + public operator fun invoke( + id: Id, + tag: WidgetTag, + ): Create = Create(id.value, tag.value) + } +} public sealed interface ValueChange : Change @Serializable @SerialName("property") @Poko -public class PropertyChange( - override val id: Id, - /** Identifies which property changed on the widget with [id]. */ - public val tag: PropertyTag, +public class PropertyChange private constructor( + @SerialName("id") + private val _id: Int, + @SerialName("tag") + private val _tag: Int, public val value: JsonElement = JsonNull, -) : ValueChange +) : ValueChange { + override val id: Id get() = Id(_id) + + /** Identifies which property changed on the widget with [id]. */ + public val tag: PropertyTag get() = PropertyTag(_tag) + + public companion object { + public operator fun invoke( + id: Id, + /** Identifies which property changed on the widget with [id]. */ + tag: PropertyTag, + value: JsonElement = JsonNull, + ): PropertyChange = PropertyChange(id.value, tag.value, value) + } +} @Serializable @SerialName("modifier") @Poko -public class ModifierChange( - override val id: Id, +public class ModifierChange private constructor( + @SerialName("id") + private val _id: Int, public val elements: List = emptyList(), -) : ValueChange +) : ValueChange { + override val id: Id get() = Id(_id) + + public companion object { + public operator fun invoke( + id: Id, + elements: List = emptyList(), + ): ModifierChange = ModifierChange(id.value, elements) + } +} @Serializable(with = ModifierElementSerializer::class) @Poko @@ -126,34 +183,80 @@ public sealed interface ChildrenChange : Change { @Serializable @SerialName("add") @Poko - public class Add( - override val id: Id, - override val tag: ChildrenTag, - public val childId: Id, + public class Add private constructor( + @SerialName("id") + private val _id: Int, + @SerialName("tag") + private val _tag: Int, + @SerialName("childId") + private val _childId: Int, public val index: Int, - ) : ChildrenChange + ) : ChildrenChange { + override val id: Id get() = Id(_id) + override val tag: ChildrenTag get() = ChildrenTag(_tag) + public val childId: Id get() = Id(_childId) + + public companion object { + public operator fun invoke( + id: Id, + tag: ChildrenTag, + childId: Id, + index: Int, + ): Add = Add(id.value, tag.value, childId.value, index) + } + } @Serializable @SerialName("move") @Poko - public class Move( - override val id: Id, - override val tag: ChildrenTag, + public class Move private constructor( + @SerialName("id") + private val _id: Int, + @SerialName("tag") + private val _tag: Int, public val fromIndex: Int, public val toIndex: Int, public val count: Int, - ) : ChildrenChange + ) : ChildrenChange { + override val id: Id get() = Id(_id) + override val tag: ChildrenTag get() = ChildrenTag(_tag) + + public companion object { + public operator fun invoke( + id: Id, + tag: ChildrenTag, + fromIndex: Int, + toIndex: Int, + count: Int, + ): Move = Move(id.value, tag.value, fromIndex, toIndex, count) + } + } @Serializable @SerialName("remove") @Poko - public class Remove( - override val id: Id, - override val tag: ChildrenTag, + public class Remove private constructor( + @SerialName("id") + private val _id: Int, + @SerialName("tag") + private val _tag: Int, public val index: Int, public val count: Int, // TODO Remove this for Redwood 1.0.0. @Deprecated("Only sent for compatibility with old hosts. Do not consume.", level = ERROR) public val removedIds: List = emptyList(), - ) : ChildrenChange + ) : ChildrenChange { + override val id: Id get() = Id(_id) + override val tag: ChildrenTag get() = ChildrenTag(_tag) + + public companion object { + public operator fun invoke( + id: Id, + tag: ChildrenTag, + index: Int, + count: Int, + removedIds: List = emptyList(), + ): Remove = Remove(id.value, tag.value, index, count, removedIds) + } + } } diff --git a/redwood-protocol/src/commonTest/kotlin/app/cash/redwood/protocol/SnapshotChangeListTest.kt b/redwood-protocol/src/commonTest/kotlin/app/cash/redwood/protocol/SnapshotChangeListTest.kt index 8bdcf34b2b..be853ddde7 100644 --- a/redwood-protocol/src/commonTest/kotlin/app/cash/redwood/protocol/SnapshotChangeListTest.kt +++ b/redwood-protocol/src/commonTest/kotlin/app/cash/redwood/protocol/SnapshotChangeListTest.kt @@ -70,8 +70,8 @@ class SnapshotChangeListTest { |Snapshot change list cannot contain move or remove operations | |Found: - | - Move(id=Id(value=0), tag=ChildrenTag(value=1), fromIndex=1, toIndex=2, count=3) - | - Remove(id=Id(value=0), tag=ChildrenTag(value=1), index=1, count=2, removedIds=[Id(value=3), Id(value=4)]) + | - Move(_id=0, _tag=1, fromIndex=1, toIndex=2, count=3) + | - Remove(_id=0, _tag=1, index=1, count=2, removedIds=[Id(value=3), Id(value=4)]) """.trimMargin(), ) } diff --git a/redwood-tooling-codegen/src/main/kotlin/app/cash/redwood/tooling/codegen/protocolGuestGeneration.kt b/redwood-tooling-codegen/src/main/kotlin/app/cash/redwood/tooling/codegen/protocolGuestGeneration.kt index 17413cdac9..7342a6d658 100644 --- a/redwood-tooling-codegen/src/main/kotlin/app/cash/redwood/tooling/codegen/protocolGuestGeneration.kt +++ b/redwood-tooling-codegen/src/main/kotlin/app/cash/redwood/tooling/codegen/protocolGuestGeneration.kt @@ -40,7 +40,6 @@ import com.squareup.kotlinpoet.KModifier.OVERRIDE import com.squareup.kotlinpoet.KModifier.PRIVATE import com.squareup.kotlinpoet.KModifier.PUBLIC import com.squareup.kotlinpoet.LONG -import com.squareup.kotlinpoet.LambdaTypeName import com.squareup.kotlinpoet.MemberName import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import com.squareup.kotlinpoet.PropertySpec @@ -429,26 +428,17 @@ internal fun generateProtocolWidget( .addFunction( FunSpec.builder("depthFirstWalk") .addModifiers(OVERRIDE) - .addParameter( - "block", - LambdaTypeName.get( - null, - ProtocolGuest.ProtocolWidget, - Protocol.ChildrenTag, - ProtocolGuest.ProtocolWidgetChildren, - returnType = UNIT, - ), - ) + .addParameter("visitor", ProtocolGuest.ProtocolWidgetChildrenVisitor) .apply { for (trait in widget.traits) { if (trait is ProtocolChildren) { if (workAroundLazyListPlaceholderRemoveCrash(widget, trait)) { addComment("Work around the LazyList.placeholder remove crash.") beginControlFlow("if (!guestAdapter.synthesizeSubtreeRemoval)") - addStatement("%N.depthFirstWalk(this, block)", trait.name) + addStatement("%N.depthFirstWalk(this, visitor)", trait.name) endControlFlow() } else { - addStatement("%N.depthFirstWalk(this, block)", trait.name) + addStatement("%N.depthFirstWalk(this, visitor)", trait.name) } } } diff --git a/redwood-tooling-codegen/src/main/kotlin/app/cash/redwood/tooling/codegen/types.kt b/redwood-tooling-codegen/src/main/kotlin/app/cash/redwood/tooling/codegen/types.kt index 69e94c29d7..b85ff8a231 100644 --- a/redwood-tooling-codegen/src/main/kotlin/app/cash/redwood/tooling/codegen/types.kt +++ b/redwood-tooling-codegen/src/main/kotlin/app/cash/redwood/tooling/codegen/types.kt @@ -44,6 +44,7 @@ internal object ProtocolGuest { ClassName("app.cash.redwood.protocol.guest", "ProtocolMismatchHandler") val ProtocolWidget = ClassName("app.cash.redwood.protocol.guest", "ProtocolWidget") val ProtocolWidgetChildren = ClassName("app.cash.redwood.protocol.guest", "ProtocolWidgetChildren") + val ProtocolWidgetChildrenVisitor = ProtocolWidget.nestedClass("ChildrenVisitor") val ProtocolWidgetSystemFactory = ClassName("app.cash.redwood.protocol.guest", "ProtocolWidgetSystemFactory") } diff --git a/redwood-treehouse-guest/src/jsMain/kotlin/app/cash/redwood/treehouse/ProtocolBridgeJs.kt b/redwood-treehouse-guest/src/jsMain/kotlin/app/cash/redwood/treehouse/ProtocolBridgeJs.kt index 8961fcea84..e7f96d5399 100644 --- a/redwood-treehouse-guest/src/jsMain/kotlin/app/cash/redwood/treehouse/ProtocolBridgeJs.kt +++ b/redwood-treehouse-guest/src/jsMain/kotlin/app/cash/redwood/treehouse/ProtocolBridgeJs.kt @@ -51,7 +51,7 @@ internal class FastGuestProtocolAdapter( hostVersion: RedwoodVersion, private val widgetSystemFactory: ProtocolWidgetSystemFactory, private val mismatchHandler: ProtocolMismatchHandler = ProtocolMismatchHandler.Throwing, -) : GuestProtocolAdapter { +) : GuestProtocolAdapter(hostVersion) { private var nextValue = Id.Root.value + 1 private val widgets = JsMap() private val changes = JsArray() @@ -64,8 +64,6 @@ internal class FastGuestProtocolAdapter( override val root: ProtocolWidgetChildren = ProtocolWidgetChildren(Id.Root, ChildrenTag.Root, this) - override val synthesizeSubtreeRemoval: Boolean = hostVersion < RedwoodVersion("0.10.0-SNAPSHOT") - override fun sendEvent(event: Event) { val node = widgets[event.id.value] if (node != null) {