Proposal changes stop rebuilding the whole board — lanes and card faces gate on their values
LaneView and CardFaceView become Equatable and are instantiated through .equatable(): the strip's body re-runs on every drop-proposal change, and without the gates that rebuilt every lane and every card face on every cursor move of a drag. The == compares value inputs and window-lived collaborator identities; the closures BoardView rebuilds each pass are deliberately excluded (BoardDropContext.isEquivalent / MarqueeControl. isEquivalent / CardFaceRole.isEquivalent own that judgment). Observation reads inside the bodies still self-invalidate — the lane under the drag keeps re-running; the other lanes stop. Ports the pathfinder's CardView/ColumnView gating pattern (drag-perf suspect #2, card cbb6e476). Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -40,6 +40,17 @@ struct MarqueeControl {
|
||||
let registry: MarqueeTargetRegistry
|
||||
let store: BoardStore
|
||||
|
||||
/// Whether two of these lend the same band — the whole of what this value contributes to
|
||||
/// `LaneView.==` and `CardFaceView.==` (`BoardDropContext.isEquivalent(to:)` is its twin).
|
||||
///
|
||||
/// All three members are window-lived objects, so identity is the comparison: this struct holds
|
||||
/// no geometry and no closures of its own, and the strip rebuilds it on every body pass.
|
||||
nonisolated func isEquivalent(to other: MarqueeControl) -> Bool {
|
||||
session === other.session
|
||||
&& registry === other.registry
|
||||
&& store === other.store
|
||||
}
|
||||
|
||||
/// The band, as one gesture attached with `simultaneousGesture` wherever empty space is.
|
||||
///
|
||||
/// - **The begin guard is geometric**: a drag whose start lands inside a registered frame is
|
||||
|
||||
Reference in New Issue
Block a user