Проверка шаблона шины для iOS
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

129 lignes
3.4KB

  1. import Combine
  2. import Foundation
  3. public protocol MPAKControllerProtocol: AnyObject {
  4. associatedtype Model
  5. func pipe<T>(
  6. dbg: String?,
  7. sub: UnsafeMutablePointer<[AnyCancellable]>?,
  8. _ node: AnyPublisher<T, Never>,
  9. _ reaction: @escaping (inout Model) -> Void,
  10. _ reversion: ((inout Model) -> Void)?
  11. )
  12. func pipeValue<T>(
  13. dbg: String?,
  14. sub: UnsafeMutablePointer<[AnyCancellable]>?,
  15. _ node: AnyPublisher<T, Never>,
  16. _ reaction: @escaping (inout Model, T) -> Void,
  17. _ reversion: ((inout Model, T) -> Void)?
  18. )
  19. }
  20. extension MPAK {
  21. open class Controller<Model>: MPAKControllerProtocol {
  22. public let m: CurrentValueSubject<Model, Never>
  23. public var subscriptions = [AnyCancellable]()
  24. private var debugClassName: String?
  25. private var debugLog: ((String) -> Void)?
  26. private var model: Model
  27. public init(
  28. _ model: Model,
  29. debugClassName: String? = nil,
  30. debugLog: ((String) -> Void)? = nil
  31. ) {
  32. m = .init(model)
  33. self.model = model
  34. self.debugClassName = debugClassName
  35. self.debugLog = debugLog
  36. }
  37. public func pipe<T>(
  38. dbg: String? = nil,
  39. sub: UnsafeMutablePointer<[AnyCancellable]>? = nil,
  40. _ node: AnyPublisher<T, Never>,
  41. _ reaction: @escaping (inout Model) -> Void,
  42. _ reversion: ((inout Model) -> Void)? = nil
  43. ) {
  44. let subscription = node
  45. .sink { [weak self] _ in
  46. assert(Thread.isMainThread)
  47. guard let self = self else { return }
  48. self.dbgLog(dbg)
  49. reaction(&self.model)
  50. let modelCopy = self.model
  51. if let rev = reversion {
  52. rev(&self.model)
  53. }
  54. self.m.send(modelCopy)
  55. }
  56. if let sub = sub {
  57. sub.pointee.append(subscription)
  58. } else {
  59. subscriptions.append(subscription)
  60. }
  61. }
  62. public func pipeOptional<T>(
  63. dbg: String? = nil,
  64. _ node: AnyPublisher<T?, Never>,
  65. _ reaction: @escaping (inout Model, T?) -> Void,
  66. _ reversion: ((inout Model, T?) -> Void)? = nil
  67. ) {
  68. node
  69. .sink { [weak self] value in
  70. assert(Thread.isMainThread)
  71. guard let self = self else { return }
  72. self.dbgLog(dbg)
  73. reaction(&self.model, value)
  74. let modelCopy = self.model
  75. if let rev = reversion {
  76. rev(&self.model, value)
  77. }
  78. self.m.send(modelCopy)
  79. }
  80. .store(in: &subscriptions)
  81. }
  82. public func pipeValue<T>(
  83. dbg: String? = nil,
  84. sub: UnsafeMutablePointer<[AnyCancellable]>? = nil,
  85. _ node: AnyPublisher<T, Never>,
  86. _ reaction: @escaping (inout Model, T) -> Void,
  87. _ reversion: ((inout Model, T) -> Void)? = nil
  88. ) {
  89. let subscription = node
  90. .sink { [weak self] value in
  91. assert(Thread.isMainThread)
  92. guard let self = self else { return }
  93. self.dbgLog(dbg)
  94. reaction(&self.model, value)
  95. let modelCopy = self.model
  96. if let rev = reversion {
  97. rev(&self.model, value)
  98. }
  99. self.m.send(modelCopy)
  100. }
  101. if let sub = sub {
  102. sub.pointee.append(subscription)
  103. } else {
  104. subscriptions.append(subscription)
  105. }
  106. }
  107. private func dbgLog(_ text: String?) {
  108. guard
  109. let className = debugClassName,
  110. let log = debugLog,
  111. let text = text
  112. else {
  113. return
  114. }
  115. log("\(className).\(text)")
  116. }
  117. }
  118. }