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

Refactor code for better typing, naming, and RouteMapping support. #36

Merged
merged 28 commits into from
Dec 10, 2015
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
Refactor code by separating event-only-driven Machine and `StateMac…
…hine`.

- Add `Machine` (event-only-driven state machine).
- Add `Disposable` derived from ReactiveCocoa.
- Add Package.swift & change directory structure for Swift-Package-Manager.
  • Loading branch information
inamiy committed Dec 5, 2015
commit f7ce7483e33c3a0bf7ac6ae6d71f0988d17cdb31
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ DerivedData
*.xcuserstate

Carthage/Build
.build
Packages/
13 changes: 13 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// Package.swift
// SwiftState
//
// Created by Yasuhiro Inami on 2015-12-05.
// Copyright © 2015 Yasuhiro Inami. All rights reserved.
//

import PackageDescription

let package = Package(
name: "SwiftState"
)
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ enum MyEvent: EventType {
let machine = StateMachine<MyState, MyEvent>(state: .State0) { machine in

// add 0 => 1 => 2
machine.addRouteEvent(.Event0, transitions: [
machine.addRoute(event: .Event0, transitions: [
.State0 => .State1,
.State1 => .State2,
])
Expand All @@ -89,9 +89,8 @@ machine <-! .Event0
XCTAssertEqual(machine.state, MyState.State2)

// tryEvent
let success = machine <-! .Event0
XCTAssertEqual(machine.state, MyState.State2)
XCTAssertFalse(success, "Event0 doesn't have 2 => Any")
machine <-! .Event0
XCTAssertEqual(machine.state, MyState.State2, "Event0 doesn't have 2 => Any")
```

If there is no `Event`-based transition, use built-in `NoEvent` instead.
Expand Down Expand Up @@ -126,8 +125,9 @@ State Machine | `Machine` | State transition manager which c
Transition | `Transition` | `From-` and `to-` states represented as `.State1 => .State2`. Also, `.Any` can be used to represent _any state_.
Route | `Route` | `Transition` + `Condition`.
Condition | `Context -> Bool` | Closure for validating transition. If condition returns `false`, transition will fail and associated handlers will not be invoked.
Route Mapping | `(event: E?, fromState: S, userInfo: Any?) -> S?` | Another way of defining routes **using closure instead of transition arrows (`=>`)**. This is useful when state & event are enum with associated values. Return value (`S?`) means "preferred-toState", where passing `nil` means no routes available. See [#36](https://github.com/ReactKit/SwiftState/pull/36) for more info.
Handler | `Context -> Void` | Transition callback invoked after state has been changed.
Event Route Mapping | `(event: E?, fromState: S, userInfo: Any?) -> S?` | Another way of defining routes **using closure instead of transition arrows (`=>`)**. This is useful when state & event are enum with associated values. Return value (`S?`) means preferred-`toState`, where passing `nil` means no routes available. See [#36](https://github.com/ReactKit/SwiftState/pull/36) for more info.
State Route Mapping | `(fromState: S, userInfo: Any?) -> [S]?` | Another way of defining routes **using closure instead of transition arrows (`=>`)**. This is useful when state is enum with associated values. Return value (`[S]?`) means multiple `toState`s from single `fromState`. See [#36](https://github.com/ReactKit/SwiftState/pull/36) for more info.
Handler | `Context -> Void` | Transition callback invoked when state has been changed successfully.
Context | `(event: E?, fromState: S, toState: S, userInfo: Any?)` | Closure argument for `Condition` & `Handler`.
Chain | `TransitionChain` / `RouteChain` | Group of continuous routes represented as `.State1 => .State2 => .State3`

Expand Down
45 changes: 45 additions & 0 deletions Sources/Disposable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Disposable.swift
// ReactiveCocoa
//
// Created by Justin Spahr-Summers on 2014-06-02.
// Copyright (c) 2014 GitHub. All rights reserved.
//

//
// NOTE:
// This file is a partial copy from ReactiveCocoa v4.0.0-alpha.4 (removing `Atomic` dependency),
// which has not been taken out as microframework yet.
// https://github.com/ReactiveCocoa/ReactiveCocoa/issues/2579
//
// Note that `ActionDisposable` also works as `() -> ()` wrapper to help suppressing warning:
// "Expression resolved to unused function", when returned function was not used.
//

/// Represents something that can be “disposed,” usually associated with freeing
/// resources or canceling work.
public protocol Disposable {
/// Whether this disposable has been disposed already.
var disposed: Bool { get }

func dispose()
}

/// A disposable that will run an action upon disposal.
public final class ActionDisposable: Disposable {
private var action: (() -> ())?

public var disposed: Bool {
return action == nil
}

/// Initializes the disposable to run the given action upon disposal.
public init(action: () -> ()) {
self.action = action
}

public func dispose() {
self.action?()
self.action = nil
}
}
62 changes: 62 additions & 0 deletions Sources/EventType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// EventType.swift
// SwiftState
//
// Created by Yasuhiro Inami on 2014/08/05.
// Copyright (c) 2014年 Yasuhiro Inami. All rights reserved.
//

public protocol EventType: Hashable {}

// MARK: Event

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

public var value: E?
{
switch self {
case .Some(let x): return x
default: return nil
}
}

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

public func == <E: EventType>(lhs: Event<E>, rhs: Event<E>) -> Bool
{
switch (lhs, rhs) {
case let (.Some(x1), .Some(x2)) where x1 == x2:
return true
case (.Any, .Any):
return true
default:
return false
}
}

// MARK: NoEvent

/// Useful for creating StateMachine without events, i.e. `StateMachine<MyState, NoEvent>`.
public enum NoEvent: EventType
{
public var hashValue: Int
{
return 0
}
}

public func == (lhs: NoEvent, rhs: NoEvent) -> Bool
{
return true
}
File renamed without changes.
Loading