Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support macOS 9 #18

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,6 @@ Carthage/Build

fastlane/report.xml
fastlane/screenshots

# AppCode
.idea/
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
![](Logo/Logo.png)

[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager)
![macOS](https://img.shields.io/badge/macOS-10.9-lightgrey.svg)

# Reactor

Reactor is a framework for making more reactive applications inspired by [Elm](https://github.com/evancz/elm-architecture-tutorial), [Redux](http://redux.js.org/docs/basics/index.html), and recent work on [ReSwift](https://github.com/ReSwift/ReSwift). It's small and simple (just one file), so you can either use Carthage to stay up to date, or just drag and drop into your project and go. Or you can look through it and roll your own.
Expand Down
11 changes: 6 additions & 5 deletions Reactor.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
OBJ_15 /* Reactor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Reactor.framework; sourceTree = BUILT_PRODUCTS_DIR; };
OBJ_16 /* ReactorTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = ReactorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
OBJ_9 /* Reactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reactor.swift; sourceTree = "<group>"; };
OBJ_9 /* Reactor.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = Reactor.swift; sourceTree = "<group>"; tabWidth = 4; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -153,6 +153,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = OBJ_5;
Expand Down Expand Up @@ -212,7 +213,7 @@
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos appletvsimulator iphonesimulator watchsimulator";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE;
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
TARGET_NAME = Reactor;
};
name = Debug;
Expand All @@ -235,7 +236,7 @@
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos appletvsimulator iphonesimulator watchsimulator";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE;
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
TARGET_NAME = Reactor;
};
name = Release;
Expand Down Expand Up @@ -284,7 +285,7 @@
ENABLE_NS_ASSERTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "-DXcode";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -305,7 +306,7 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_OPTIMIZATION_LEVEL = s;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MACOSX_DEPLOYMENT_TARGET = 10.9;
OTHER_SWIFT_FLAGS = "-DXcode";
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
48 changes: 45 additions & 3 deletions Sources/Reactor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extension Middleware {
}

public struct Middlewares<StateType: State> {
let id: UInt64
private(set) var middleware: AnyMiddleware
}

Expand Down Expand Up @@ -80,13 +81,31 @@ public struct Subscription<StateType: State> {
}
}

extension String {
static func random(length: Int = 20) -> String {
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in base.randomElement()! })
}
}

class Counter {
private var queue = DispatchQueue(label: String.random())
private (set) var value: UInt64 = 0

func increment() -> UInt64 {
return queue.sync(execute: { () -> UInt64 in
value += 1
return value
})
}
}

// MARK: - Core

public class Core<StateType: State> {

private let jobQueue:DispatchQueue = DispatchQueue(label: "reactor.core.queue", qos: .userInitiated, attributes: [])
private var middlewareCounter = Counter()
private let jobQueue:DispatchQueue

private let subscriptionsSyncQueue = DispatchQueue(label: "reactor.core.subscription.sync")
private var _subscriptions = [Subscription<StateType>]()
Expand All @@ -103,7 +122,7 @@ public class Core<StateType: State> {
}
}

private let middlewares: [Middlewares<StateType>]
private var middlewares: [Middlewares<StateType>]
public private (set) var state: StateType {
didSet {
subscriptions = subscriptions.filter { $0.subscriber != nil }
Expand All @@ -115,7 +134,16 @@ public class Core<StateType: State> {

public init(state: StateType, middlewares: [AnyMiddleware] = []) {
self.state = state
self.middlewares = middlewares.map(Middlewares.init)
var tempMiddlewares = [Middlewares<StateType>]()
for m in middlewares {
tempMiddlewares.append(Middlewares(id: middlewareCounter.increment(), middleware: m))
}
self.middlewares = tempMiddlewares
if #available(macOS 10.10, *) {
self.jobQueue = DispatchQueue(label: "reactor.core.queue", qos: .userInitiated, attributes: [])
} else {
self.jobQueue = DispatchQueue(label: "reactor.core.queue", qos: .unspecified, attributes: [])
}
}


Expand Down Expand Up @@ -149,5 +177,19 @@ public class Core<StateType: State> {
command.execute(state: self.state, core: self)
}
}

public func observe(with middleware: AnyMiddleware) -> () -> () {
let wrapper = Middlewares<StateType>(id: middlewareCounter.increment(), middleware: middleware)
jobQueue.async {
self.middlewares.append(wrapper)
}
return {
self.jobQueue.sync {
if let index = self.middlewares.firstIndex(where: { $0.id == wrapper.id }) {
self.middlewares.remove(at: index)
}
}
}
}

}