Swiftgram/SwiftSignalKit/Disposable.swift
2015-06-10 12:53:19 +03:00

130 lines
3.0 KiB
Swift

import Foundation
public protocol Disposable
{
func dispose()
}
internal struct _EmptyDisposable : Disposable {
internal func dispose() {
}
}
public let EmptyDisposable: Disposable = _EmptyDisposable()
public final class ActionDisposable : Disposable
{
private var action: () -> Void
private var lock: OSSpinLock = 0
public init(action: () -> Void) {
self.action = action
}
public func dispose() {
var action = doNothing
OSSpinLockLock(&self.lock)
action = self.action
self.action = doNothing
OSSpinLockUnlock(&self.lock)
action()
}
}
public final class MetaDisposable : Disposable
{
private var lock: OSSpinLock = 0
private var disposed = false
private var disposable: Disposable! = nil
public init() {
}
public func set(disposable: Disposable?) {
var previousDisposable: Disposable! = nil
var disposeImmediately = false
OSSpinLockLock(&self.lock)
disposeImmediately = self.disposed
if !disposeImmediately {
previousDisposable = self.disposable
if let disposable = disposable {
self.disposable = disposable
} else {
self.disposable = nil
}
}
OSSpinLockUnlock(&self.lock)
if previousDisposable != nil {
previousDisposable.dispose()
}
if disposeImmediately {
if let disposable = disposable {
disposable.dispose()
}
}
}
public func dispose()
{
var disposable: Disposable! = nil
OSSpinLockLock(&self.lock)
if !self.disposed {
self.disposed = true
disposable = self.disposable
self.disposable = nil
}
OSSpinLockUnlock(&self.lock)
if disposable != nil {
disposable.dispose()
}
}
}
public final class DisposableSet : Disposable {
private var lock: OSSpinLock = 0
private var disposed = false
private var disposables: [Disposable] = []
public init() {
}
public func add(disposable: Disposable) {
var disposeImmediately = false
OSSpinLockLock(&self.lock)
if self.disposed {
disposeImmediately = true
} else {
self.disposables.append(disposable)
}
OSSpinLockUnlock(&self.lock)
if disposeImmediately {
disposable.dispose()
}
}
public func dispose() {
var disposables: [Disposable] = []
OSSpinLockLock(&self.lock)
if !self.disposed {
self.disposed = true
disposables = self.disposables
self.disposables = []
}
OSSpinLockUnlock(&self.lock)
if disposables.count != 0 {
for disposable in disposables {
disposable.dispose()
}
}
}
}