杨锴
2024-08-14 909e20941e45f8712c012db602034b47da0bfdb0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//
//  NSControl+Rx.swift
//  RxCocoa
//
//  Created by Krunoslav Zaher on 5/31/15.
//  Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
 
#if os(macOS)
 
import Cocoa
import RxSwift
 
private var rx_value_key: UInt8 = 0
private var rx_control_events_key: UInt8 = 0
 
extension Reactive where Base: NSControl {
 
    /// Reactive wrapper for control event.
    public var controlEvent: ControlEvent<()> {
        MainScheduler.ensureRunningOnMainThread()
 
        let source = self.lazyInstanceObservable(&rx_control_events_key) { () -> Observable<Void> in
            Observable.create { [weak control = self.base] observer in
                MainScheduler.ensureRunningOnMainThread()
 
                guard let control = control else {
                    observer.on(.completed)
                    return Disposables.create()
                }
 
                let observer = ControlTarget(control: control) { _ in
                    observer.on(.next(()))
                }
                
                return observer
            }
            .take(until: self.deallocated)
            .share()
        }
 
        return ControlEvent(events: source)
    }
 
    /// Creates a `ControlProperty` that is triggered by target/action pattern value updates.
    ///
    /// - parameter getter: Property value getter.
    /// - parameter setter: Property value setter.
    public func controlProperty<T>(
        getter: @escaping (Base) -> T,
        setter: @escaping (Base, T) -> Void
    ) -> ControlProperty<T> {
        MainScheduler.ensureRunningOnMainThread()
 
        let source = self.base.rx.lazyInstanceObservable(&rx_value_key) { () -> Observable<()> in
                return Observable.create { [weak weakControl = self.base] (observer: AnyObserver<()>) in
                    guard let control = weakControl else {
                        observer.on(.completed)
                        return Disposables.create()
                    }
 
                    observer.on(.next(()))
 
                    let observer = ControlTarget(control: control) { _ in
                        if weakControl != nil {
                            observer.on(.next(()))
                        }
                    }
 
                    return observer
                }
                .take(until: self.deallocated)
                .share(replay: 1, scope: .whileConnected)
            }
            .flatMap { [weak base] _ -> Observable<T> in
                guard let control = base else { return Observable.empty() }
                return Observable.just(getter(control))
            }
 
        let bindingObserver = Binder(self.base, binding: setter)
 
        return ControlProperty(values: source, valueSink: bindingObserver)
    }
}
 
 
#endif