Skip to content

Commit

Permalink
Merge pull request #1 from bfcrampton/master
Browse files Browse the repository at this point in the history
Allow for subscriptions which contain oldValue from didSet
  • Loading branch information
hyperspacemark committed Mar 1, 2016
2 parents 77d09a5 + 3a647df commit d6afc96
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 30 deletions.
10 changes: 7 additions & 3 deletions Notice.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

/* Begin PBXBuildFile section */
396F33661BB3461F00792AB5 /* Notice.h in Headers */ = {isa = PBXBuildFile; fileRef = 396F33651BB3461F00792AB5 /* Notice.h */; settings = {ATTRIBUTES = (Public, ); }; };
396F336E1BB3464300792AB5 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396F336D1BB3464300792AB5 /* Observable.swift */; settings = {ASSET_TAGS = (); }; };
396F33701BB3468300792AB5 /* Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396F336F1BB3468300792AB5 /* Subscription.swift */; settings = {ASSET_TAGS = (); }; };
396F33721BB346C800792AB5 /* Subscriptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396F33711BB346C800792AB5 /* Subscriptions.swift */; settings = {ASSET_TAGS = (); }; };
396F336E1BB3464300792AB5 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396F336D1BB3464300792AB5 /* Observable.swift */; };
396F33701BB3468300792AB5 /* Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396F336F1BB3468300792AB5 /* Subscription.swift */; };
396F33721BB346C800792AB5 /* Subscriptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396F33711BB346C800792AB5 /* Subscriptions.swift */; };
62839F6B1C80BD3E0076F99F /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62839F6A1C80BD3E0076F99F /* Event.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -20,6 +21,7 @@
396F336D1BB3464300792AB5 /* Observable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = "<group>"; };
396F336F1BB3468300792AB5 /* Subscription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Subscription.swift; sourceTree = "<group>"; };
396F33711BB346C800792AB5 /* Subscriptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Subscriptions.swift; sourceTree = "<group>"; };
62839F6A1C80BD3E0076F99F /* Event.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -57,6 +59,7 @@
396F336D1BB3464300792AB5 /* Observable.swift */,
396F336F1BB3468300792AB5 /* Subscription.swift */,
396F33711BB346C800792AB5 /* Subscriptions.swift */,
62839F6A1C80BD3E0076F99F /* Event.swift */,
);
path = Notice;
sourceTree = "<group>";
Expand Down Expand Up @@ -140,6 +143,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
62839F6B1C80BD3E0076F99F /* Event.swift in Sources */,
396F33721BB346C800792AB5 /* Subscriptions.swift in Sources */,
396F33701BB3468300792AB5 /* Subscription.swift in Sources */,
396F336E1BB3464300792AB5 /* Observable.swift in Sources */,
Expand Down
29 changes: 29 additions & 0 deletions Notice/Event.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
public protocol Event {
typealias ValueType
typealias HandlerType

var value: ValueType { get }
func handle(handler: HandlerType)
}

public struct NewEvent<T>: Event {
public let value: T

public func handle(handler: T -> Void) {
handler(value)
}
}

public struct NewOldEvent<T>: Event {
public let value: T
public let oldValue: T?

init(value: T, oldValue: T? = nil) {
self.value = value
self.oldValue = oldValue
}

public func handle(handler: (old: T?, new: T) -> Void) {
handler(old: oldValue, new: value)
}
}
40 changes: 29 additions & 11 deletions Notice/Observable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public struct Observable<T> {

// MARK: - Types

public typealias SubscriptionType = Subscription<T>
public typealias NewEventType = NewEvent<T>
public typealias NewOldEventType = NewOldEvent<T>


// MARK: - Properties
Expand All @@ -22,7 +23,8 @@ public struct Observable<T> {
public var value: T {
didSet {
dispatch_sync(eventQueue) {
self.subscribers.send(self.value)
self.newSubscribers.send(NewEvent(value: self.value))
self.newOldSubscribers.send(NewOldEvent(value: self.value, oldValue: oldValue))
}
}
}
Expand All @@ -37,20 +39,36 @@ public struct Observable<T> {

// MARK: - Subscribers

private var subscribers = Subscriptions<T>()
private var newSubscribers = Subscriptions<NewEventType>()
private var newOldSubscribers = Subscriptions<NewOldEventType>()

public mutating func subscribe(options: SubscriptionOptions = [.New], handler: SubscriptionType.EventHandler) -> SubscriptionType {
let subscription = Subscription(handler: handler)
public mutating func subscribe(options: SubscriptionOptions = [.New], handler: NewEventType.HandlerType) -> Subscription<NewEventType> {
let subscriber = Subscription<NewEventType>(handler: handler)

if options.contains(.Initial) {
subscription.handler(value)
subscriber.handle(NewEvent(value: self.value))
}

subscribers.add(subscription)
return subscription

newSubscribers.add(subscriber)
return subscriber
}

public mutating func unsubscribe(subscriber: Subscription<NewEventType>) {
newSubscribers.remove(subscriber)
}

public mutating func subscribeNewOld(options: SubscriptionOptions = [.New], handler: NewOldEventType.HandlerType) -> Subscription<NewOldEventType> {
let subscriber = Subscription<NewOldEventType>(handler: handler)

if options.contains(.Initial) {
subscriber.handle(NewOldEventType(value: self.value))
}

newOldSubscribers.add(subscriber)
return subscriber
}

public mutating func unsubscribe(subscriber: SubscriptionType) {
subscribers.remove(subscriber)
public mutating func unsubscribe(subscriber: Subscription<NewOldEventType>) {
newOldSubscribers.remove(subscriber)
}
}
10 changes: 7 additions & 3 deletions Notice/Subscription.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
public class Subscription<T>: Hashable {
public typealias EventHandler = T -> Void
public class Subscription<EventType: Event>: Hashable {
public typealias EventHandler = EventType.HandlerType

let handler: EventHandler
private let UUID = NSUUID().UUIDString
Expand All @@ -11,8 +11,12 @@ public class Subscription<T>: Hashable {
public var hashValue: Int {
return UUID.hashValue
}

func handle(event: EventType) {
event.handle(handler)
}
}

public func ==<T>(lhs: Subscription<T>, rhs: Subscription<T>) -> Bool {
public func ==<EventType: Event>(lhs: Subscription<EventType>, rhs: Subscription<EventType>) -> Bool {
return lhs.UUID == rhs.UUID
}
24 changes: 11 additions & 13 deletions Notice/Subscriptions.swift
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
protocol SubscriptionsType {
typealias ValueType
typealias EventType: Event

var subscriptions: Set<Subscription<ValueType>> { get set }
var subscriptions: Set<Subscription<EventType>> { get set }

mutating func add(subscription: Subscription<ValueType>)
mutating func remove(subscription: Subscription<ValueType>)
func send(value: ValueType)
mutating func add(subscription: Subscription<EventType>)
mutating func remove(subscription: Subscription<EventType>)
func send(value: EventType)
}

extension SubscriptionsType {
mutating func add(subscription: Subscription<ValueType>) {
mutating func add(subscription: Subscription<EventType>) {
subscriptions.insert(subscription)
}

mutating func remove(subscription: Subscription<ValueType>) {
mutating func remove(subscription: Subscription<EventType>) {
subscriptions.remove(subscription)
}
}

class Subscriptions<T>: SubscriptionsType {
typealias ValueType = T
class Subscriptions<EventType: Event>: SubscriptionsType {
var subscriptions = Set<Subscription<EventType>>()

var subscriptions = Set<Subscription<ValueType>>()

func send(value: ValueType) {
subscriptions.forEach { $0.handler(value) }
func send(event: EventType) {
subscriptions.forEach { $0.handle(event) }
}
}

0 comments on commit d6afc96

Please sign in to comment.