Skip to content

Commit 7b171ae

Browse files
author
Maciej Konieczny
committed
Merge branch 'LABSM-16-final-touches' into develop
2 parents d5ceca0 + af244db commit 7b171ae

3 files changed

Lines changed: 82 additions & 76 deletions

File tree

README.md

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ for clarity and maintainability. Can create diagrams:
77
![example digraph](example-digraph.png)
88

99
- Version 0.1.0 (following [Semantic Versioning][])
10-
- Developed and tested under Xcode 6.3β4 (Swift 1.2)
10+
- Developed and tested under Swift 1.2 (Xcode 6.3)
1111
- Published under the [MIT License](LICENSE)
1212
- [Carthage][] compatible
1313

@@ -31,12 +31,12 @@ Features
3131
--------
3232

3333
- Diagrams that can be automatically saved in your repo each time you run
34-
the app in a simulator
34+
the app in the simulator
3535
- Immutable, reusable state machine schemas
3636
- Readable state and event names — no long prefixes
37-
- Type safety: compile time errors when forgetting about a state or an
38-
event when defining the schema, when passing an event from a different
39-
state machine, etc.
37+
- Type safety: errors will appear at compilation when a state or an event
38+
are absent from schema, when passing an event from a different state
39+
machine, etc.
4040

4141

4242
Documentation
@@ -61,7 +61,7 @@ project. We recommend using [Carthage][Carthage add]:
6161
Example
6262
-------
6363

64-
In this example we're going to implement a simple state machine you've
64+
In this example, we're going to implement a simple state machine you've
6565
seen at the beginning of this file:
6666

6767
![example digraph](example-digraph.png)
@@ -78,14 +78,14 @@ enum Operation {
7878
}
7979
```
8080

81-
Next we have to specify the state machine layout. In SwiftyStateMachine
82-
it means creating a schema. Schemas are immutable `struct`s that can be
81+
Next, we have to specify the state machine layout. In SwiftyStateMachine,
82+
that means creating a schema. Schemas are immutable `struct`s that can be
8383
used by many `StateMachine` instances. They indicate the initial state
84-
and describe transition logic how states are connected via events and
84+
and describe transition logic, i.e. how states are connected via events and
8585
what code is executed during state transitions.
8686

8787
Schemas incorporate three generic types: `State` and `Event`, which we
88-
defined above, and `Subject`, which represents an object associated with
88+
defined above, and `Subject` which represents an object associated with
8989
a state machine. To keep things simple we won't use subject right now,
9090
so we'll specify its type as `Void`:
9191

@@ -114,10 +114,10 @@ let schema = StateMachineSchema<Number, Operation, Void>(initialState: .One) { (
114114
}
115115
```
116116

117-
You've probably expected nested `switch` statements after defining two
117+
You probably expected nested `switch` statements after defining two
118118
`enum`s. :wink:
119119

120-
To understand the above snippet, it's helpful to look at initializer's
120+
To understand the above snippet, it's helpful to look at the initializer's
121121
signature:
122122

123123
```swift
@@ -128,9 +128,9 @@ init(initialState: State,
128128
We specify transition logic as a block. It accepts two arguments: the
129129
current state and the event being handled. It returns an optional tuple
130130
of a new state and an optional transition block. When the tuple is
131-
`nil`, it indicates that there is no transition for given state-event
132-
pair, i.e. given event should be ignored in given state. When the
133-
tuple is non-`nil`, it specifies the new state that machine should
131+
`nil`, it indicates that there is no transition for a given state-event
132+
pair, i.e. a given event should be ignored in a given state. When the
133+
tuple is non-`nil`, it specifies the new state that the machine should
134134
transition to and a block that should be called after the transition.
135135
The transition block is optional. It gets passed a `Subject` object
136136
as an argument, which we ignored in this example by using `_`.
@@ -161,11 +161,11 @@ machine.didTransitionCallback = { (oldState, event, newState) in
161161

162162
OK, what about the diagram? SwiftyStateMachine can create diagrams in
163163
the [DOT][] graph description language. To create a diagram, we have
164-
to use `GraphableStateMachineSchema`, which has the same initializer as
164+
to use `GraphableStateMachineSchema` which has the same initializer as
165165
the regular `StateMachineSchema`, but requires state and event types to
166166
conform to the [`DOTLabelable`][DOTLabelable] protocol. This protocol
167167
makes sure that all elements have nice readable labels and that they are
168-
present on the graph at all (there's no way to automatically find all
168+
present on the graph (there's no way to automatically find all
169169
`enum` cases):
170170

171171
[DOT]: http://en.wikipedia.org/wiki/DOT_%28graph_description_language%29
@@ -200,7 +200,7 @@ extension Operation: DOTLabelable {
200200
}
201201
```
202202

203-
Notice that above code doesn't use a `switch` statement in
203+
Notice that the above code doesn't use a `switch` statement in the
204204
`DOTLabelableItems` implementation. We won't get a compiler error after
205205
adding a new case to an `enum`. To get some help from the compiler in
206206
such situations, we can use the following trick:
@@ -210,7 +210,7 @@ static var DOTLabelableItems: [Number] {
210210
let items: [Number] = [.One, .Two, .Three]
211211

212212
// Trick: switch on all cases and get an error if you miss any.
213-
// Copy and paste following cases to the array above.
213+
// Copy and paste the following cases to the array above.
214214
for item in items {
215215
switch item {
216216
case .One, .Two, .Three: break
@@ -222,8 +222,8 @@ static var DOTLabelableItems: [Number] {
222222
```
223223

224224
When our types conform to `DOTLabelable`, we can define our structure as
225-
before, but using `GraphableStateMachineSchema`. Then we can print the
226-
diagram:
225+
before, but this time using `GraphableStateMachineSchema`. Then we can
226+
print the diagram:
227227

228228
```swift
229229
let schema = GraphableStateMachineSchema// ...
@@ -249,15 +249,15 @@ digraph {
249249
```
250250

251251
[On iOS][] we can even have the graph file saved in the repo each time
252-
we run the app in a simulator:
252+
we run the app in the simulator:
253253

254254
[On iOS]: https://github.com/macoscope/SwiftyStateMachine/commit/9b4963c26a934915b56d5023f84e42ff128f6a1d
255255

256256
```swift
257257
schema.saveDOTDigraphIfRunningInSimulator(filepathRelativeToCurrentFile: "123.dot")
258258
```
259259

260-
DOT files can be viewed by a number of applications, including free
260+
DOT files can be viewed by a number of applications, including the free
261261
[Graphviz][]. If you use [Homebrew][], you can install Graphviz with
262262
the following commands:
263263

@@ -268,7 +268,7 @@ the following commands:
268268
[Graphviz]: http://www.graphviz.org/
269269
[Homebrew]: http://brew.sh/
270270

271-
Graphviz comes with a `dot` command, which can be used to generate graph
271+
Graphviz comes with a `dot` command which can be used to generate graph
272272
images without launching the GUI app:
273273

274274
dot -Tpng 123.dot > 123.png
@@ -317,18 +317,18 @@ class MyViewController: UIViewController {
317317
Development
318318
-----------
319319

320-
If you see a way to improve the project, please leave a comment, open an
321-
[issue][] or start a [pull request][]. It's better to begin
322-
with an issue rather than a pull request, though, because we might disagree
323-
whether proposed change is an actual improvement. :wink:
320+
If you see a way to improve the project, please leave a comment, open
321+
an [issue][] or start a [pull request][]. It's better to begin with
322+
an issue rather than a pull request, though, because we might disagree
323+
whether the proposed change is an actual improvement. :wink:
324324

325325
To run tests, install [Carthage][] and run `carthage update` to download
326326
and build test frameworks.
327327

328-
When introducing changes, please try to conform to the style present
329-
in the project — both with respect to code formatting and commit
330-
messages. We recommend following [GitHub Swift Style Guide][] with one
331-
important difference: 4 spaces instead of tabs.
328+
When introducing changes, please try to conform to the style present in
329+
the project — both with respect to code formatting and commit messages.
330+
We recommend following [GitHub Swift Style Guide][] with one important
331+
difference: 4 spaces instead of tabs.
332332

333333
Thanks! :v:
334334

StateMachine/GraphableStateMachineSchema.swift

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,24 @@ import Foundation
1212
/// [1]: http://en.wikipedia.org/wiki/DOT_%28graph_description_language%29
1313
public protocol DOTLabelable {
1414

15-
/// A textual representation of `self`, suitable for creating a label
15+
/// A textual representation of `self`, suitable for creating labels
1616
/// in a graph.
1717
var DOTLabel: String { get }
1818

19-
/// Array of items of given type (states or events) used in a graph.
19+
/// An array of items of a given type (states or events) used in a graph.
2020
static var DOTLabelableItems: [Self] { get }
2121
}
2222

2323

2424
/// A state machine schema with a graph of the state machine in the DOT graph
2525
/// description language [1].
2626
///
27-
/// Requires `State` and `Event` types to conform to `DOTLabelable` protocol.
27+
/// Requires `State` and `Event` types to conform to the `DOTLabelable`
28+
/// protocol.
2829
///
29-
/// Textual representation of a graph is accessible by `DOTDigraph` property.
30-
/// On iOS, it can be saved to disk with `saveDOTDigraphIfRunningInSimulator`
31-
/// method.
30+
/// The textual representation of a graph is accessible via the
31+
/// `DOTDigraph` property. On iOS, it can be saved to disk with
32+
/// the `saveDOTDigraphIfRunningInSimulator` method.
3233
///
3334
/// For more information about state machine schemas, see
3435
/// `StateMachineSchemaType` documentation.
@@ -50,28 +51,30 @@ public struct GraphableStateMachineSchema<A: DOTLabelable, B: DOTLabelable, C>:
5051
}
5152

5253
#if os(OSX)
53-
// TODO: Figure out how detect scenario "I'm running my Mac app from Xcode".
54+
// TODO: Figure out how to detect the "I'm running my Mac app from Xcode"
55+
// scenario.
5456
//
55-
// Verify if [`AmIBeingDebugged`][1] can be used here. In particular, figure out
56-
// if this means that an app will be rejected during App Review:
57+
// Verify if [`AmIBeingDebugged`][1] can be used here. In particular,
58+
// figure out if this means that an app will be rejected during App Review:
5759
//
58-
// > Important: Because the definition of the kinfo_proc structure (in <sys/sysctl.h>)
59-
// > is conditionalized by __APPLE_API_UNSTABLE, you should restrict use of the above
60-
// > code to the debug build of your program.
60+
// > Important: Because the definition of the kinfo_proc structure
61+
// > (in <sys/sysctl.h>) is conditionalized by __APPLE_API_UNSTABLE, you
62+
// > should restrict use of the above code to the debug build of your
63+
// > program.
6164
//
6265
// [1]: https://developer.apple.com/library/mac/qa/qa1361/_index.html
6366
#else
64-
/// Save textual graph representation from `DOTDigraph` property to a file,
65-
/// preferably in a project directory, for documentation purposes. Works
66-
/// only when running in a simulator.
67+
/// Save the textual graph representation from the `DOTDigraph` property
68+
/// to a file, preferably in a project directory, for documentation
69+
/// purposes. Works only when running in a simulator.
6770
///
68-
/// Filepath of the graph file is relative to the filepath of the calling
69-
/// file, e.g. if you call this method from a file called
71+
/// The filepath of the graph file is relative to the filepath of the
72+
/// calling file, e.g. if you call this method from a file called
7073
/// `MyProject/InboxViewController.swift` and pass `"Inbox.dot"` as
71-
/// a filepath, diagram will be saved as `MyProject/Inbox.dot`.
74+
/// a filepath, the diagram will be saved as `MyProject/Inbox.dot`.
7275
///
73-
/// Files in DOT format [1] can be viewed in different applications, e.g.
74-
/// Graphviz [2].
76+
/// Files in the DOT format [1] can be viewed in different applications,
77+
/// e.g. Graphviz [2].
7578
///
7679
/// [1]: https://developer.apple.com/library/mac/qa/qa1361/_index.html
7780
/// [2]: http://www.graphviz.org/

StateMachine/StateMachine.swift

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
/// A type representing schema that can be reused by `StateMachine` instances.
1+
/// A type representing schema that can be reused by `StateMachine`
2+
/// instances.
23
///
3-
/// Schema incorporates three generic types: `State` and `Event`, which should
4-
/// be `enum`s, and `Subject`, which represents an object associated with
5-
/// a state machine. If you don't want to associate any object, use `Void`
6-
/// as `Subject` type.
4+
/// The schema incorporates three generic types: `State` and `Event`,
5+
/// which should be `enum`s, and `Subject`, which represents an object
6+
/// associated with a state machine. If you don't want to associate any
7+
/// object, use `Void` as `Subject` type.
78
///
8-
/// Schema indicates the initial state and describes transition logic — how
9-
/// states are connected via events and what code is executed during state
10-
/// transitions. You specify transition logic as a block that accepts two
11-
/// arguments: current state and event being handled. It returns an optional
12-
/// tuple of a new state and an optional transition block. When the tuple is
13-
/// `nil`, it indicates that there is no transition for given state-event
14-
/// pair, i.e. given event should be ignored in given state. When the tuple
15-
/// is non-`nil`, it specifies the new state that machine should transition to
16-
/// and a block that should be called after the transition. The transition
17-
/// block is optional and it gets passed a `Subject` object as an argument.
9+
/// The schema indicates the initial state and describes the transition
10+
/// logic, i.e. how states are connected via events and what code is
11+
/// executed during state transitions. You specify transition logic
12+
/// as a block that accepts two arguments: the current state and the
13+
/// event being handled. It returns an optional tuple of a new state
14+
/// and an optional transition block. When the tuple is `nil`, it
15+
/// indicates that there is no transition for a given state-event pair,
16+
/// i.e. a given event should be ignored in a given state. When the
17+
/// tuple is non-`nil`, it specifies the new state that the machine
18+
/// should transition to and a block that should be called after the
19+
/// transition. The transition block is optional and it gets passed
20+
/// the `Subject` object as an argument.
1821
public protocol StateMachineSchemaType {
1922
typealias State
2023
typealias Event
@@ -27,8 +30,8 @@ public protocol StateMachineSchemaType {
2730
}
2831

2932

30-
/// A state machine schema conforming to `StateMachineSchemaType` protocol.
31-
/// See protocol's documentation for more information.
33+
/// A state machine schema conforming to the `StateMachineSchemaType`
34+
/// protocol. See protocol documentation for more information.
3235
public struct StateMachineSchema<A, B, C>: StateMachineSchemaType {
3336
typealias State = A
3437
typealias Event = B
@@ -44,11 +47,11 @@ public struct StateMachineSchema<A, B, C>: StateMachineSchemaType {
4447
}
4548

4649

47-
/// State machine for given schema, associated with given subject. See
50+
/// A state machine for a given schema, associated with a given subject. See
4851
/// `StateMachineSchemaType` documentation for more information about schemas
4952
/// and subjects.
5053
///
51-
/// State machine provides the `state` property for inspecting the current
54+
/// The state machine provides the `state` property for inspecting the current
5255
/// state and the `handleEvent` method for triggering state transitions
5356
/// defined in the schema.
5457
///
@@ -57,15 +60,15 @@ public struct StateMachineSchema<A, B, C>: StateMachineSchemaType {
5760
/// the state before the transition, the event causing the transition,
5861
/// and the state after the transition.
5962
public struct StateMachine<T: StateMachineSchemaType> {
60-
/// Current state of the machine.
63+
/// The current state of the machine.
6164
public var state: T.State
6265

63-
/// Optional block called after a transition with three arguments:
66+
/// An optional block called after a transition with three arguments:
6467
/// the state before the transition, the event causing the transition,
6568
/// and the state after the transition.
6669
public var didTransitionCallback: ((T.State, T.Event, T.State) -> ())?
6770

68-
/// Schema of the state machine. See `StateMachineSchemaType`
71+
/// The schema of the state machine. See `StateMachineSchemaType`
6972
/// documentation for more information.
7073
private let schema: T
7174

@@ -80,8 +83,8 @@ public struct StateMachine<T: StateMachineSchemaType> {
8083
}
8184

8285
/// A method for triggering transitions and changing the state of the
83-
/// machine. If transition logic of the schema defines a transition
84-
/// for current state and given event, the state is changed, optional
86+
/// machine. If the transition logic of the schema defines a transition
87+
/// for current state and given event, the state is changed, the optional
8588
/// transition block is executed, and `didTransitionCallback` is called.
8689
public mutating func handleEvent(event: T.Event) {
8790
if let (newState, transition) = schema.transitionLogic(state, event) {

0 commit comments

Comments
 (0)