Skip to content

Commit

Permalink
Merge pull request #10 from ktatroe/Swift3Update
Browse files Browse the repository at this point in the history
Swift3 update
  • Loading branch information
ktatroe committed Dec 2, 2016
2 parents 27464fe + f71d34a commit f811009
Show file tree
Hide file tree
Showing 60 changed files with 959 additions and 829 deletions.
65 changes: 24 additions & 41 deletions Horatio/Container/Container.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,68 +35,51 @@ import Foundation
if let bridge = Container.resolve(ParkServiceBridge.self) { }
*/
public class Container {
open class Container {
static internal var sharedContainer = Container()

private var services = [ContainerItemKey: ContainerItemType]()
fileprivate var services = [ContainerItemKey: ContainerItemType]()

// we need a recursive lock, because sometimes we do a resolve() inside a resolve()
private let servicesLock = NSRecursiveLock()

public func register<T>(serviceType: T.Type, name: String? = nil, factory: Resolvable -> T) -> ContainerEntry<T> {
open func register<T>(_ serviceType: T.Type, name: String? = nil, factory: (Resolvable) -> T) -> ContainerEntry<T> {
return registerFactory(serviceType, factory: factory, name: name)
}

internal func registerFactory<T, Factory>(serviceType: T.Type, factory: Factory, name: String?) -> ContainerEntry<T> {
let key = ContainerItemKey(factoryType: factory.dynamicType, name: name)
internal func registerFactory<T, Factory>(_ serviceType: T.Type, factory: Factory, name: String?) -> ContainerEntry<T> {
let key = ContainerItemKey(factoryType: type(of: factory), name: name)
let entry = ContainerEntry(serviceType: serviceType, factory: factory)

// ensure no other access while writing
servicesLock.lock()

defer {
servicesLock.unlock()
}

services[key] = entry

return entry
}

static public func register<T>(serviceType: T.Type, name: String? = nil, factory: Resolvable -> T) -> ContainerEntry<T> {
@discardableResult
static open func register<T>(_ serviceType: T.Type, name: String? = nil, factory: (Resolvable) -> T) -> ContainerEntry<T> {
return sharedContainer.register(serviceType, name: name, factory: factory)
}
}


extension Container : Resolvable {
public func resolve<T>(serviceType: T.Type, name: String? = nil) -> T? {
typealias FactoryType = Resolvable -> T
@discardableResult
public func resolve<T>(_ serviceType: T.Type, name: String? = nil) -> T? {
typealias FactoryType = (Resolvable) -> T

return resolveFactory(name) { (factory: FactoryType) in factory(self) }
}

static public func resolve<T>(serviceType: T.Type, name: String? = nil) -> T? {
return sharedContainer.resolve(serviceType, name: name)
@discardableResult
static public func resolve<T>(_ serviceType: T.Type, name: String? = nil) -> T? {
let result = sharedContainer.resolve(serviceType, name: name)

return result
}

internal func resolveFactory<T, Factory>(name: String?, invoker: Factory -> T) -> T? {
internal func resolveFactory<T, Factory>(_ name: String?, invoker: (Factory) -> T) -> T? {
let key = ContainerItemKey(factoryType: Factory.self, name: name)

var lockedEntry: ContainerItemType? = nil

// read from data structure in a thread-safe manner
servicesLock.lock()

defer {
servicesLock.unlock()
}

lockedEntry = services[key]

if let entry = lockedEntry as? ContainerEntry<T> {
if let entry = services[key] as? ContainerEntry<T> {
if entry.instance == nil {
// this is doing a write to a shared object, and also must happen inside the lock
entry.instance = resolveEntry(entry, key: key, invoker: invoker) as Any
}

Expand All @@ -106,7 +89,7 @@ extension Container : Resolvable {
return nil
}

private func resolveEntry<T, Factory>(entry: ContainerEntry<T>, key: ContainerItemKey, invoker: Factory -> T) -> T {
fileprivate func resolveEntry<T, Factory>(_ entry: ContainerEntry<T>, key: ContainerItemKey, invoker: (Factory) -> T) -> T {
let resolvedInstance = invoker(entry.factory as! Factory)

return resolvedInstance
Expand All @@ -117,13 +100,13 @@ extension Container : Resolvable {
public typealias FunctionType = Any

public protocol Resolvable {
func resolve<T>(serviceType: T.Type, name: String?) -> T?
func resolve<T>(_ serviceType: T.Type, name: String?) -> T?
}


internal struct ContainerItemKey {
private let factoryType: FunctionType.Type
private let name: String?
fileprivate let factoryType: FunctionType.Type
fileprivate let name: String?

internal init(factoryType: FunctionType.Type, name: String? = nil) {
self.factoryType = factoryType
Expand All @@ -134,7 +117,7 @@ internal struct ContainerItemKey {

extension ContainerItemKey : Hashable {
var hashValue: Int {
return String(factoryType).hashValue ^ (name?.hashValue ?? 0)
return String(describing: factoryType).hashValue ^ (name?.hashValue ?? 0)
}
}

Expand All @@ -145,8 +128,8 @@ func == (lhs: ContainerItemKey, rhs: ContainerItemKey) -> Bool {

internal typealias ContainerItemType = Any

public class ContainerEntry<T> : ContainerItemType {
private let serviceType: T.Type
open class ContainerEntry<T> : ContainerItemType {
fileprivate let serviceType: T.Type
let factory: FunctionType

var instance: Any? = nil
Expand Down
26 changes: 13 additions & 13 deletions Horatio/Features/FeatureCondition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation
Determines whether a feature is currently available to a given `FeatureSubject`.
*/
protocol FeatureCondition {
func isMet(subject: FeatureSubject?) -> Bool
func isMet(_ subject: FeatureSubject?) -> Bool
}


Expand All @@ -19,7 +19,7 @@ protocol FeatureCondition {
class DateFeatureCondition: FeatureCondition {
// MARK: - Initialization

init(startDate: NSDate? = nil, endDate: NSDate? = nil) {
init(startDate: Date? = nil, endDate: Date? = nil) {
self.startDate = startDate
self.endDate = endDate
}
Expand All @@ -29,17 +29,17 @@ class DateFeatureCondition: FeatureCondition {

// MARK: - <FeatureCondition>

func isMet(subject: FeatureSubject?) -> Bool {
let currentDate = NSDate()
func isMet(_ subject: FeatureSubject?) -> Bool {
let currentDate = Date()

if let startDate = startDate {
if currentDate.compare(startDate) == NSComparisonResult.OrderedAscending {
if currentDate.compare(startDate) == ComparisonResult.orderedAscending {
return false
}
}

if let endDate = endDate {
if currentDate.compare(endDate) == NSComparisonResult.OrderedDescending {
if currentDate.compare(endDate) == ComparisonResult.orderedDescending {
return false
}
}
Expand All @@ -50,8 +50,8 @@ class DateFeatureCondition: FeatureCondition {

// MARK: - Private

private let startDate: NSDate?
private let endDate: NSDate?
fileprivate let startDate: Date?
fileprivate let endDate: Date?
}


Expand All @@ -71,14 +71,14 @@ class InverseFeatureCondition: FeatureCondition {

// MARK: - <FeatureCondition>

func isMet(subject: FeatureSubject?) -> Bool {
func isMet(_ subject: FeatureSubject?) -> Bool {
return !condition.isMet(subject)
}


// MARK: - Private

private let condition: FeatureCondition
fileprivate let condition: FeatureCondition
}


Expand All @@ -98,13 +98,13 @@ class AndFeatureCondition: FeatureCondition {

// MARK: - <FeatureCondition>

func isMet(subject: FeatureSubject?) -> Bool {
func isMet(_ subject: FeatureSubject?) -> Bool {
return lhs.isMet(subject) && rhs.isMet(subject)
}


// MARK: - Private

private let lhs: FeatureCondition
private let rhs: FeatureCondition
fileprivate let lhs: FeatureCondition
fileprivate let rhs: FeatureCondition
}
4 changes: 2 additions & 2 deletions Horatio/Features/FeatureManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Foundation
environments).
*/
protocol FeatureProvider {
func feature(named: String) -> Feature?
func feature(_ named: String) -> Feature?

func activeSubject() -> FeatureSubject?
}
Expand Down Expand Up @@ -79,5 +79,5 @@ class StaticFeature: Feature {

// MARK: - Private

private let staticValue: FeatureValue
fileprivate let staticValue: FeatureValue
}
10 changes: 5 additions & 5 deletions Horatio/Features/FeatureSelector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Foundation
*/
protocol FeatureSelector {
/// Returns the selector's mapped value in the range [0, 1) for a given subject and feature.
func select(feature: Feature, subject: FeatureSubject?) -> Double?
func select(_ feature: Feature, subject: FeatureSubject?) -> Double?
}


Expand All @@ -24,7 +24,7 @@ class WeightedFeatureSelector: FeatureSelector {

// MARK: <FeatureSelector>

func select(feature: Feature, subject: FeatureSubject? = nil) -> Double? {
func select(_ feature: Feature, subject: FeatureSubject? = nil) -> Double? {
guard let subject = subject else { return nil }

let hashValue = "\(feature.identifier).\(subject.identifier)".hashValue
Expand All @@ -35,7 +35,7 @@ class WeightedFeatureSelector: FeatureSelector {

// MARK: - Private

private func normalize(value: Int) -> Double {
fileprivate func normalize(_ value: Int) -> Double {
return Double(value) / Double(Int.max)
}
}
Expand All @@ -55,12 +55,12 @@ class FixedFeatureSelector: FeatureSelector {

// MARK: <FeatureSelector>

func select(feature: Feature, subject: FeatureSubject?) -> Double? {
func select(_ feature: Feature, subject: FeatureSubject?) -> Double? {
return weight
}


// MARK: - Private

private let weight: Double
fileprivate let weight: Double
}
4 changes: 2 additions & 2 deletions Horatio/Features/FeatureSubject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class RandomFeatureSubject: FeatureSubject {

// MARK: - Private

private static func generateRandomIdentifier(length: Int) -> String {
fileprivate static func generateRandomIdentifier(_ length: Int) -> String {
let allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let count = UInt32(allowed.characters.count)

Expand All @@ -43,7 +43,7 @@ class RandomFeatureSubject: FeatureSubject {
for _ in (0 ..< length) {
let random = Int(arc4random_uniform(count))

let c = allowed[allowed.startIndex.advancedBy(random)]
let c = allowed[allowed.characters.index(allowed.startIndex, offsetBy: random)]
identifier += String(c)
}

Expand Down
2 changes: 1 addition & 1 deletion Horatio/Features/VendorIDFeatureSubject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ class VendorIDFeatureSubject: FeatureSubject {
// MARK: - Initialization

init() {
self.identifier = UIDevice.currentDevice().identifierForVendor?.UUIDString ?? "<unavailable>"
self.identifier = UIDevice.current.identifierForVendor?.uuidString ?? "<unavailable>"
}
}
Loading

0 comments on commit f811009

Please sign in to comment.