0001    // Debounce.swift
0002    //
0003    // Copyright (c) 2015 Jens Ravens (http://jensravens.de)
0004    //
0005    // Permission is hereby granted, free of charge, to any person obtaining a copy
0006    // of this software and associated documentation files (the "Software"), to deal
0007    // in the Software without restriction, including without limitation the rights
0008    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0009    // copies of the Software, and to permit persons to whom the Software is
0010    // furnished to do so, subject to the following conditions:
0011    //
0012    // The above copyright notice and this permission notice shall be included in
0013    // all copies or substantial portions of the Software.
0014    //
0015    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0018    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0020    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0021    // THE SOFTWARE.
0022    
0023    import Foundation
0024    
0025    private var SignalUpdateCalledHandle
Debounce.swift:31
            if let handle = objc_getAssociatedObject(self, &SignalUpdateCalledHandle) as? NSDate {
Debounce.swift:38
            objc_setAssociatedObject(self, &SignalUpdateCalledHandle, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
: UInt8 = 0 0026 public extension Signal { 0027 #if os(Linux) 0028 #else 0029 internal var lastCalled
Debounce.swift:54
                    let timeSinceLastCall = signal.lastCalled?.timeIntervalSinceNow
Debounce.swift:57
                        signal.lastCalled = NSDate()
Debounce.swift:61
                        if currentTime.compare(signal.lastCalled!) == .OrderedDescending {
: NSDate? { 0030 get { 0031 if let handle = objc_getAssociatedObject(self, &SignalUpdateCalledHandle) as? NSDate { 0032 return handle 0033 } else { 0034 return nil 0035 } 0036 } 0037 set { 0038 objc_setAssociatedObject(self, &SignalUpdateCalledHandle, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 0039 } 0040 } 0041 0042 /** 0043 Creates a new signal that is only firing once per specified time interval. The last 0044 call to update will always be delivered (although it might be delayed up to the 0045 specified amount of seconds). 0046 */ 0047 public func debounce(seconds: NSTimeInterval) -> Signal<T> { 0048 let signal = Signal<T>() 0049 0050 subscribe { result in 0051 let currentTime = NSDate() 0052 func updateIfNeeded(signal: Signal<T>) -> Result<T> -> Void { 0053 return { result in 0054 let timeSinceLastCall = signal.lastCalled?.timeIntervalSinceNow 0055 if timeSinceLastCall == nil || timeSinceLastCall <= -seconds { 0056 // no update before or update outside of debounce window 0057 signal.lastCalled = NSDate() 0058 signal.update(result) 0059 } else { 0060 // skip result if there was a newer result 0061 if currentTime.compare(signal.lastCalled!) == .OrderedDescending { 0062 let s = Signal<T>() 0063 s.delay(seconds - timeSinceLastCall!).subscribe(updateIfNeeded(signal)) 0064 s.update(result) 0065 } 0066 } 0067 } 0068 } 0069 updateIfNeeded(signal)(result) 0070 } 0071 0072 return signal 0073 } 0074 #endif 0075 }