import Foundation public protocol PostboxView: AnyObject { } protocol MutablePostboxView: AnyObject { func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool func immutableView() -> PostboxView } final class CombinedMutableView { let views: [PostboxViewKey: MutablePostboxView] init(views: [PostboxViewKey: MutablePostboxView]) { self.views = views } func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> (updated: Bool, updateTrackedHoles: Bool) { var anyUpdated = false var updateTrackedHoles = false for (_, view) in self.views { if let mutableView = view as? MutableMessageHistoryView { var innerUpdated = false let previousPeerIds = mutableView.peerIds if mutableView.replay(postbox: postbox, transaction: transaction) { innerUpdated = true } var updateType: ViewUpdateType = .Generic switch mutableView.peerIds { case let .single(peerId, threadId): for key in transaction.currentPeerHoleOperations.keys { if key.peerId == peerId && key.threadId == threadId { updateType = .FillHole break } } case .associated: var ids = Set() switch mutableView.peerIds { case .single, .external: assertionFailure() case let .associated(mainPeerId, associatedId): ids.insert(mainPeerId) if let associatedId = associatedId { ids.insert(associatedId.peerId) } } if !ids.isEmpty { for key in transaction.currentPeerHoleOperations.keys { if ids.contains(key.peerId) { updateType = .FillHole break } } } case .external: break } mutableView.updatePeerIds(transaction: transaction) if mutableView.peerIds != previousPeerIds { updateType = .UpdateVisible let _ = mutableView.refreshDueToExternalTransaction(postbox: postbox) innerUpdated = true } if innerUpdated { anyUpdated = true updateTrackedHoles = true let _ = updateType //pipe.putNext((MessageHistoryView(mutableView), updateType)) } } else if view.replay(postbox: postbox, transaction: transaction) { anyUpdated = true } } return (anyUpdated, updateTrackedHoles) } func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool { var updated = false for (_, view) in self.views { if view.refreshDueToExternalTransaction(postbox: postbox) { updated = true } } return updated } func immutableView() -> CombinedView { var result: [PostboxViewKey: PostboxView] = [:] for (key, view) in self.views { result[key] = view.immutableView() } return CombinedView(views: result) } } public final class CombinedView { public let views: [PostboxViewKey: PostboxView] init(views: [PostboxViewKey: PostboxView]) { self.views = views } }