Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
cc6bc8f
[Test] Add FrogcjnTest (event + associated value).
inamiy Nov 1, 2015
ef07416
Refactor code for better typing, naming, and routeMapping support.
inamiy Nov 14, 2015
465146a
[Test] Remove unnecessary `case Any`.
inamiy Nov 14, 2015
da9b9b4
Remove unnecessary methods.
inamiy Nov 24, 2015
c9f6db9
Add comment.
inamiy Nov 24, 2015
32630e2
Rename `Mapping` to `RouteMapping`.
inamiy Nov 24, 2015
93f184b
[Test] Organize tests.
inamiy Nov 24, 2015
bfd9ed2
Remove verbose methods in `Transition` & `Route`.
inamiy Nov 24, 2015
439d5a8
Organize code.
inamiy Nov 28, 2015
12cb3b8
[Test] Add testHasRoute_anyEvent()
inamiy Nov 28, 2015
2eeff1f
Add `final` modifiers.
inamiy Nov 28, 2015
1be6782
[Test] Re-add HierarchicalMachineTests which was deleted in ef07416.
inamiy Nov 29, 2015
8e093da
Update README.md & BasicTests.
inamiy Nov 30, 2015
2986012
Resize logo.png
inamiy Nov 30, 2015
f7ce748
Refactor code by separating event-only-driven `Machine` and `StateMac…
inamiy Dec 5, 2015
8ade68e
[Test] Add more RouteMapping tests.
inamiy Dec 5, 2015
e9c1bf3
[Test] Improve 8ade68e & update README.md
inamiy Dec 5, 2015
c1c18ec
Add `addStateRouteMapping()` & rename `EventRouteMapping` to `RouteMa…
inamiy Dec 7, 2015
b42ac6d
Update README.md
inamiy Dec 7, 2015
4c15f86
Conform State<S> & Event<E> to RawRepresentable.
inamiy Dec 8, 2015
edc0f3e
Set codeCoverageEnabled=YES.
inamiy Dec 8, 2015
2c9844f
[Test] Add StateTests & EventTests.
inamiy Dec 8, 2015
ce2ef2a
Fix RouteMapping + handler.
inamiy Dec 8, 2015
56b8c76
Simplify `machine.addRoutes()`.
inamiy Dec 8, 2015
e49b1c6
[Test] Improve code coverage.
inamiy Dec 8, 2015
c1751bf
Create universal framework to support watchOS & tvOS by using xcconfigs.
inamiy Dec 8, 2015
c6b59e4
Merge pull request #38 from ReactKit/universal-framework
inamiy Dec 8, 2015
83af536
Remove unnecessary xcodeproj settings.
inamiy Dec 9, 2015
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
Prev Previous commit
Next Next commit
Conform State<S> & Event<E> to RawRepresentable.
  • Loading branch information
inamiy committed Dec 8, 2015
commit 4c15f864af0fe1b81e41ea5b6422e0aef1f7dde1
44 changes: 35 additions & 9 deletions Sources/EventType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,41 @@ public protocol EventType: Hashable {}

// MARK: Event

/// `EventType` wrapper for handling`.Any` event.
public enum Event<E: EventType>: Hashable
/// `EventType` wrapper for handling `.Any` event.
public enum Event<E: EventType>
{
case Some(E)
case Any

public var value: E?
}

extension Event: Hashable
{
public var hashValue: Int
{
switch self {
case .Some(let x): return x
default: return nil
case .Some(let x): return x.hashValue
case .Any: return _hashValueForAny
}
}
}

extension Event: RawRepresentable
{
public init(rawValue: E?)
{
if let rawValue = rawValue {
self = .Some(rawValue)
}
else {
self = .Any
}
}

public var hashValue: Int
public var rawValue: E?
{
switch self {
case .Some(let x): return x.hashValue
case .Any: return _hashValueForAny
case .Some(let x): return x
default: return nil
}
}
}
Expand All @@ -45,6 +61,16 @@ public func == <E: EventType>(lhs: Event<E>, rhs: Event<E>) -> Bool
}
}

public func == <E: EventType>(lhs: Event<E>, rhs: E) -> Bool
{
return lhs.hashValue == rhs.hashValue
}

public func == <E: EventType>(lhs: E, rhs: Event<E>) -> Bool
{
return lhs.hashValue == rhs.hashValue
}

// MARK: NoEvent

/// Useful for creating StateMachine without events, i.e. `StateMachine<MyState, NoEvent>`.
Expand Down
10 changes: 5 additions & 5 deletions Sources/Machine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ public class Machine<S: StateType, E: EventType>
/// Check for added routes & routeMappings.
public func hasRoute(event event: E, transition: Transition<S>, userInfo: Any? = nil) -> Bool
{
guard let fromState = transition.fromState.value,
toState = transition.toState.value else
guard let fromState = transition.fromState.rawValue,
toState = transition.toState.rawValue else
{
assertionFailure("State = `.Any` is not supported for `hasRoute()` (always returns `false`)")
return false
Expand Down Expand Up @@ -110,7 +110,7 @@ public class Machine<S: StateType, E: EventType>

if let event = event {
for (ev, routeDict) in self._routes {
if ev.value == event || ev == .Any {
if ev.rawValue == event || ev == .Any {
routeDicts += [routeDict]
}
}
Expand Down Expand Up @@ -165,7 +165,7 @@ public class Machine<S: StateType, E: EventType>
if transition.fromState == .Some(self.state) || transition.fromState == .Any {
for (_, condition) in keyConditionDict {
// if toState is `.Any`, always treat as identity transition
let toState = transition.toState.value ?? self.state
let toState = transition.toState.rawValue ?? self.state

if _canPassCondition(condition, forEvent: event, fromState: self.state, toState: toState, userInfo: userInfo) {
return toState
Expand Down Expand Up @@ -426,7 +426,7 @@ public class Machine<S: StateType, E: EventType>
return
}

if triggeredEvent == event.value || event == .Any {
if triggeredEvent == event.rawValue || event == .Any {
handler(context)
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/StateMachine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ public final class StateMachine<S: StateType, E: EventType>: Machine<S, E>
/// - Note: This method also checks for event-based-routes.
public func hasRoute(transition: Transition<S>, userInfo: Any? = nil) -> Bool
{
guard let fromState = transition.fromState.value,
toState = transition.toState.value else
guard let fromState = transition.fromState.rawValue,
toState = transition.toState.rawValue else
{
assertionFailure("State = `.Any` is not supported for `hasRoute()` (always returns `false`)")
return false
Expand Down
24 changes: 20 additions & 4 deletions Sources/StateType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,37 @@ public protocol StateType: Hashable {}

// MARK: State

/// `StateType` wrapper for handling`.Any` state.
public enum State<S: StateType>: Hashable
/// `StateType` wrapper for handling `.Any` state.
public enum State<S: StateType>
{
case Some(S)
case Any

}

extension State: Hashable
{
public var hashValue: Int
{
switch self {
case .Some(let x): return x.hashValue
case .Any: return _hashValueForAny
}
}
}

extension State: RawRepresentable
{
public init(rawValue: S?)
{
if let rawValue = rawValue {
self = .Some(rawValue)
}
else {
self = .Any
}
}

public var value: S?
public var rawValue: S?
{
switch self {
case .Some(let x): return x
Expand Down
12 changes: 6 additions & 6 deletions Tests/RouteTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ class RouteTests: _TestCase
func testInit()
{
let route = Route<MyState, NoEvent>(transition: .State0 => .State1, condition: nil)
XCTAssertEqual(route.transition.fromState.value, MyState.State0)
XCTAssertEqual(route.transition.toState.value, MyState.State1)
XCTAssertEqual(route.transition.fromState.rawValue, MyState.State0)
XCTAssertEqual(route.transition.toState.rawValue, MyState.State1)
XCTAssertTrue(route.condition == nil)

let route2 = Route<MyState, NoEvent>(transition: .State1 => .State2, condition: { _ in false })
XCTAssertEqual(route2.transition.fromState.value, MyState.State1)
XCTAssertEqual(route2.transition.toState.value, MyState.State2)
XCTAssertEqual(route2.transition.fromState.rawValue, MyState.State1)
XCTAssertEqual(route2.transition.toState.rawValue, MyState.State2)
XCTAssertTrue(route2.condition != nil)

let route3 = Route<MyState, NoEvent>(transition: .State2 => .State3, condition: { context in false })
XCTAssertEqual(route3.transition.fromState.value, MyState.State2)
XCTAssertEqual(route3.transition.toState.value, MyState.State3)
XCTAssertEqual(route3.transition.fromState.rawValue, MyState.State2)
XCTAssertEqual(route3.transition.toState.rawValue, MyState.State3)
XCTAssertTrue(route3.condition != nil)
}
}
24 changes: 12 additions & 12 deletions Tests/TransitionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,37 @@ class TransitionTests: _TestCase
func testInit()
{
let transition = Transition<MyState>(fromState: .State0, toState: .State1)
XCTAssertEqual(transition.fromState.value, MyState.State0)
XCTAssertEqual(transition.toState.value, MyState.State1)
XCTAssertEqual(transition.fromState.rawValue, MyState.State0)
XCTAssertEqual(transition.toState.rawValue, MyState.State1)

// shorthand
let transition2 = MyState.State1 => .State0
XCTAssertEqual(transition2.fromState.value, MyState.State1)
XCTAssertEqual(transition2.toState.value, MyState.State0)
XCTAssertEqual(transition2.fromState.rawValue, MyState.State1)
XCTAssertEqual(transition2.toState.rawValue, MyState.State0)
}

func testInit_fromAny()
{
let transition = Transition<MyState>(fromState: .Any, toState: .State1)
XCTAssertNil(transition.fromState.value)
XCTAssertEqual(transition.toState.value, MyState.State1)
XCTAssertNil(transition.fromState.rawValue)
XCTAssertEqual(transition.toState.rawValue, MyState.State1)

// shorthand
let transition2 = .Any => MyState.State0
XCTAssertNil(transition2.fromState.value)
XCTAssertEqual(transition2.toState.value, MyState.State0)
XCTAssertNil(transition2.fromState.rawValue)
XCTAssertEqual(transition2.toState.rawValue, MyState.State0)
}

func testInit_toAny()
{
let transition = Transition<MyState>(fromState: .State0, toState: .Any)
XCTAssertEqual(transition.fromState.value, MyState.State0)
XCTAssertNil(transition.toState.value)
XCTAssertEqual(transition.fromState.rawValue, MyState.State0)
XCTAssertNil(transition.toState.rawValue)

// shorthand
let transition2 = MyState.State1 => .Any
XCTAssertEqual(transition2.fromState.value, MyState.State1)
XCTAssertNil(transition2.toState.value)
XCTAssertEqual(transition2.fromState.rawValue, MyState.State1)
XCTAssertNil(transition2.toState.rawValue)
}

func testNil()
Expand Down