crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

LocalMovesSnapshot.swift (1078B)


      1 import Foundation
      2 
      3 /// A point-in-time view of an author's merged Moves state, partitioned by
      4 /// whether each cell currently holds a letter. Diffed against a later snapshot
      5 /// to derive net adds and net clears for the in-app catch-up banner. Stored
      6 /// per peer as the local "what I've seen" baseline, advanced on leave, and
      7 /// shipped across the account's devices (keyed by peer) on
      8 /// `Player.sessionSnapshot` so siblings converge.
      9 struct LocalMovesSnapshot: Equatable, Sendable, Codable {
     10     /// Positions where the Moves row currently has a non-empty letter.
     11     let filled: Set<GridPosition>
     12     /// Positions where the Moves row currently has an explicit empty entry
     13     /// (cells the user cleared, including ones a peer had filled).
     14     let cleared: Set<GridPosition>
     15 
     16     static let empty = LocalMovesSnapshot(filled: [], cleared: [])
     17 
     18     func encoded() throws -> Data {
     19         try JSONEncoder().encode(self)
     20     }
     21 
     22     static func decode(_ data: Data) throws -> LocalMovesSnapshot {
     23         try JSONDecoder().decode(LocalMovesSnapshot.self, from: data)
     24     }
     25 }