From 24bc62145f13f0c7d1808f62ca49624d547b9e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=9A=D0=B0=D0=BF?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BA=D0=BE?= Date: Thu, 28 Dec 2023 14:13:38 +0300 Subject: [PATCH] d --- Modules/MPAKX/MPAKX.podspec | 14 +++ Modules/MPAKX/Package.swift | 21 ++++ Modules/MPAKX/README.md | 1 + Modules/MPAKX/src/MPAK.Controller.swift | 128 ++++++++++++++++++++++++ Modules/MPAKX/src/MPAK.swift | 10 ++ Modules/MeetupIdX/MeetupIdX.podspec | 1 + app/Podfile | 1 + app/Podfile.lock | 10 +- 8 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 Modules/MPAKX/MPAKX.podspec create mode 100644 Modules/MPAKX/Package.swift create mode 100644 Modules/MPAKX/README.md create mode 100644 Modules/MPAKX/src/MPAK.Controller.swift create mode 100644 Modules/MPAKX/src/MPAK.swift diff --git a/Modules/MPAKX/MPAKX.podspec b/Modules/MPAKX/MPAKX.podspec new file mode 100644 index 0000000..fe49e41 --- /dev/null +++ b/Modules/MPAKX/MPAKX.podspec @@ -0,0 +1,14 @@ +Pod::Spec.new do |s| + +s.name = 'MPAKX' +s.version = '2023.12.15' +s.license = 'IVCS' +s.summary = 'IVCS' +s.homepage = 'IVCS' +s.author = 'IVCS' +s.source = { :git => 'https://fake.com/FAKE.git', :tag => s.version } +s.source_files = 'src/*.swift' +s.swift_version = '5.2' +s.ios.deployment_target = '14.0' + +end diff --git a/Modules/MPAKX/Package.swift b/Modules/MPAKX/Package.swift new file mode 100644 index 0000000..7172df4 --- /dev/null +++ b/Modules/MPAKX/Package.swift @@ -0,0 +1,21 @@ +// swift-tools-version: 5.9 + +import PackageDescription + +let package = Package( + name: "MPAKX", + platforms: [.iOS(.v14)], + products: [ + .library( + name: "MPAKX", + type: .dynamic, + targets: ["MPAKX"] + ), + ], + targets: [ + .target( + name: "MPAKX", + path: "src" + ), + ] +) diff --git a/Modules/MPAKX/README.md b/Modules/MPAKX/README.md new file mode 100644 index 0000000..a7888f6 --- /dev/null +++ b/Modules/MPAKX/README.md @@ -0,0 +1 @@ +Сущности для уменьшения количества кода при использовании архитектуры "Мрак в Моделях" diff --git a/Modules/MPAKX/src/MPAK.Controller.swift b/Modules/MPAKX/src/MPAK.Controller.swift new file mode 100644 index 0000000..516185f --- /dev/null +++ b/Modules/MPAKX/src/MPAK.Controller.swift @@ -0,0 +1,128 @@ +import Combine +import Foundation + +public protocol MPAKControllerProtocol: AnyObject { + associatedtype Model + + func pipe( + dbg: String?, + sub: UnsafeMutablePointer<[AnyCancellable]>?, + _ node: AnyPublisher, + _ reaction: @escaping (inout Model) -> Void, + _ reversion: ((inout Model) -> Void)? + ) + + func pipeValue( + dbg: String?, + sub: UnsafeMutablePointer<[AnyCancellable]>?, + _ node: AnyPublisher, + _ reaction: @escaping (inout Model, T) -> Void, + _ reversion: ((inout Model, T) -> Void)? + ) +} + +extension MPAK { + open class Controller: MPAKControllerProtocol { + public let m: CurrentValueSubject + public var subscriptions = [AnyCancellable]() + + private var debugClassName: String? + private var debugLog: ((String) -> Void)? + private var model: Model + + public init( + _ model: Model, + debugClassName: String? = nil, + debugLog: ((String) -> Void)? = nil + ) { + m = .init(model) + self.model = model + self.debugClassName = debugClassName + self.debugLog = debugLog + } + + public func pipe( + dbg: String? = nil, + sub: UnsafeMutablePointer<[AnyCancellable]>? = nil, + _ node: AnyPublisher, + _ reaction: @escaping (inout Model) -> Void, + _ reversion: ((inout Model) -> Void)? = nil + ) { + let subscription = node + .sink { [weak self] _ in + assert(Thread.isMainThread) + guard let self = self else { return } + self.dbgLog(dbg) + reaction(&self.model) + let modelCopy = self.model + if let rev = reversion { + rev(&self.model) + } + self.m.send(modelCopy) + } + if let sub = sub { + sub.pointee.append(subscription) + } else { + subscriptions.append(subscription) + } + } + + public func pipeOptional( + dbg: String? = nil, + _ node: AnyPublisher, + _ reaction: @escaping (inout Model, T?) -> Void, + _ reversion: ((inout Model, T?) -> Void)? = nil + ) { + node + .sink { [weak self] value in + assert(Thread.isMainThread) + guard let self = self else { return } + self.dbgLog(dbg) + reaction(&self.model, value) + let modelCopy = self.model + if let rev = reversion { + rev(&self.model, value) + } + self.m.send(modelCopy) + } + .store(in: &subscriptions) + } + + public func pipeValue( + dbg: String? = nil, + sub: UnsafeMutablePointer<[AnyCancellable]>? = nil, + _ node: AnyPublisher, + _ reaction: @escaping (inout Model, T) -> Void, + _ reversion: ((inout Model, T) -> Void)? = nil + ) { + let subscription = node + .sink { [weak self] value in + assert(Thread.isMainThread) + guard let self = self else { return } + self.dbgLog(dbg) + reaction(&self.model, value) + let modelCopy = self.model + if let rev = reversion { + rev(&self.model, value) + } + self.m.send(modelCopy) + } + if let sub = sub { + sub.pointee.append(subscription) + } else { + subscriptions.append(subscription) + } + } + + private func dbgLog(_ text: String?) { + guard + let className = debugClassName, + let log = debugLog, + let text = text + else { + return + } + log("\(className).\(text)") + } + } +} diff --git a/Modules/MPAKX/src/MPAK.swift b/Modules/MPAKX/src/MPAK.swift new file mode 100644 index 0000000..a5f1bf6 --- /dev/null +++ b/Modules/MPAKX/src/MPAK.swift @@ -0,0 +1,10 @@ +public enum MPAK { + public struct Recent { + public var isRecent = false + public var value: T + + public init(_ value: T) { + self.value = value + } + } +} diff --git a/Modules/MeetupIdX/MeetupIdX.podspec b/Modules/MeetupIdX/MeetupIdX.podspec index 84cb375..6b802f1 100644 --- a/Modules/MeetupIdX/MeetupIdX.podspec +++ b/Modules/MeetupIdX/MeetupIdX.podspec @@ -12,5 +12,6 @@ s.swift_version = '5.2' s.ios.deployment_target = '14.0' s.dependency 'BusX' s.dependency 'CordX' +s.dependency 'MPAKX' end diff --git a/app/Podfile b/app/Podfile index 1178d14..dd88220 100644 --- a/app/Podfile +++ b/app/Podfile @@ -6,6 +6,7 @@ platform :ios, '14.0' pod 'BusX', :path => '../Modules/BusX' pod 'CordX', :path => '../Modules/CordX' pod 'MeetupIdX', :path => '../Modules/MeetupIdX' +pod 'MPAKX', :path => '../Modules/MPAKX' target 'pesochnicza' do use_frameworks! diff --git a/app/Podfile.lock b/app/Podfile.lock index 164907d..02004d1 100644 --- a/app/Podfile.lock +++ b/app/Podfile.lock @@ -5,11 +5,14 @@ PODS: - MeetupIdX (2023.12.28): - BusX - CordX + - MPAKX + - MPAKX (2023.12.15) DEPENDENCIES: - BusX (from `../Modules/BusX`) - CordX (from `../Modules/CordX`) - MeetupIdX (from `../Modules/MeetupIdX`) + - MPAKX (from `../Modules/MPAKX`) EXTERNAL SOURCES: BusX: @@ -18,12 +21,15 @@ EXTERNAL SOURCES: :path: "../Modules/CordX" MeetupIdX: :path: "../Modules/MeetupIdX" + MPAKX: + :path: "../Modules/MPAKX" SPEC CHECKSUMS: BusX: fd22c04ad544d131e66315c1a33d87d85b19712e CordX: 63515d366b217366b9562edcfef34630a7be1171 - MeetupIdX: 2492aa1705abcda355a2a737bc11a36f25f95cf5 + MeetupIdX: 73bad884d8b9475a9f68c5bfbc41fd801bcd9bff + MPAKX: dc592434f55edf34709f6e4f37c9ec90dcd95185 -PODFILE CHECKSUM: cc90c0545c91b88d241373031398c5b3c4dc6663 +PODFILE CHECKSUM: dec392687416132036b0dfd3d25285cb6aa81629 COCOAPODS: 1.13.0