├── .gitignore
├── .jazzy.yaml
├── .swift-version
├── .swiftformat
├── .tailor.yml
├── .travis.yml
├── CHANGELOG.md
├── Finite.playground
├── Contents.swift
├── contents.xcplayground
├── playground.xcworkspace
│ └── contents.xcworkspacedata
└── timeline.xctimeline
├── Finite.podspec
├── Finite.xcodeproj
├── FiniteTests_Info.plist
├── Finite_Info.plist
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── xcshareddata
│ └── xcschemes
│ └── Finite-Package.xcscheme
├── Finite.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ ├── IDEWorkspaceChecks.plist
│ └── WorkspaceSettings.xcsettings
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── LinuxMain.swift
├── Package.resolved
├── Package.swift
├── README.md
├── Scripts
└── docs-head.html
├── Sources
├── Ref.swift
├── StateFlow.swift
├── StateMachine.swift
└── Transition.swift
├── Tests
├── FiniteTests
│ ├── StateFlowTests.swift
│ ├── StateMachine.swift
│ ├── SwiftShim.swift
│ └── TransitionTests.swift
└── XCTestManifests.swift
├── codecov.yml
└── docs
├── Enums.html
├── Enums
└── TransitionError.html
├── Protocols.html
├── Protocols
└── ReferenceDisposable.html
├── Structs.html
├── Structs
├── StateFlow.html
├── StateMachine.html
└── Transition.html
├── Typealiases.html
├── badge.svg
├── css
├── highlight.css
└── jazzy.css
├── docsets
├── Finite.docset
│ └── Contents
│ │ ├── Info.plist
│ │ └── Resources
│ │ ├── Documents
│ │ ├── Enums.html
│ │ ├── Enums
│ │ │ └── TransitionError.html
│ │ ├── Protocols.html
│ │ ├── Protocols
│ │ │ └── ReferenceDisposable.html
│ │ ├── Structs.html
│ │ ├── Structs
│ │ │ ├── StateFlow.html
│ │ │ ├── StateMachine.html
│ │ │ └── Transition.html
│ │ ├── Typealiases.html
│ │ ├── badge.svg
│ │ ├── css
│ │ │ ├── highlight.css
│ │ │ └── jazzy.css
│ │ ├── img
│ │ │ ├── carat.png
│ │ │ ├── dash.png
│ │ │ ├── gh.png
│ │ │ └── spinner.gif
│ │ ├── index.html
│ │ ├── js
│ │ │ ├── jazzy.js
│ │ │ ├── jazzy.search.js
│ │ │ ├── jquery.min.js
│ │ │ ├── lunr.min.js
│ │ │ └── typeahead.jquery.js
│ │ ├── search.json
│ │ └── undocumented.json
│ │ └── docSet.dsidx
├── Finite.tgz
└── Finite.xml
├── img
├── carat.png
├── dash.png
├── gh.png
└── spinner.gif
├── index.html
├── js
├── jazzy.js
├── jazzy.search.js
├── jquery.min.js
├── lunr.min.js
└── typeahead.jquery.js
├── search.json
└── undocumented.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Mac
2 | .DS_Store
3 | ._*
4 |
5 | # VS Code
6 | ## Settings
7 | .vscode
8 |
9 | # Xcode
10 | ## Build generated
11 | .build/
12 | .swiftpm/
13 | build/
14 | DerivedData
15 |
16 | ## Various settings
17 | *.pbxuser
18 | !default.pbxuser
19 | *.mode1v3
20 | !default.mode1v3
21 | *.mode2v3
22 | !default.mode2v3
23 | *.perspectivev3
24 | !default.perspectivev3
25 | xcuserdata
26 |
27 | ## Other
28 | *.xccheckout
29 | *.moved-aside
30 | *.xcuserstate
31 | *.xcscmblueprint
32 |
33 | ## Docs
34 | # docs/
35 |
--------------------------------------------------------------------------------
/.jazzy.yaml:
--------------------------------------------------------------------------------
1 | author: Valentin Knabel
2 | author_url: https://twitter.com/vknabel
3 | github_url: https://github.com/vknabel/Finite
4 | module: Finite
5 | module_version: 4.0.0
6 | root_url: https://vknabel.github.io/Finite/
7 | readme: README.md
8 | output: docs/
9 | theme: fullwidth
10 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 5.3.1
2 |
--------------------------------------------------------------------------------
/.swiftformat:
--------------------------------------------------------------------------------
1 | --disable redundantSelf # ambiguous wait(for:timeout:)
2 | --tabwidth 4
--------------------------------------------------------------------------------
/.tailor.yml:
--------------------------------------------------------------------------------
1 | include:
2 | - Sources
3 | - Tests
4 | - Package.swift
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: generic
2 | sudo: required
3 | dist: trusty
4 | notifications:
5 | email: false
6 | os: linux
7 | matrix:
8 | include:
9 | - os: linux
10 | env:
11 | - SWIFT_VERSION=5.0.1
12 | install:
13 | - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
14 | - swift package resolve
15 | script:
16 | - swift build
17 | - swift test
18 | - os: linux
19 | env:
20 | - SWIFT_VERSION=5.3.1
21 | install:
22 | - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
23 | - swift package resolve
24 | script:
25 | - swift build
26 | - swift test
27 | - os: osx
28 | osx_image: xcode10.2
29 | env:
30 | - SWIFT_VERSION=system
31 | install:
32 | - swift package resolve
33 | script:
34 | - xcodebuild -scheme Finite -enableCodeCoverage YES test | xcpretty
35 | after_success:
36 | - bash <(curl -s https://codecov.io/bash)
37 | - os: osx
38 | osx_image: xcode12.2
39 | env:
40 | - SWIFT_VERSION=system
41 | install:
42 | - swift package resolve
43 | script:
44 | - xcodebuild -scheme Finite -enableCodeCoverage YES test | xcpretty
45 | after_success:
46 | - bash <(curl -s https://codecov.io/bash)
47 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 4.0.0
4 |
5 | The new Finite offers you two new features: temporarily subscribing transitions and observing any transitions at once.
6 |
7 | Use the new `onTransitions(perform:)` or `subscribeTransitions(perform:)` methods to observe all transitions.
8 | Temporarily `subscribeTransitions` of your State Machines and bind the callbacks to the lifetime of your View Controllers. Just don't forget to store the subscription to bind `self` as `weak` or `unowned`.
9 |
10 | ### Breaking Changes
11 |
12 | - Requires Swift 5
13 | - Previously passing `Transition.nilTransition` to `StateMachine.onTransitions(like:perform:)` did never trigger the `perform` handler and was therefore useless. Now it will always be triggered.
14 |
15 | ### Additions
16 |
17 | - Deprecated `StateMachine.onTransitions(transition:perform:)` in favor of `StateMachine.onTransitions(like:perform:)`.
18 | - The `StateMachine.onTransitions(perform:)` overload for `StateMachine.onTransitions(perform:)`.
19 | - Adds temporary observation of transitions `subscribeTransitions(like:perform:)`, `subscribeTransitions(perform:)`, `subscribeTransitions(from:perform:)`, `subscribeTransitions(to:perform:)`, `subscribeTransitions(from:to:perform:)`. All return a `ReferenceDisposable` which needs to be stored as a strong reference. On deinit, the handler will be freed.
20 |
21 | ### Upgrading to 4.0.0
22 |
23 | First bump your dependency version of Finite to `4.0.0`.
24 | When you compile your project, you won't experience compile errors. Instead you will receive compiler warnings whenever you used `StateMachine.onTransitions(transition:perform:)`. If there are no warnings, you already finished the upgrade.
25 |
26 | In case you passed `.nilTransition`: this did never work. Your `perform` operation has never been called!
27 | Starting from 4.0.0, `.nilTransition` operations will always be called.
28 |
29 | In case you did not pass a `.nilTransition`, apply the fix-it and use `onTransitions(like:perform:)` instead.
30 |
31 | ## 3.1.1
32 |
33 | ### Fixes
34 |
35 | - Avoid assertion failure by combining hash values instead of summing them up - @iLuke93 @snofla
36 |
37 | ## 3.1.0
38 |
39 | ### Additions
40 |
41 | - Introduced graphviz compatible descriptions - @snofla
42 |
43 | ## 3.0.3
44 |
45 | *Released: 2017-10-06*
46 |
47 | ### Other Changes
48 |
49 | - Readme updates - @vknabel
50 | - Proven Swift 4.0 support - @vknabel
51 |
52 | ## 3.0.2
53 |
54 | *Released: 2016-09-26*
55 |
56 | ### Other Changes
57 |
58 | - Fixes Testing error - @vknabel
59 |
60 | ## 3.0.1
61 |
62 | *Released: 2016-09-26*
63 |
64 | ### Other Changes
65 |
66 | - Added support for Travis builds - @vknabel
67 | - Added test support for Linux - @vknabel
68 | - Updated docs - @vknabel
69 |
70 | ## 3.0.0
71 |
72 | *Released: 2016-09-08*
73 |
74 | ### Breaking Changes
75 |
76 | - Dropped Swift 2.2 and 2.3 support - @vknabel
77 |
78 | ## 2.0.0
79 | *Released: 2016-08-22*
80 |
81 | ### Breaking Changes
82 |
83 | - Renamed Project from `StateMachine` to `Finite` - @vknabel
84 | - Renamed `StateMachine.triggerTransition(to:)` to `StateMachine.transition(to:)` - @vknabel
85 | - `StateMachine.transition(to:)` throws `TransitionError` and rethrows - @vknabel
86 |
87 | ### API Additions
88 |
89 | - `Operation`s may now throw - @vknabel
90 | - Added `TransitionError` - @vknabel
91 | - Added Swift 3.0 Support - @vknabel
92 | - Added generated Docs - @vknabel
93 |
94 | ### Other Changes
95 |
96 | - Added `CocoaPods` and `Swift Package Manager` support - @vknabel
97 | - Started this `CHANGELOG`.
98 |
99 |
--------------------------------------------------------------------------------
/Finite.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | // Playground - noun: a place where people can play
2 |
3 | import Finite
4 |
5 | enum Test: Int {
6 | case Saving, Fetching, Deleting
7 | case Ready, Fail
8 | }
9 |
10 | var machine = StateMachine(initial: .Ready) { c in
11 | c.allow(from: [.Saving, .Fetching, .Deleting], to: [.Ready, .Fail])
12 | c.allow(from: .Ready, to: [.Saving, .Fetching, .Deleting])
13 | }
14 |
15 | machine.onTransitions(from: .Ready) {
16 | print("From Ready: show activity indicator")
17 | }
18 |
19 | machine.onTransitions(to: .Ready) {
20 | print("To Ready: hide activity indicator")
21 | }
22 |
23 | machine.onTransitions(to: .Saving) {
24 | print("To: save")
25 | }
26 |
27 | try machine.transition(to: .Saving) {
28 | print("Triggered: save")
29 | }
30 |
31 | machine.state
32 |
33 | enum State: Hashable {
34 | case Ready
35 | case Error
36 | case Busy(T)
37 |
38 | var hashValue: Int {
39 | switch self {
40 | case .Ready:
41 | return 0
42 | case .Error:
43 | return 1
44 | case let .Busy(b):
45 | return 2 + b.hashValue
46 | }
47 | }
48 |
49 | var isBusy: Bool {
50 | switch self {
51 | case .Busy:
52 | return true
53 | default:
54 | return false
55 | }
56 | }
57 | }
58 |
59 | func == (lhs: State, rhs: State) -> Bool {
60 | switch (lhs, rhs) {
61 | case (.Ready, .Ready):
62 | return true
63 | case (.Error, .Error):
64 | return true
65 | case let (.Busy(lhb), .Busy(rhb)):
66 | return lhb == rhb
67 | default:
68 | return false
69 | }
70 | }
71 |
72 | enum Process {
73 | case Saving, Fetching, Deleting
74 | }
75 |
76 | var scnd = StateMachine>(initial: .Ready) { flow in
77 | // allow transitions from busy
78 | flow.allow(to: [.Ready, .Error]) { transition in
79 | transition.from?.isBusy ?? false
80 | }
81 | // allow transitions from ready to busy
82 | flow.allow(from: .Ready) { t in
83 | t.to?.isBusy ?? false
84 | }
85 | flow.allow(transition: Transition(from: nil, to: .Busy(.Deleting)))
86 | }
87 |
88 | do {
89 | try scnd.transition(to: State.Busy(.Deleting))
90 | } catch {
91 | print(error)
92 | }
93 |
--------------------------------------------------------------------------------
/Finite.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Finite.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Finite.playground/timeline.xctimeline:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Finite.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'Finite'
3 | s.version = '4.0.0'
4 | s.summary = 'A simple state machine written in Swift.'
5 | s.description = <<-DESC
6 | Finite is a simple, pure Swift finite state machine.
7 | DESC
8 | s.social_media_url = "https://twitter.com/vknabel"
9 | s.homepage = 'https://github.com/vknabel/Finite'
10 | s.license = { :type => 'MIT', :file => 'LICENSE' }
11 | s.author = { 'Valentin Knabel' => 'dev@vknabel.com' }
12 | s.source = { :git => 'https://github.com/vknabel/Finite.git', :tag => s.version.to_s }
13 | s.ios.deployment_target = '8.0'
14 | s.osx.deployment_target = '10.9'
15 | s.watchos.deployment_target = "2.0"
16 | s.tvos.deployment_target = "9.0"
17 | s.source_files = 'Sources/*.swift'
18 | end
19 |
--------------------------------------------------------------------------------
/Finite.xcodeproj/FiniteTests_Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundleDevelopmentRegion
5 | en
6 | CFBundleExecutable
7 | $(EXECUTABLE_NAME)
8 | CFBundleIdentifier
9 | $(PRODUCT_BUNDLE_IDENTIFIER)
10 | CFBundleInfoDictionaryVersion
11 | 6.0
12 | CFBundleName
13 | $(PRODUCT_NAME)
14 | CFBundlePackageType
15 | BNDL
16 | CFBundleShortVersionString
17 | 1.0
18 | CFBundleSignature
19 | ????
20 | CFBundleVersion
21 | $(CURRENT_PROJECT_VERSION)
22 | NSPrincipalClass
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Finite.xcodeproj/Finite_Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundleDevelopmentRegion
5 | en
6 | CFBundleExecutable
7 | $(EXECUTABLE_NAME)
8 | CFBundleIdentifier
9 | $(PRODUCT_BUNDLE_IDENTIFIER)
10 | CFBundleInfoDictionaryVersion
11 | 6.0
12 | CFBundleName
13 | $(PRODUCT_NAME)
14 | CFBundlePackageType
15 | FMWK
16 | CFBundleShortVersionString
17 | 1.0
18 | CFBundleSignature
19 | ????
20 | CFBundleVersion
21 | $(CURRENT_PROJECT_VERSION)
22 | NSPrincipalClass
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Finite.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
--------------------------------------------------------------------------------
/Finite.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Finite.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Finite.xcodeproj/xcshareddata/xcschemes/Finite-Package.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
21 |
22 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Finite.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Finite.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Finite.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 |
2 | gem "cocoapods"
3 | gem "jazzy"
4 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | specs:
3 | CFPropertyList (3.0.2)
4 | activesupport (5.2.4.4)
5 | concurrent-ruby (~> 1.0, >= 1.0.2)
6 | i18n (>= 0.7, < 2)
7 | minitest (~> 5.1)
8 | tzinfo (~> 1.1)
9 | addressable (2.7.0)
10 | public_suffix (>= 2.0.2, < 5.0)
11 | algoliasearch (1.27.5)
12 | httpclient (~> 2.8, >= 2.8.3)
13 | json (>= 1.5.1)
14 | atomos (0.1.3)
15 | claide (1.0.3)
16 | cocoapods (1.10.0)
17 | addressable (~> 2.6)
18 | claide (>= 1.0.2, < 2.0)
19 | cocoapods-core (= 1.10.0)
20 | cocoapods-deintegrate (>= 1.0.3, < 2.0)
21 | cocoapods-downloader (>= 1.4.0, < 2.0)
22 | cocoapods-plugins (>= 1.0.0, < 2.0)
23 | cocoapods-search (>= 1.0.0, < 2.0)
24 | cocoapods-trunk (>= 1.4.0, < 2.0)
25 | cocoapods-try (>= 1.1.0, < 2.0)
26 | colored2 (~> 3.1)
27 | escape (~> 0.0.4)
28 | fourflusher (>= 2.3.0, < 3.0)
29 | gh_inspector (~> 1.0)
30 | molinillo (~> 0.6.6)
31 | nap (~> 1.0)
32 | ruby-macho (~> 1.4)
33 | xcodeproj (>= 1.19.0, < 2.0)
34 | cocoapods-core (1.10.0)
35 | activesupport (> 5.0, < 6)
36 | addressable (~> 2.6)
37 | algoliasearch (~> 1.0)
38 | concurrent-ruby (~> 1.1)
39 | fuzzy_match (~> 2.0.4)
40 | nap (~> 1.0)
41 | netrc (~> 0.11)
42 | public_suffix
43 | typhoeus (~> 1.0)
44 | cocoapods-deintegrate (1.0.4)
45 | cocoapods-downloader (1.4.0)
46 | cocoapods-plugins (1.0.0)
47 | nap
48 | cocoapods-search (1.0.0)
49 | cocoapods-trunk (1.5.0)
50 | nap (>= 0.8, < 2.0)
51 | netrc (~> 0.11)
52 | cocoapods-try (1.2.0)
53 | colored2 (3.1.2)
54 | concurrent-ruby (1.1.7)
55 | escape (0.0.4)
56 | ethon (0.12.0)
57 | ffi (>= 1.3.0)
58 | ffi (1.13.1)
59 | fourflusher (2.3.1)
60 | fuzzy_match (2.0.4)
61 | gh_inspector (1.1.3)
62 | httpclient (2.8.3)
63 | i18n (1.8.5)
64 | concurrent-ruby (~> 1.0)
65 | jazzy (0.13.5)
66 | cocoapods (~> 1.5)
67 | mustache (~> 1.1)
68 | open4
69 | redcarpet (~> 3.4)
70 | rouge (>= 2.0.6, < 4.0)
71 | sassc (~> 2.1)
72 | sqlite3 (~> 1.3)
73 | xcinvoke (~> 0.3.0)
74 | json (2.3.1)
75 | liferaft (0.0.6)
76 | minitest (5.14.2)
77 | molinillo (0.6.6)
78 | mustache (1.1.1)
79 | nanaimo (0.3.0)
80 | nap (1.1.0)
81 | netrc (0.11.0)
82 | open4 (1.3.4)
83 | public_suffix (4.0.6)
84 | redcarpet (3.5.0)
85 | rouge (3.23.0)
86 | ruby-macho (1.4.0)
87 | sassc (2.4.0)
88 | ffi (~> 1.9)
89 | sqlite3 (1.4.2)
90 | thread_safe (0.3.6)
91 | typhoeus (1.4.0)
92 | ethon (>= 0.9.0)
93 | tzinfo (1.2.8)
94 | thread_safe (~> 0.1)
95 | xcinvoke (0.3.0)
96 | liferaft (~> 0.0.6)
97 | xcodeproj (1.19.0)
98 | CFPropertyList (>= 2.3.3, < 4.0)
99 | atomos (~> 0.1.3)
100 | claide (>= 1.0.2, < 2.0)
101 | colored2 (~> 3.1)
102 | nanaimo (~> 0.3.0)
103 |
104 | PLATFORMS
105 | ruby
106 |
107 | DEPENDENCIES
108 | cocoapods
109 | jazzy
110 |
111 | BUNDLED WITH
112 | 1.17.3
113 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Valentin Knabel
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import FiniteTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += FiniteTests.__allTests()
7 |
8 | XCTMain(tests)
9 |
--------------------------------------------------------------------------------
/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "Komondor",
6 | "repositoryURL": "https://github.com/shibapm/Komondor.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "3cd6d76887816ead5931ddbfb249c2935f518e17",
10 | "version": "1.0.4"
11 | }
12 | },
13 | {
14 | "package": "Logger",
15 | "repositoryURL": "https://github.com/shibapm/Logger",
16 | "state": {
17 | "branch": null,
18 | "revision": "53c3ecca5abe8cf46697e33901ee774236d94cce",
19 | "version": "0.2.3"
20 | }
21 | },
22 | {
23 | "package": "PackageConfig",
24 | "repositoryURL": "https://github.com/shibapm/PackageConfig.git",
25 | "state": {
26 | "branch": null,
27 | "revision": "bf90dc69fa0792894b08a0b74cf34029694ae486",
28 | "version": "0.13.0"
29 | }
30 | },
31 | {
32 | "package": "Rocket",
33 | "repositoryURL": "https://github.com/f-meloni/Rocket.git",
34 | "state": {
35 | "branch": null,
36 | "revision": "623cb4ccf55d708d082516ccd5cfea3dac8f9032",
37 | "version": "1.0.0"
38 | }
39 | },
40 | {
41 | "package": "ShellOut",
42 | "repositoryURL": "https://github.com/JohnSundell/ShellOut.git",
43 | "state": {
44 | "branch": null,
45 | "revision": "e1577acf2b6e90086d01a6d5e2b8efdaae033568",
46 | "version": "2.3.0"
47 | }
48 | },
49 | {
50 | "package": "SwiftFormat",
51 | "repositoryURL": "https://github.com/nicklockwood/SwiftFormat.git",
52 | "state": {
53 | "branch": null,
54 | "revision": "d9b7cf39e06e89428004a767d97006fb6d293c53",
55 | "version": "0.43.5"
56 | }
57 | },
58 | {
59 | "package": "SwiftShell",
60 | "repositoryURL": "https://github.com/kareman/SwiftShell",
61 | "state": {
62 | "branch": null,
63 | "revision": "fb7fc2c9ad8811caf324431a508fb79e3fb74f99",
64 | "version": "5.0.1"
65 | }
66 | },
67 | {
68 | "package": "Yams",
69 | "repositoryURL": "https://github.com/jpsim/Yams",
70 | "state": {
71 | "branch": null,
72 | "revision": "c947a306d2e80ecb2c0859047b35c73b8e1ca27f",
73 | "version": "2.0.0"
74 | }
75 | }
76 | ]
77 | },
78 | "version": 1
79 | }
80 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.0
2 | import PackageDescription
3 |
4 | let package = Package(
5 | name: "Finite",
6 | products: [
7 | .library(
8 | name: "Finite",
9 | targets: ["Finite"]
10 | ),
11 | ],
12 | dependencies: [
13 | .package(url: "https://github.com/shibapm/Komondor.git", from: "1.0.4"), // dev
14 | .package(url: "https://github.com/nicklockwood/SwiftFormat.git", from: "0.43.5"), // dev
15 | .package(url: "https://github.com/f-meloni/Rocket.git", from: "1.0.0"), // dev
16 | ],
17 | targets: [
18 | .target(name: "Finite", path: "Sources"),
19 | .testTarget(name: "FiniteTests", dependencies: ["Finite"], path: "Tests"),
20 | ]
21 | )
22 |
23 | #if canImport(PackageConfig)
24 | import PackageConfig
25 |
26 | let config = PackageConfiguration([
27 | "komondor": [
28 | "pre-push": "swift test",
29 | "pre-commit": [
30 | "swift package generate-xcodeproj --enable-code-coverage || true",
31 | "swift test --generate-linuxmain || true",
32 | "swift test",
33 | "swift run swiftformat Sources *.swift Tests",
34 | "git add .",
35 | ],
36 | ],
37 | "rocket": ["steps": [
38 | "jazzy --head \"$(cat Scripts/docs-head.html)\" --module-version $VERSION || true",
39 | ["script": ["content": "echo Release $VERSION"]],
40 | "hide_dev_dependencies",
41 | ["git_add": ["paths": ["Package.swift", "docs"]]],
42 | ["commit": ["no_verify": true]],
43 | "tag",
44 | "unhide_dev_dependencies",
45 | ["git_add": ["paths": ["Package.swift", "docs"]]],
46 | ["commit": ["no_verify": true, "message": "Unhide dev dependencies"]],
47 | "push",
48 | ]],
49 | ]).write()
50 | #endif
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | []()
2 | []()
3 | []()
4 | []()
5 |
6 | # Finite
7 |
8 | Finite is a simple, pure Swift finite state machine. Only exlicitly allowed transitions between states are allowed, otherwise an error will be thrown.
9 |
10 | | **Finite** | **Swift** |
11 | | ---------- | -------------------- |
12 | | `2.0.0` | `2.2` and `3.0 Beta` |
13 | | `3.x.x` | `3.0` and `4.0` |
14 | | `4.x.x` | `5.0` |
15 |
16 | ## Installation
17 |
18 | Finite has no external dependencies and supports [Swift Package Manager](https://github.com/apple/swift-package-manager), [Carthage](https://github.com/Carthage/Carthage) and [CocoaPods](https://github.com/CocoaPods/CocoaPods).
19 |
20 | ### Swift Package Manager
21 |
22 | ```swift
23 | import PackageDescription
24 |
25 | let package = Package(
26 | name: "YourPackage",
27 | dependencies: [
28 | .package(url: "https://github.com/vknabel/Finite.git", from: "4.0.0")
29 | ],
30 | targets: [
31 | .target(name: "YourTarget", dependencies: ["Finite"]),
32 | ]
33 | )
34 | ```
35 |
36 | ### Carthage
37 |
38 | ```ruby
39 | github "vknabel/Finite"
40 | ```
41 |
42 | ### CocoaPods
43 |
44 | ```ruby
45 | source 'https://github.com/CocoaPods/Specs.git'
46 | use_frameworks!
47 |
48 | pod 'Finite', '~> 4.0.0'
49 | ```
50 |
51 | ## Introduction
52 |
53 | It operates on a given type, where each value represents an internal state of the machine. A `StateMachine` is defined by providing all allowed state transitions.
54 |
55 | ```swift
56 | enum Test: Int {
57 | case saving, fetching, deleting
58 | case ready, fail
59 | }
60 |
61 | var machine = StateMachine(initial: .ready) { c in
62 | c.allow(from: [.saving, .fetching, .deleting], to: [.ready, .fail])
63 | c.allow(from: .ready, to: [.saving, .fetching, .deleting])
64 | }
65 | ```
66 |
67 | It is possible to provide callbacks, that will be called once certain transitions will happen.
68 |
69 | ```swift
70 | machine.onTransitions {
71 | println("Successfully triggered transition!")
72 | }
73 | machine.onTransitions(from: .ready) {
74 | println("From Ready: show activity indicator")
75 | }
76 | machine.onTransitions(to: .ready) {
77 | println("To Ready: hide activity indicator")
78 | }
79 | machine.onTransitions(to: .saving) {
80 | println("To: save")
81 | }
82 |
83 | let subscription = machine.subscribeTransitions(to: .saving) {
84 | println("Only triggered as long as you keep `subscription`")
85 | }
86 | ```
87 |
88 | Once the `StateMachine` has been set up, you may trigger all transitions you have declared above.
89 |
90 | ```swift
91 | try machine.transition(to: .saving) {
92 | println("Triggered: save")
93 | }
94 |
95 | // this will throw TransitionError.denied(from: .saving, to: .fetching)
96 | try machine.transition(to: .fetching)
97 | ```
98 |
99 | ## Author
100 |
101 | Valentin Knabel, dev@vknabel.com
102 |
103 | Special thanks to @snofla for allowing to export state machines to graphviz.
104 |
105 | ## License
106 |
107 | Finite is available under the [MIT](./LICENSE) license.
108 |
--------------------------------------------------------------------------------
/Scripts/docs-head.html:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/Sources/Ref.swift:
--------------------------------------------------------------------------------
1 | /// A subscription reference which needs to be referenced strongly.
2 | public protocol ReferenceDisposable {
3 | /// Disposes the current subscription. Current and future operations will be canceled.
4 | func dispose()
5 | }
6 |
7 | internal class Ref {
8 | private var value: () -> T?
9 |
10 | init(dereference: @escaping () -> T?) {
11 | value = dereference
12 | }
13 |
14 | func resolve() -> T? {
15 | value()
16 | }
17 |
18 | func free() {
19 | value = { nil }
20 | }
21 | }
22 |
23 | extension Ref {
24 | static func weak(_ value: T) -> (ReferenceDisposable, Ref) {
25 | let lifetime = Box(value)
26 | let weak = Weak(value: lifetime)
27 | return (
28 | lifetime,
29 | .init(dereference: { weak.value?.value })
30 | )
31 | }
32 |
33 | static func strong(_ value: T) -> Ref {
34 | .init(dereference: { value })
35 | }
36 |
37 | private struct Weak {
38 | fileprivate weak var value: Box?
39 | }
40 |
41 | private class Box: ReferenceDisposable {
42 | var value: T?
43 |
44 | init(_ value: T?) {
45 | self.value = value
46 | }
47 |
48 | func dispose() {
49 | value = nil
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Sources/StateFlow.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StateFlow.swift
3 | // StateMachine
4 | //
5 | // Created by Valentin Knabel on 19.02.15.
6 | // Copyright (c) 2015 Valentin Knabel. All rights reserved.
7 | //
8 |
9 | /// Represents a configuration of a state machine.
10 | public struct StateFlow: CustomStringConvertible {
11 | /// Filters wether a transition is allowed to be performed.
12 | public typealias TransitionFilter = (Transition) -> Bool
13 | /// Configures the instance for immutable usage.
14 | public typealias Configurator = (inout StateFlow) -> Void
15 |
16 | /// Empty array means transition is allowed.
17 | /// Once there is a single filter, all previous unconditioned transitions are omitted.
18 | private var transitionFilters: [Transition: TransitionFilter?] = [:]
19 |
20 | /**
21 | Creates a new instance that can be mutated to be stored immutable.
22 |
23 | - parameter config: A function that mutates the constructed instance.
24 | */
25 | public init(config: Configurator) {
26 | config(&self)
27 | }
28 |
29 | /// Creates a new instance to be used mutable.
30 | public init() {}
31 |
32 | /**
33 | Allows all less-equal general transitions to be triggered.
34 |
35 | - parameter transition: The transition allowing less-equal transitions.
36 | - parameter filter: An optional filter for transitions.
37 | */
38 | public mutating func allow(transition: Transition, filter: TransitionFilter? = nil) {
39 | if transitionFilters[transition] == nil {
40 | transitionFilters[transition] = filter
41 | }
42 | }
43 |
44 | /**
45 | Returns wether a specific transition is allowed or not.
46 | Invokes defined transition filters until one returned true or a transition is unconditioned.
47 |
48 | - parameter transition: The transition to be tested.
49 | - returns: Returns true if a more-equal transition is allowed.
50 | */
51 | public func allows(_ transition: Transition) -> Bool {
52 | for current in transition.generalTransitions {
53 | if let opf = transitionFilters[current] {
54 | let succ = opf?(current) ?? true
55 | if succ {
56 | return true
57 | }
58 | }
59 | }
60 | return false
61 | }
62 |
63 | /**
64 | Returns list of of transitions, sorted by the hash values of the
65 | from node
66 | */
67 | public var description: String {
68 | let graph = transitionFilters.sorted { (lhs, rhs) -> Bool in
69 | lhs.key.hashValue < rhs.key.hashValue
70 | }.compactMap { (transform) -> String? in
71 | transform.key.description
72 | }
73 | if graph.count > 0 {
74 | return graph.joined(separator: "\n")
75 | } else {
76 | return ""
77 | }
78 | }
79 | }
80 |
81 | public extension StateFlow {
82 | /**
83 | Convinience method that allows all less-equal general absolute transitions to be triggered.
84 |
85 | - parameter from: The source state.
86 | - parameter filter: An optional filter for transitions.
87 | */
88 | mutating func allow(from: T, filter: TransitionFilter? = nil) {
89 | allow(transition: Transition(from: from, to: nil), filter: filter)
90 | }
91 |
92 | /**
93 | Convinience method that allows all less-equal general absolute transitions to be triggered.
94 |
95 | - parameter to: The target state.
96 | - parameter filter: An optional filter for transitions.
97 | */
98 | mutating func allow(to: T, filter: TransitionFilter? = nil) {
99 | allow(transition: Transition(from: nil, to: to), filter: filter)
100 | }
101 |
102 | /**
103 | Convinience method that allows all less-equal general absolute transitions to be triggered.
104 |
105 | - parameter from: The source state.
106 | - parameter to: The target state.
107 | - parameter filter: An optional filter for transitions.
108 | */
109 | mutating func allow(from: T, to: T, filter: TransitionFilter? = nil) {
110 | allow(transition: Transition(from: from, to: to), filter: filter)
111 | }
112 |
113 | /**
114 | Convinience method that allows all less-equal general absolute transitions to be triggered.
115 |
116 | - parameter from: All source states.
117 | - parameter filter: An optional filter for transitions.
118 | */
119 | mutating func allow(from: [T], filter: TransitionFilter? = nil) {
120 | for f in from {
121 | allow(transition: Transition(from: f, to: nil), filter: filter)
122 | }
123 | }
124 |
125 | /**
126 | Convinience method that allows all less-equal general absolute transitions to be triggered.
127 |
128 | - parameter from: All source states.
129 | - parameter to: The target state.
130 | - parameter filter: An optional filter for transitions.
131 | */
132 | mutating func allow(from: [T], to: T, filter: TransitionFilter? = nil) {
133 | for f in from {
134 | allow(transition: Transition(from: f, to: to), filter: filter)
135 | }
136 | }
137 |
138 | /**
139 | Convinience method that allows all less-equal general absolute transitions to be triggered.
140 |
141 | - parameter to: All target states.
142 | - parameter filter: An optional filter for transitions.
143 | */
144 | mutating func allow(to: [T], filter: TransitionFilter? = nil) {
145 | for t in to {
146 | allow(transition: Transition(from: nil, to: t), filter: filter)
147 | }
148 | }
149 |
150 | /**
151 | Convinience method that allows all less-equal general absolute transitions to be triggered.
152 |
153 | - parameter from: The source state.
154 | - parameter to: All target states.
155 | - parameter filter: An optional filter for transitions.
156 | */
157 | mutating func allow(from: T, to: [T], filter: TransitionFilter? = nil) {
158 | for t in to {
159 | allow(transition: Transition(from: from, to: t), filter: filter)
160 | }
161 | }
162 |
163 | /**
164 | Convinience method that allows all less-equal general absolute transitions to be triggered.
165 |
166 | - parameter from: All source states.
167 | - parameter to: All target states.
168 | - parameter filter: An optional filter for transitions.
169 | */
170 | mutating func allow(from: [T], to: [T], filter: TransitionFilter? = nil) {
171 | for f in from {
172 | for t in to {
173 | allow(transition: Transition(from: f, to: t), filter: filter)
174 | }
175 | }
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/Sources/StateMachine.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StateMachine.swift
3 | // StateMachine
4 | //
5 | // Created by Valentin Knabel on 19.02.15.
6 | // Copyright (c) 2015 Valentin Knabel. All rights reserved.
7 | //
8 |
9 | /// Indicates that a transition failed.
10 | public enum TransitionError: Error {
11 | /// Represents a tried transition that is not allowed.
12 | case denied(from: T, to: T)
13 | }
14 |
15 | /// Represents a state machine.
16 | public struct StateMachine: CustomStringConvertible {
17 | /// An empty operation to be performed.
18 | public typealias Operation = () throws -> Void
19 | public typealias TransitionFilter = StateFlow.TransitionFilter
20 |
21 | /// Stores the current state.
22 | internal var currentState: T
23 | /// Stores the immutable state flow.
24 | internal let configuration: StateFlow
25 | /// Stores all transition handlers associated to transitions.
26 | internal var transitionHandlers: [Transition: [Ref]] = [:]
27 |
28 | /// The current state of the machine.
29 | public var state: T {
30 | currentState
31 | }
32 |
33 | /**
34 | Instantiates a state machine by configuring the StateFlow instance.
35 |
36 | - parameter initial: The initial state.
37 | - parameter config: A configurator for an instance of StateFlow.
38 | */
39 | public init(initial: T, config: StateFlow.Configurator) {
40 | currentState = initial
41 | configuration = StateFlow(config: config)
42 | }
43 |
44 | /**
45 | Instantiates a state machine by passing an instance of StateFlow.
46 |
47 | - parameter initial: The initial state.
48 | - parameter stateFlow: The state flow to be used as configuration.
49 | */
50 | public init(initial: T, stateFlow: StateFlow) {
51 | currentState = initial
52 | configuration = stateFlow
53 | }
54 |
55 | /**
56 | Triggers a transition to a given state and invokes a callback on completion.
57 |
58 | - parameter to: The targeted state.
59 | - parameter completion: An optional callback. Will be only be called on success and after all defined transition handlers were invoked.
60 | - throws: Either TransitionError or rethrows underlying errors.
61 | - returns: Wether the transition could be performed or not.
62 | */
63 | public mutating func transition(to: T, completion: Operation? = nil) throws {
64 | let transition = self.transition(to: to)
65 | if configuration.allows(transition) {
66 | for t in transition.generalTransitions + [.nilTransition] {
67 | if let handlers = self.transitionHandlers[t] {
68 | for h in handlers {
69 | try h.resolve()?() // rethrows
70 | }
71 | }
72 | transitionHandlers[t]?.removeAll(where: { $0.resolve() == nil })
73 | }
74 | currentState = to
75 | try completion?()
76 | } else {
77 | throw TransitionError.denied(from: currentState, to: to)
78 | }
79 | }
80 |
81 | /**
82 | Returns wether transitioning to a state is allowed.
83 |
84 | - parameter to: The targeted state.
85 | - returns: true if allowed else false.
86 | */
87 | public func allows(to: T) -> Bool {
88 | configuration.allows(transition(to: to))
89 | }
90 |
91 | private mutating func observeTransitions(like transition: Transition, perform opRef: Ref) {
92 | if transitionHandlers[transition] == nil {
93 | transitionHandlers[transition] = []
94 | }
95 | transitionHandlers[transition]?.append(opRef)
96 | }
97 |
98 | /**
99 | Appends a transition handler for all more-equal general transitions.
100 |
101 | - parameter transition: The most specific transition.
102 | - parameter perform: The operation the be performed.
103 | */
104 | public mutating func onTransitions(like transition: Transition = .nilTransition, perform op: @escaping Operation) {
105 | observeTransitions(like: transition, perform: .strong(op))
106 | }
107 |
108 | /**
109 | Appends a transition handler for all more-equal general transitions.
110 |
111 | - parameter transition: The most specific transition.
112 | - parameter perform: The operation the be performed.
113 | */
114 | public mutating func subscribeTransitions(like transition: Transition = .nilTransition, perform op: @escaping Operation) -> ReferenceDisposable {
115 | let (subscription, ref) = Ref.weak(op)
116 | observeTransitions(like: transition, perform: ref)
117 | return subscription
118 | }
119 |
120 | /**
121 | Returns the graph for the state machine
122 | */
123 | public var description: String {
124 | let result = "digraph {\n" + "graph [rankdir=LR]\n" + configuration.description + "\n}\n"
125 | return result
126 | }
127 | }
128 |
129 | internal extension StateMachine {
130 | /// - returns: A transition from the current state to a given target.
131 | private func transition(to: T) -> Transition {
132 | Transition(from: currentState, to: to)
133 | }
134 | }
135 |
136 | public extension StateMachine {
137 | /**
138 | Appends a transition handler for all more-equal general transitions.
139 |
140 | - parameter from: The source state.
141 | - parameter to: The target state.
142 | - parameter perform: The operation the be performed.
143 | */
144 | mutating func onTransitions(from: T, to: T, perform op: @escaping Operation) {
145 | let transition = Transition(from: from, to: to)
146 | onTransitions(like: transition, perform: op)
147 | }
148 |
149 | /**
150 | Appends a transition handler for all more-equal general transitions.
151 |
152 | - parameter from: The source state.
153 | - parameter to: The target state.
154 | - parameter perform: The operation the be performed.
155 | - returns: subcription which needs to be kept.
156 | */
157 | mutating func subscribeTransitions(from: T, to: T, perform op: @escaping Operation) -> ReferenceDisposable {
158 | let transition = Transition(from: from, to: to)
159 | return subscribeTransitions(like: transition, perform: op)
160 | }
161 |
162 | /**
163 | Appends a transition handler for all more-equal general transitions.
164 |
165 | - parameter from: The source state.
166 | - parameter perform: The operation the be performed.
167 | */
168 | mutating func onTransitions(from: T, perform op: @escaping Operation) {
169 | let transition = Transition(from: from, to: nil)
170 | onTransitions(like: transition, perform: op)
171 | }
172 |
173 | /**
174 | Appends a transition handler for all more-equal general transitions.
175 |
176 | - parameter from: The source state.
177 | - parameter perform: The operation the be performed.
178 | - returns: subcription which needs to be kept.
179 | */
180 | mutating func subscribeTransitions(from: T, perform op: @escaping Operation) -> ReferenceDisposable {
181 | let transition = Transition(from: from, to: nil)
182 | return subscribeTransitions(like: transition, perform: op)
183 | }
184 |
185 | /**
186 | Appends a transition handler for all more-equal general transitions.
187 |
188 | - parameter to: The target state.
189 | - parameter perform: The operation the be performed.
190 | */
191 | mutating func onTransitions(to: T, perform op: @escaping Operation) {
192 | let transition = Transition(from: nil, to: to)
193 | onTransitions(like: transition, perform: op)
194 | }
195 |
196 | /**
197 | Appends a transition handler for all more-equal general transitions.
198 |
199 | - parameter to: The target state.
200 | - parameter perform: The operation the be performed.
201 | - returns: subcription which needs to be kept.
202 | */
203 | mutating func subscribeTransitions(to: T, perform op: @escaping Operation) -> ReferenceDisposable {
204 | let transition = Transition(from: nil, to: to)
205 | return subscribeTransitions(like: transition, perform: op)
206 | }
207 | }
208 |
209 | public extension StateMachine {
210 | /**
211 | Appends a transition handler for all more-equal general transitions.
212 | Deprecated, use `StateMachine.onTransitions(like:perform:)` instead.
213 | Operations for .nilTransition will now be performed for every transition.
214 |
215 | - parameter transition: The most specific transition.
216 | - parameter perform: The operation the be performed.
217 | */
218 | @available(*, renamed: "onTransitions(like:perform:)", deprecated, message: "Operations for .nilTransition will now be performed for every transition")
219 | mutating func onTransitions(transition: Transition, perform op: @escaping Operation) {
220 | observeTransitions(like: transition, perform: .strong(op))
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/Sources/Transition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Transition.swift
3 | // StateMachine
4 | //
5 | // Created by Valentin Knabel on 19.02.15.
6 | // Copyright (c) 2015 Valentin Knabel. All rights reserved.
7 | //
8 |
9 | /**
10 | The Transition class represents a transition from a given state to a targeted state.
11 | There are three types of transitions:
12 |
13 | 1. Absolute Transitions have a source and a target state set.
14 | 2. Relative Transitions have only one state set.
15 | 3. Nil Transitions have none states set and will be ignored.
16 | */
17 | public struct Transition: Hashable, CustomStringConvertible {
18 | /// Nil transitions will be ignored.
19 | public static var nilTransition: Transition {
20 | Transition(from: nil, to: nil)
21 | }
22 |
23 | /// The source state.
24 | public var from: T?
25 | /// The targeted state.
26 | public var to: T?
27 |
28 | /**
29 | Constructs an absolute, relative or nil transition.
30 |
31 | - parameter from: The source state.
32 | - parameter to: The target state.
33 | */
34 | public init(from: T?, to: T?) {
35 | self.from = from
36 | self.to = to
37 | }
38 |
39 | /**
40 | All more general transitions include itself except the nil transition.
41 |
42 | - returns: All general transitions.
43 |
44 | - Generals of an absolute transition is itself and relative transitions.
45 | - Generals of a relative transition is only itself.
46 | - Nil transitions have no generals.
47 | */
48 | public var generalTransitions: Set {
49 | var generals = Set([self, Transition(from: from, to: nil), Transition(from: nil, to: to)])
50 | generals.remove(.nilTransition)
51 | return generals
52 | }
53 |
54 | public var description: String {
55 | let f = from != nil ? String(describing: from!) : "any"
56 | let t = to != nil ? String(describing: to!) : "any"
57 | return "\(f) -> \(t)"
58 | }
59 |
60 | public func hash(into hasher: inout Hasher) {
61 | hasher.combine(from)
62 | hasher.combine(to)
63 | }
64 | }
65 |
66 | /// :nodoc:
67 | public func == (lhs: Transition, rhs: Transition) -> Bool {
68 | lhs.from == rhs.from && lhs.to == rhs.to
69 | }
70 |
--------------------------------------------------------------------------------
/Tests/FiniteTests/StateMachine.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StateMachine.swift
3 | // FiniteTests
4 | //
5 | // Created by Valentin Knabel on 06.11.17.
6 | //
7 |
8 | import Finite
9 | import XCTest
10 |
11 | class StateMachineTests: XCTestCase {
12 | enum Test {
13 | case s0, s1
14 | }
15 |
16 | var sut: StateMachine!
17 |
18 | override func setUp() {
19 | sut = nil
20 | }
21 |
22 | func testCreatingStateMachineWillSetState() {
23 | prepare(initial: .s0, allowing: Transition(from: .s0, to: .s1))
24 | XCTAssertEqual(sut.state, .s0)
25 | }
26 |
27 | func testAllowedTransitionsDoNotThrowAndAdjustTheState() {
28 | prepare(allowing: Transition(from: .s0, to: .s1))
29 | XCTAssertNoThrow(try sut.transition(to: .s1))
30 | XCTAssertEqual(sut.state, .s1)
31 | }
32 |
33 | func testNotAllowedTransitionsDoThrowAndKeepTheState() {
34 | prepare(initial: .s0, allowing: Transition(from: .s0, to: .s1))
35 | let action = { try self.sut.transition(to: .s0) }
36 | XCTAssertThrowsError(try action()) { error in
37 | if case let .denied(from: from, to: to) = error as? TransitionError {
38 | XCTAssertEqual(from, .s0)
39 | XCTAssertEqual(to, .s0)
40 | } else {
41 | XCTFail()
42 | }
43 | }
44 | XCTAssertEqual(sut.state, .s0)
45 | }
46 |
47 | func testOnTransitionsForNilTransitionTriggered() throws {
48 | prepare(allowing: Transition(from: .s0, to: .s1))
49 | let calledOnNilTransitions = expectation(description: "onTransitions(like:_:) called")
50 | sut.onTransitions(like: .nilTransition) {
51 | calledOnNilTransitions.fulfill()
52 | }
53 | let calledOnDefaultTransitions = expectation(description: "onTransitions(_:) called")
54 | sut.onTransitions {
55 | calledOnDefaultTransitions.fulfill()
56 | }
57 | try sut.transition(to: .s1)
58 | self.wait(for: [calledOnNilTransitions, calledOnDefaultTransitions], timeout: 0.1)
59 | }
60 |
61 | func testSubscribeTransitionsForNilTransitionTriggeredWhenHold() throws {
62 | var disposeBag = [ReferenceDisposable]()
63 | prepare(allowing: Transition(from: .s0, to: .s1))
64 | let calledOnNilTransitions = expectation(description: "subscribeTransitions(like:_:) called")
65 | disposeBag.append(sut.subscribeTransitions(like: .nilTransition) {
66 | calledOnNilTransitions.fulfill()
67 | })
68 | let calledOnDefaultTransitions = expectation(description: "subscribeTransitions(_:) called")
69 | disposeBag.append(sut.subscribeTransitions {
70 | calledOnDefaultTransitions.fulfill()
71 | })
72 | try sut.transition(to: .s1)
73 | self.wait(for: [calledOnNilTransitions, calledOnDefaultTransitions], timeout: 0.1)
74 | }
75 |
76 | func testSubscribeTransitionsForNilTransitionNeverTriggeredWhenNotHold() throws {
77 | prepare(allowing: Transition(from: .s0, to: .s1))
78 | let calledOnNilTransitions = expectation(description: "subscribeTransitions(like:_:) called")
79 | calledOnNilTransitions.isInverted = true
80 | _ = sut.subscribeTransitions(like: .nilTransition) {
81 | calledOnNilTransitions.fulfill()
82 | }
83 | let calledOnDefaultTransitions = expectation(description: "subscribeTransitions(_:) called")
84 | calledOnDefaultTransitions.isInverted = true
85 | _ = sut.subscribeTransitions {
86 | calledOnDefaultTransitions.fulfill()
87 | }
88 | try sut.transition(to: .s1)
89 | self.wait(for: [calledOnNilTransitions, calledOnDefaultTransitions], timeout: 0.1)
90 | }
91 |
92 | func testOnTransitionsTriggeredOnExactTransition() throws {
93 | prepare(allowing: Transition(from: .s0, to: .s1))
94 | let calledOnTransitions = expectation(description: "onTransitions(like:_:) called")
95 | sut.onTransitions(like: Transition(from: .s0, to: .s1)) {
96 | calledOnTransitions.fulfill()
97 | }
98 | let calledOnTransitionsTo = expectation(description: "onTransitions(to:_:) called")
99 | sut.onTransitions(to: .s1) {
100 | calledOnTransitionsTo.fulfill()
101 | }
102 | let calledOnTransitionsFrom = expectation(description: "onTransitions(from:_:) called")
103 | sut.onTransitions(from: .s0) {
104 | calledOnTransitionsFrom.fulfill()
105 | }
106 | let calledOnTransitionsFromTo = expectation(description: "onTransitions(from:to:_:) called")
107 | sut.onTransitions(from: .s0, to: .s1) {
108 | calledOnTransitionsFromTo.fulfill()
109 | }
110 |
111 | try sut.transition(to: .s1)
112 | self.wait(for: [calledOnTransitions, calledOnTransitionsTo, calledOnTransitionsFrom, calledOnTransitionsFromTo], timeout: 1)
113 | }
114 |
115 | func testOnTransitionsNeverTriggeredOnSwappedTransition() throws {
116 | prepare(allowing: Transition(from: .s0, to: .s1))
117 |
118 | let anyCalled = expectation(description: "any transition called")
119 | anyCalled.isInverted = true
120 | sut.onTransitions(like: Transition(from: .s1, to: .s0)) {
121 | anyCalled.fulfill()
122 | }
123 | sut.onTransitions(to: .s0) {
124 | anyCalled.fulfill()
125 | }
126 | sut.onTransitions(from: .s1) {
127 | anyCalled.fulfill()
128 | }
129 | sut.onTransitions(from: .s1, to: .s0) {
130 | anyCalled.fulfill()
131 | }
132 |
133 | try sut.transition(to: .s1)
134 | self.wait(for: [anyCalled], timeout: 0.1)
135 | }
136 |
137 | func testSubscribedTransitionsTriggeredOnExactTransitionWhenStored() throws {
138 | var disposeBag = [ReferenceDisposable]()
139 | prepare(allowing: Transition(from: .s0, to: .s1))
140 | let calledSubscribeTransitions = expectation(description: "subscribeTransitions(like:_:) called")
141 | disposeBag.append(sut.subscribeTransitions(like: Transition(from: .s0, to: .s1)) {
142 | calledSubscribeTransitions.fulfill()
143 | })
144 | let calledSubscribeTransitionsTo = expectation(description: "subscribeTransitions(to:_:) called")
145 | disposeBag.append(sut.subscribeTransitions(to: .s1) {
146 | calledSubscribeTransitionsTo.fulfill()
147 | })
148 | let calledSubscribeTransitionsFrom = expectation(description: "subscribeTransitions(from:_:) called")
149 | disposeBag.append(sut.subscribeTransitions(from: .s0) {
150 | calledSubscribeTransitionsFrom.fulfill()
151 | })
152 | let calledSubscribeTransitionsFromTo = expectation(description: "subscribeTransitions(from:to:_:) called")
153 | disposeBag.append(sut.subscribeTransitions(from: .s0, to: .s1) {
154 | calledSubscribeTransitionsFromTo.fulfill()
155 | })
156 |
157 | try sut.transition(to: .s1)
158 | self.wait(for: [calledSubscribeTransitions, calledSubscribeTransitionsTo, calledSubscribeTransitionsFrom, calledSubscribeTransitionsFromTo], timeout: 0.1)
159 | }
160 |
161 | func testSubscribedTransitionsNeverTriggeredOnExactTransitionWhenNotStored() throws {
162 | prepare(allowing: Transition(from: .s0, to: .s1))
163 | let anyCalled = expectation(description: "any subscribeTransitions called")
164 | anyCalled.isInverted = true
165 |
166 | _ = sut.subscribeTransitions(like: Transition(from: .s0, to: .s1)) {
167 | anyCalled.fulfill()
168 | }
169 | _ = sut.subscribeTransitions(to: .s1) {
170 | anyCalled.fulfill()
171 | }
172 | _ = sut.subscribeTransitions(from: .s0) {
173 | anyCalled.fulfill()
174 | }
175 | _ = sut.subscribeTransitions(from: .s0, to: .s1) {
176 | anyCalled.fulfill()
177 | }
178 |
179 | try sut.transition(to: .s1)
180 | self.wait(for: [anyCalled], timeout: 1)
181 | }
182 |
183 | private func prepare(initial state: Test = .s0, allowing transitions: Transition...) {
184 | sut = StateMachine(initial: state) { flow in
185 | for t in transitions {
186 | flow.allow(transition: t)
187 | }
188 | }
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/Tests/FiniteTests/SwiftShim.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftShim.swift
3 | // FiniteTests
4 | //
5 | // Created by Valentin Knabel on 07.11.17.
6 | //
7 |
8 | import XCTest
9 |
10 | #if !swift(>=4.0)
11 |
12 | func XCTAssertNoThrow(_ expression: @autoclosure () throws -> T, _ message: @autoclosure () -> String = "XCTAssertNoThrow", file: StaticString = #file, line: UInt = #line) {
13 | do {
14 | _ = try expression()
15 | } catch {
16 | XCTFail(message(), file: file, line: line)
17 | }
18 | }
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/Tests/FiniteTests/TransitionTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransitionTests.swift
3 | // StateMachine
4 | //
5 | // Created by Valentin Knabel on 20.02.15.
6 | // Copyright (c) 2015 Valentin Knabel. All rights reserved.
7 | //
8 |
9 | import Finite
10 | import XCTest
11 |
12 | class TransitionTests: XCTestCase {
13 | enum Test {
14 | case s0, s1
15 | }
16 |
17 | var nilt: Transition!
18 | var relft: Transition!
19 | var reltt: Transition!
20 | var abst: Transition!
21 | var abstr: Transition!
22 | var ts: [Transition]! {
23 | [nilt, relft, reltt, abst, abstr]
24 | }
25 |
26 | override func setUp() {
27 | nilt = Transition.nilTransition
28 | relft = Transition(from: Test.s0, to: nil)
29 | reltt = Transition(from: nil, to: Test.s1)
30 | abst = Transition(from: Test.s0, to: Test.s1)
31 | abstr = Transition(from: Test.s1, to: Test.s0)
32 | }
33 |
34 | func testAbsolute() {
35 | if abst.from == nil || abst.to == nil {
36 | XCTFail("Absolute Transition")
37 | }
38 | }
39 |
40 | func testRelative() {
41 | if relft.from == nil || relft.to != nil {
42 | XCTFail("Source Transition")
43 | }
44 |
45 | if reltt.from != nil || reltt.to == nil {
46 | XCTFail("Target Transition")
47 | }
48 | }
49 |
50 | func testNil() {
51 | let nilt = Transition(from: nil, to: nil)
52 | if nilt.from != nil || nilt.from != nil {
53 | XCTFail("Nil Transition")
54 | }
55 | }
56 |
57 | func testEqualty() {
58 | for li in 0 ..< ts.count {
59 | for ri in 0 ..< ts.count {
60 | XCTAssertEqual(ts[li] == ts[ri], li == ri, "Diagonal equal, else unequal")
61 | }
62 | }
63 | }
64 |
65 | func testHash() {
66 | // cannot test for unequalty => there may always be collisions
67 | for i in 0 ..< ts.count {
68 | XCTAssertEqual(ts[i].hashValue, ts[i].hashValue, "Diagonal hash equal")
69 | }
70 | }
71 |
72 | func testGeneral() {
73 | XCTAssertEqual(nilt.generalTransitions, [], "Nil transition generals")
74 | XCTAssertEqual(relft.generalTransitions, [relft], "Relative source transition generals")
75 | XCTAssertEqual(reltt.generalTransitions, [reltt], "Relative target transition generals")
76 | XCTAssertEqual(abst.generalTransitions, [abst, relft, reltt], "Absolute transition generals")
77 | }
78 |
79 | func testDescription() {
80 | XCTAssertEqual(nilt.description, "any -> any")
81 | XCTAssertEqual(relft.description, "s0 -> any")
82 | XCTAssertEqual(reltt.description, "any -> s1")
83 | XCTAssertEqual(abst.description, "s0 -> s1")
84 | XCTAssertEqual(abstr.description, "s1 -> s0")
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Tests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | #if !canImport(ObjectiveC)
2 | import XCTest
3 |
4 | extension StateFlowTests {
5 | // DO NOT MODIFY: This is autogenerated, use:
6 | // `swift test --generate-linuxmain`
7 | // to regenerate.
8 | static let __allTests__StateFlowTests = [
9 | ("testAllowingConvenienceFromRelativeTransitionHelper", testAllowingConvenienceFromRelativeTransitionHelper),
10 | ("testAllowingConvenienceToRelativeTransitionHelper", testAllowingConvenienceToRelativeTransitionHelper),
11 | ("testAllowingEverythingMultipleConvenienceFromToAbsoluteTransitionHelperForEveryState", testAllowingEverythingMultipleConvenienceFromToAbsoluteTransitionHelperForEveryState),
12 | ("testAllowingMultipleConvenienceFromAbsoluteTransitionHelper", testAllowingMultipleConvenienceFromAbsoluteTransitionHelper),
13 | ("testAllowingMultipleConvenienceFromRelativeTransitionHelper", testAllowingMultipleConvenienceFromRelativeTransitionHelper),
14 | ("testAllowingMultipleConvenienceFromToAbsoluteTransitionHelper", testAllowingMultipleConvenienceFromToAbsoluteTransitionHelper),
15 | ("testAllowingMultipleConvenienceToAbsoluteTransitionHelper", testAllowingMultipleConvenienceToAbsoluteTransitionHelper),
16 | ("testAllowingMultipleConvenienceToRelativeTransitionHelper", testAllowingMultipleConvenienceToRelativeTransitionHelper),
17 | ("testAllowsAbsoluteTransitionsWhenAddedPreviously", testAllowsAbsoluteTransitionsWhenAddedPreviously),
18 | ("testAllowsAbsoluteTransitionsWhenAddedPreviouslyUsingEmptyInitializer", testAllowsAbsoluteTransitionsWhenAddedPreviouslyUsingEmptyInitializer),
19 | ("testAllowsAbsoluteTransitionWhenFromRelativeIsAllowed", testAllowsAbsoluteTransitionWhenFromRelativeIsAllowed),
20 | ("testAllowsAbsoluteTransitionWhenToRelativeIsAllowed", testAllowsAbsoluteTransitionWhenToRelativeIsAllowed),
21 | ("testAllowsAlwaysSucceedingFilter", testAllowsAlwaysSucceedingFilter),
22 | ("testAllowsFromRelativeTransitionsWhenAddedPreviously", testAllowsFromRelativeTransitionsWhenAddedPreviously),
23 | ("testAllowsToRelativeTransitionsWhenAddedPreviously", testAllowsToRelativeTransitionsWhenAddedPreviously),
24 | ("testDeniesAlwaysDenyingFilter", testDeniesAlwaysDenyingFilter),
25 | ("testDescriptionWithContents", testDescriptionWithContents),
26 | ("testDescriptionWithoutContents", testDescriptionWithoutContents),
27 | ("testDoesNotAllowAbsoluteTransitionsWhenAddedNilPreviously", testDoesNotAllowAbsoluteTransitionsWhenAddedNilPreviously),
28 | ("testDoesNotAllowNilTransitionsWhenAddedPreviously", testDoesNotAllowNilTransitionsWhenAddedPreviously),
29 | ("testDoesNotAllowTransitionsToSameStateByDefault", testDoesNotAllowTransitionsToSameStateByDefault),
30 | ("testDoesNotAllowUnrelatedAbsoluteTransitions", testDoesNotAllowUnrelatedAbsoluteTransitions),
31 | ("testEmptyDeniesEverything", testEmptyDeniesEverything),
32 | ("testEmptyDeniesEverythingForConfig", testEmptyDeniesEverythingForConfig),
33 | ]
34 | }
35 |
36 | extension StateMachineTests {
37 | // DO NOT MODIFY: This is autogenerated, use:
38 | // `swift test --generate-linuxmain`
39 | // to regenerate.
40 | static let __allTests__StateMachineTests = [
41 | ("testAllowedTransitionsDoNotThrowAndAdjustTheState", testAllowedTransitionsDoNotThrowAndAdjustTheState),
42 | ("testCreatingStateMachineWillSetState", testCreatingStateMachineWillSetState),
43 | ("testNotAllowedTransitionsDoThrowAndKeepTheState", testNotAllowedTransitionsDoThrowAndKeepTheState),
44 | ("testOnTransitionsForNilTransitionTriggered", testOnTransitionsForNilTransitionTriggered),
45 | ("testOnTransitionsNeverTriggeredOnSwappedTransition", testOnTransitionsNeverTriggeredOnSwappedTransition),
46 | ("testOnTransitionsTriggeredOnExactTransition", testOnTransitionsTriggeredOnExactTransition),
47 | ("testSubscribedTransitionsNeverTriggeredOnExactTransitionWhenNotStored", testSubscribedTransitionsNeverTriggeredOnExactTransitionWhenNotStored),
48 | ("testSubscribedTransitionsTriggeredOnExactTransitionWhenStored", testSubscribedTransitionsTriggeredOnExactTransitionWhenStored),
49 | ("testSubscribeTransitionsForNilTransitionNeverTriggeredWhenNotHold", testSubscribeTransitionsForNilTransitionNeverTriggeredWhenNotHold),
50 | ("testSubscribeTransitionsForNilTransitionTriggeredWhenHold", testSubscribeTransitionsForNilTransitionTriggeredWhenHold),
51 | ]
52 | }
53 |
54 | extension TransitionTests {
55 | // DO NOT MODIFY: This is autogenerated, use:
56 | // `swift test --generate-linuxmain`
57 | // to regenerate.
58 | static let __allTests__TransitionTests = [
59 | ("testAbsolute", testAbsolute),
60 | ("testDescription", testDescription),
61 | ("testEqualty", testEqualty),
62 | ("testGeneral", testGeneral),
63 | ("testHash", testHash),
64 | ("testNil", testNil),
65 | ("testRelative", testRelative),
66 | ]
67 | }
68 |
69 | public func __allTests() -> [XCTestCaseEntry] {
70 | [
71 | testCase(StateFlowTests.__allTests__StateFlowTests),
72 | testCase(StateMachineTests.__allTests__StateMachineTests),
73 | testCase(TransitionTests.__allTests__TransitionTests),
74 | ]
75 | }
76 | #endif
77 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | comment:
2 | layout: "header, diff"
3 | behavior: default
4 |
--------------------------------------------------------------------------------
/docs/Enums.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Enumerations Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
34 |
35 |
41 |
42 |
48 |
49 |
50 |
51 | Finite Reference
52 |
53 | Enumerations Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
Enumerations
96 |
The following enumerations are available globally.
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
113 |
114 |
115 |
116 |
117 |
118 |
Indicates that a transition failed.
119 |
120 |
See more
121 |
122 |
123 |
Declaration
124 |
125 |
Swift
126 |
public enum TransitionError < T > : Error where T : Hashable
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/docs/Enums/TransitionError.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TransitionError Enumeration Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
49 |
50 |
51 | Finite Reference
52 |
53 | TransitionError Enumeration Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
TransitionError
96 |
97 |
98 |
99 |
public enum TransitionError < T > : Error where T : Hashable
100 |
101 |
102 |
103 |
Indicates that a transition failed.
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
120 |
121 |
122 |
123 |
124 |
125 |
Represents a tried transition that is not allowed.
126 |
127 |
128 |
129 |
Declaration
130 |
131 |
Swift
132 |
case denied ( from : T , to : T )
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/docs/Protocols.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Protocols Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
49 |
50 |
51 | Finite Reference
52 |
53 | Protocols Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
Protocols
96 |
The following protocols are available globally.
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
113 |
114 |
115 |
116 |
117 |
118 |
A subsription reference which needs to be referenced strongly.
119 |
120 |
See more
121 |
122 |
123 |
Declaration
124 |
125 |
Swift
126 |
public protocol ReferenceDisposable
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/docs/Protocols/ReferenceDisposable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ReferenceDisposable Protocol Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
49 |
50 |
51 | Finite Reference
52 |
53 | ReferenceDisposable Protocol Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
ReferenceDisposable
96 |
97 |
98 |
99 |
public protocol ReferenceDisposable
100 |
101 |
102 |
103 |
A subsription reference which needs to be referenced strongly.
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | dispose()
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
Disposes the current subscription. Current and future operations will be canceled.
126 |
127 |
128 |
129 |
Declaration
130 |
131 |
Swift
132 |
func dispose ()
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/docs/Structs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Structures Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
49 |
50 |
51 | Finite Reference
52 |
53 | Structures Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
Structures
96 |
The following structures are available globally.
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | StateFlow
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
Represents a configuration of a state machine.
119 |
120 |
See more
121 |
122 |
123 |
Declaration
124 |
125 |
Swift
126 |
public struct StateFlow < T > : CustomStringConvertible where T : Hashable
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
141 |
142 |
143 |
144 |
145 |
146 |
Represents a state machine.
147 |
148 |
See more
149 |
150 |
151 |
Declaration
152 |
153 |
Swift
154 |
public struct StateMachine < T > : CustomStringConvertible where T : Hashable
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
169 |
170 |
171 |
172 |
173 |
174 |
The Transition class represents a transition from a given state to a targeted state.
175 | There are three types of transitions:
176 |
177 |
178 | Absolute Transitions have a source and a target state set.
179 | Relative Transitions have only one state set.
180 | Nil Transitions have none states set and will be ignored.
181 |
182 |
183 |
See more
184 |
185 |
186 |
Declaration
187 |
188 |
Swift
189 |
public struct Transition < T > : Hashable , CustomStringConvertible where T : Hashable
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
207 |
208 |
209 |
210 |
--------------------------------------------------------------------------------
/docs/Typealiases.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Type Aliases Reference
5 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
54 |
55 |
56 | Finite Reference
57 |
58 | Type Aliases Reference
59 |
60 |
61 |
62 |
63 |
103 |
104 |
105 |
106 |
107 |
108 |
Type Aliases
109 |
The following type aliases are available globally.
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | Error
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
A shim for Swift 3.0’s Error protocol
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/docs/badge.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | documentation
17 |
18 |
19 | documentation
20 |
21 |
22 | 97%
23 |
24 |
25 | 97%
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/docs/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/docs/css/jazzy.css:
--------------------------------------------------------------------------------
1 | *, *:before, *:after {
2 | box-sizing: inherit; }
3 |
4 | body {
5 | margin: 0;
6 | background: #fff;
7 | color: #333;
8 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
9 | letter-spacing: .2px;
10 | -webkit-font-smoothing: antialiased;
11 | box-sizing: border-box; }
12 |
13 | h1 {
14 | font-size: 2rem;
15 | font-weight: 700;
16 | margin: 1.275em 0 0.6em; }
17 |
18 | h2 {
19 | font-size: 1.75rem;
20 | font-weight: 700;
21 | margin: 1.275em 0 0.3em; }
22 |
23 | h3 {
24 | font-size: 1.5rem;
25 | font-weight: 700;
26 | margin: 1em 0 0.3em; }
27 |
28 | h4 {
29 | font-size: 1.25rem;
30 | font-weight: 700;
31 | margin: 1.275em 0 0.85em; }
32 |
33 | h5 {
34 | font-size: 1rem;
35 | font-weight: 700;
36 | margin: 1.275em 0 0.85em; }
37 |
38 | h6 {
39 | font-size: 1rem;
40 | font-weight: 700;
41 | margin: 1.275em 0 0.85em;
42 | color: #777; }
43 |
44 | p {
45 | margin: 0 0 1em; }
46 |
47 | ul, ol {
48 | padding: 0 0 0 2em;
49 | margin: 0 0 0.85em; }
50 |
51 | blockquote {
52 | margin: 0 0 0.85em;
53 | padding: 0 15px;
54 | color: #858585;
55 | border-left: 4px solid #e5e5e5; }
56 |
57 | img {
58 | max-width: 100%; }
59 |
60 | a {
61 | color: #4183c4;
62 | text-decoration: none; }
63 | a:hover, a:focus {
64 | outline: 0;
65 | text-decoration: underline; }
66 | a.discouraged {
67 | text-decoration: line-through; }
68 | a.discouraged:hover, a.discouraged:focus {
69 | text-decoration: underline line-through; }
70 |
71 | table {
72 | background: #fff;
73 | width: 100%;
74 | border-collapse: collapse;
75 | border-spacing: 0;
76 | overflow: auto;
77 | margin: 0 0 0.85em; }
78 |
79 | tr:nth-child(2n) {
80 | background-color: #fbfbfb; }
81 |
82 | th, td {
83 | padding: 6px 13px;
84 | border: 1px solid #ddd; }
85 |
86 | pre {
87 | margin: 0 0 1.275em;
88 | padding: .85em 1em;
89 | overflow: auto;
90 | background: #f7f7f7;
91 | font-size: .85em;
92 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
93 |
94 | code {
95 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
96 |
97 | .item-container p > code, .item-container li > code, .top-matter p > code, .top-matter li > code {
98 | background: #f7f7f7;
99 | padding: .2em; }
100 | .item-container p > code:before, .item-container p > code:after, .item-container li > code:before, .item-container li > code:after, .top-matter p > code:before, .top-matter p > code:after, .top-matter li > code:before, .top-matter li > code:after {
101 | letter-spacing: -.2em;
102 | content: "\00a0"; }
103 |
104 | pre code {
105 | padding: 0;
106 | white-space: pre; }
107 |
108 | .content-wrapper {
109 | display: flex;
110 | flex-direction: column; }
111 | @media (min-width: 768px) {
112 | .content-wrapper {
113 | flex-direction: row; } }
114 | .header {
115 | display: flex;
116 | padding: 8px;
117 | font-size: 0.875em;
118 | background: #444;
119 | color: #999; }
120 |
121 | .header-col {
122 | margin: 0;
123 | padding: 0 8px; }
124 |
125 | .header-col--primary {
126 | flex: 1; }
127 |
128 | .header-link {
129 | color: #fff; }
130 |
131 | .header-icon {
132 | padding-right: 6px;
133 | vertical-align: -4px;
134 | height: 16px; }
135 |
136 | .breadcrumbs {
137 | font-size: 0.875em;
138 | padding: 8px 16px;
139 | margin: 0;
140 | background: #fbfbfb;
141 | border-bottom: 1px solid #ddd; }
142 |
143 | .carat {
144 | height: 10px;
145 | margin: 0 5px; }
146 |
147 | .navigation {
148 | order: 2; }
149 | @media (min-width: 768px) {
150 | .navigation {
151 | order: 1;
152 | width: 25%;
153 | max-width: 300px;
154 | padding-bottom: 64px;
155 | overflow: hidden;
156 | word-wrap: normal;
157 | background: #fbfbfb;
158 | border-right: 1px solid #ddd; } }
159 | .nav-groups {
160 | list-style-type: none;
161 | padding-left: 0; }
162 |
163 | .nav-group-name {
164 | border-bottom: 1px solid #ddd;
165 | padding: 8px 0 8px 16px; }
166 |
167 | .nav-group-name-link {
168 | color: #333; }
169 |
170 | .nav-group-tasks {
171 | margin: 8px 0;
172 | padding: 0 0 0 8px; }
173 |
174 | .nav-group-task {
175 | font-size: 1em;
176 | list-style-type: none;
177 | white-space: nowrap; }
178 |
179 | .nav-group-task-link {
180 | color: #808080; }
181 |
182 | .main-content {
183 | order: 1; }
184 | @media (min-width: 768px) {
185 | .main-content {
186 | order: 2;
187 | flex: 1;
188 | padding-bottom: 60px; } }
189 | .section {
190 | padding: 0 32px;
191 | border-bottom: 1px solid #ddd; }
192 |
193 | .section-content {
194 | max-width: 834px;
195 | margin: 0 auto;
196 | padding: 16px 0; }
197 |
198 | .section-name {
199 | color: #666;
200 | display: block; }
201 | .section-name p {
202 | margin-bottom: inherit; }
203 |
204 | .declaration .highlight {
205 | overflow-x: initial;
206 | padding: 8px 0;
207 | margin: 0;
208 | background-color: transparent;
209 | border: none; }
210 |
211 | .task-group-section {
212 | border-top: 1px solid #ddd; }
213 |
214 | .task-group {
215 | padding-top: 0px; }
216 |
217 | .task-name-container a[name]:before {
218 | content: "";
219 | display: block; }
220 |
221 | .section-name-container {
222 | position: relative; }
223 | .section-name-container .section-name-link {
224 | position: absolute;
225 | top: 0;
226 | left: 0;
227 | bottom: 0;
228 | right: 0;
229 | margin-bottom: 0; }
230 | .section-name-container .section-name {
231 | position: relative;
232 | pointer-events: none;
233 | z-index: 1; }
234 | .section-name-container .section-name a {
235 | pointer-events: auto; }
236 |
237 | .item-container {
238 | padding: 0; }
239 |
240 | .item {
241 | padding-top: 8px;
242 | width: 100%;
243 | list-style-type: none; }
244 | .item a[name]:before {
245 | content: "";
246 | display: block; }
247 | .item .token, .item .direct-link {
248 | display: inline-block;
249 | text-indent: -20px;
250 | padding-left: 3px;
251 | margin-left: 20px;
252 | font-size: 1rem; }
253 | .item .declaration-note {
254 | font-size: .85em;
255 | color: #808080;
256 | font-style: italic; }
257 |
258 | .pointer-container {
259 | border-bottom: 1px solid #ddd;
260 | left: -23px;
261 | padding-bottom: 13px;
262 | position: relative;
263 | width: 110%; }
264 |
265 | .pointer {
266 | left: 21px;
267 | top: 7px;
268 | display: block;
269 | position: absolute;
270 | width: 12px;
271 | height: 12px;
272 | border-left: 1px solid #ddd;
273 | border-top: 1px solid #ddd;
274 | background: #fff;
275 | transform: rotate(45deg); }
276 |
277 | .height-container {
278 | display: none;
279 | position: relative;
280 | width: 100%;
281 | overflow: hidden; }
282 | .height-container .section {
283 | background: #fff;
284 | border: 1px solid #ddd;
285 | border-top-width: 0;
286 | padding-top: 10px;
287 | padding-bottom: 5px;
288 | padding: 8px 16px; }
289 |
290 | .aside, .language {
291 | padding: 6px 12px;
292 | margin: 12px 0;
293 | border-left: 5px solid #dddddd;
294 | overflow-y: hidden; }
295 | .aside .aside-title, .language .aside-title {
296 | font-size: 9px;
297 | letter-spacing: 2px;
298 | text-transform: uppercase;
299 | padding-bottom: 0;
300 | margin: 0;
301 | color: #aaa;
302 | -webkit-user-select: none; }
303 | .aside p:last-child, .language p:last-child {
304 | margin-bottom: 0; }
305 |
306 | .language {
307 | border-left: 5px solid #cde9f4; }
308 | .language .aside-title {
309 | color: #4183c4; }
310 |
311 | .aside-warning, .aside-deprecated, .aside-unavailable {
312 | border-left: 5px solid #ff6666; }
313 | .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title {
314 | color: #ff0000; }
315 |
316 | .graybox {
317 | border-collapse: collapse;
318 | width: 100%; }
319 | .graybox p {
320 | margin: 0;
321 | word-break: break-word;
322 | min-width: 50px; }
323 | .graybox td {
324 | border: 1px solid #ddd;
325 | padding: 5px 25px 5px 10px;
326 | vertical-align: middle; }
327 | .graybox tr td:first-of-type {
328 | text-align: right;
329 | padding: 7px;
330 | vertical-align: top;
331 | word-break: normal;
332 | width: 40px; }
333 |
334 | .slightly-smaller {
335 | font-size: 0.9em; }
336 |
337 | .footer {
338 | padding: 8px 16px;
339 | background: #444;
340 | color: #ddd;
341 | font-size: 0.8em; }
342 | .footer p {
343 | margin: 8px 0; }
344 | .footer a {
345 | color: #fff; }
346 |
347 | html.dash .header, html.dash .breadcrumbs, html.dash .navigation {
348 | display: none; }
349 |
350 | html.dash .height-container {
351 | display: block; }
352 |
353 | form[role=search] input {
354 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
355 | font-size: 14px;
356 | line-height: 24px;
357 | padding: 0 10px;
358 | margin: 0;
359 | border: none;
360 | border-radius: 1em; }
361 | .loading form[role=search] input {
362 | background: white url(../img/spinner.gif) center right 4px no-repeat; }
363 |
364 | form[role=search] .tt-menu {
365 | margin: 0;
366 | min-width: 300px;
367 | background: #fbfbfb;
368 | color: #333;
369 | border: 1px solid #ddd; }
370 |
371 | form[role=search] .tt-highlight {
372 | font-weight: bold; }
373 |
374 | form[role=search] .tt-suggestion {
375 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
376 | padding: 0 8px; }
377 | form[role=search] .tt-suggestion span {
378 | display: table-cell;
379 | white-space: nowrap; }
380 | form[role=search] .tt-suggestion .doc-parent-name {
381 | width: 100%;
382 | text-align: right;
383 | font-weight: normal;
384 | font-size: 0.9em;
385 | padding-left: 16px; }
386 |
387 | form[role=search] .tt-suggestion:hover,
388 | form[role=search] .tt-suggestion.tt-cursor {
389 | cursor: pointer;
390 | background-color: #4183c4;
391 | color: #fff; }
392 |
393 | form[role=search] .tt-suggestion:hover .doc-parent-name,
394 | form[role=search] .tt-suggestion.tt-cursor .doc-parent-name {
395 | color: #fff; }
396 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | com.jazzy.finite
7 | CFBundleName
8 | Finite
9 | DocSetPlatformFamily
10 | finite
11 | isDashDocset
12 |
13 | dashIndexFilePath
14 | index.html
15 | isJavaScriptEnabled
16 |
17 | DashDocSetFamily
18 | dashtoc
19 | DashDocSetFallbackURL
20 | https://vknabel.github.io/Finite/
21 |
22 |
23 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/Enums.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Enumerations Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
49 |
50 |
51 | Finite Reference
52 |
53 | Enumerations Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
Enumerations
96 |
The following enumerations are available globally.
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
113 |
114 |
115 |
116 |
117 |
118 |
Indicates that a transition failed.
119 |
120 |
See more
121 |
122 |
123 |
Declaration
124 |
125 |
Swift
126 |
public enum TransitionError < T > : Error where T : Hashable
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/Enums/TransitionError.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TransitionError Enumeration Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
49 |
50 |
51 | Finite Reference
52 |
53 | TransitionError Enumeration Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
TransitionError
96 |
97 |
98 |
99 |
public enum TransitionError < T > : Error where T : Hashable
100 |
101 |
102 |
103 |
Indicates that a transition failed.
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
120 |
121 |
122 |
123 |
124 |
125 |
Represents a tried transition that is not allowed.
126 |
127 |
128 |
129 |
Declaration
130 |
131 |
Swift
132 |
case denied ( from : T , to : T )
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/Protocols.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Protocols Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
49 |
50 |
51 | Finite Reference
52 |
53 | Protocols Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
Protocols
96 |
The following protocols are available globally.
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
113 |
114 |
115 |
116 |
117 |
118 |
A subsription reference which needs to be referenced strongly.
119 |
120 |
See more
121 |
122 |
123 |
Declaration
124 |
125 |
Swift
126 |
public protocol ReferenceDisposable
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/Protocols/ReferenceDisposable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ReferenceDisposable Protocol Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
49 |
50 |
51 | Finite Reference
52 |
53 | ReferenceDisposable Protocol Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
ReferenceDisposable
96 |
97 |
98 |
99 |
public protocol ReferenceDisposable
100 |
101 |
102 |
103 |
A subsription reference which needs to be referenced strongly.
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | dispose()
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
Disposes the current subscription. Current and future operations will be canceled.
126 |
127 |
128 |
129 |
Declaration
130 |
131 |
Swift
132 |
func dispose ()
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/Structs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Structures Reference
5 |
6 |
7 |
8 |
9 |
10 | "
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
49 |
50 |
51 | Finite Reference
52 |
53 | Structures Reference
54 |
55 |
56 |
57 |
58 |
90 |
91 |
92 |
93 |
94 |
95 |
Structures
96 |
The following structures are available globally.
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | StateFlow
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
Represents a configuration of a state machine.
119 |
120 |
See more
121 |
122 |
123 |
Declaration
124 |
125 |
Swift
126 |
public struct StateFlow < T > : CustomStringConvertible where T : Hashable
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
141 |
142 |
143 |
144 |
145 |
146 |
Represents a state machine.
147 |
148 |
See more
149 |
150 |
151 |
Declaration
152 |
153 |
Swift
154 |
public struct StateMachine < T > : CustomStringConvertible where T : Hashable
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
169 |
170 |
171 |
172 |
173 |
174 |
The Transition class represents a transition from a given state to a targeted state.
175 | There are three types of transitions:
176 |
177 |
178 | Absolute Transitions have a source and a target state set.
179 | Relative Transitions have only one state set.
180 | Nil Transitions have none states set and will be ignored.
181 |
182 |
183 |
See more
184 |
185 |
186 |
Declaration
187 |
188 |
Swift
189 |
public struct Transition < T > : Hashable , CustomStringConvertible where T : Hashable
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
207 |
208 |
209 |
210 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/Typealiases.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Type Aliases Reference
5 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
54 |
55 |
56 | Finite Reference
57 |
58 | Type Aliases Reference
59 |
60 |
61 |
62 |
63 |
103 |
104 |
105 |
106 |
107 |
108 |
Type Aliases
109 |
The following type aliases are available globally.
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | Error
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
A shim for Swift 3.0’s Error protocol
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/badge.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | documentation
17 |
18 |
19 | documentation
20 |
21 |
22 | 97%
23 |
24 |
25 | 97%
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/css/jazzy.css:
--------------------------------------------------------------------------------
1 | *, *:before, *:after {
2 | box-sizing: inherit; }
3 |
4 | body {
5 | margin: 0;
6 | background: #fff;
7 | color: #333;
8 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
9 | letter-spacing: .2px;
10 | -webkit-font-smoothing: antialiased;
11 | box-sizing: border-box; }
12 |
13 | h1 {
14 | font-size: 2rem;
15 | font-weight: 700;
16 | margin: 1.275em 0 0.6em; }
17 |
18 | h2 {
19 | font-size: 1.75rem;
20 | font-weight: 700;
21 | margin: 1.275em 0 0.3em; }
22 |
23 | h3 {
24 | font-size: 1.5rem;
25 | font-weight: 700;
26 | margin: 1em 0 0.3em; }
27 |
28 | h4 {
29 | font-size: 1.25rem;
30 | font-weight: 700;
31 | margin: 1.275em 0 0.85em; }
32 |
33 | h5 {
34 | font-size: 1rem;
35 | font-weight: 700;
36 | margin: 1.275em 0 0.85em; }
37 |
38 | h6 {
39 | font-size: 1rem;
40 | font-weight: 700;
41 | margin: 1.275em 0 0.85em;
42 | color: #777; }
43 |
44 | p {
45 | margin: 0 0 1em; }
46 |
47 | ul, ol {
48 | padding: 0 0 0 2em;
49 | margin: 0 0 0.85em; }
50 |
51 | blockquote {
52 | margin: 0 0 0.85em;
53 | padding: 0 15px;
54 | color: #858585;
55 | border-left: 4px solid #e5e5e5; }
56 |
57 | img {
58 | max-width: 100%; }
59 |
60 | a {
61 | color: #4183c4;
62 | text-decoration: none; }
63 | a:hover, a:focus {
64 | outline: 0;
65 | text-decoration: underline; }
66 | a.discouraged {
67 | text-decoration: line-through; }
68 | a.discouraged:hover, a.discouraged:focus {
69 | text-decoration: underline line-through; }
70 |
71 | table {
72 | background: #fff;
73 | width: 100%;
74 | border-collapse: collapse;
75 | border-spacing: 0;
76 | overflow: auto;
77 | margin: 0 0 0.85em; }
78 |
79 | tr:nth-child(2n) {
80 | background-color: #fbfbfb; }
81 |
82 | th, td {
83 | padding: 6px 13px;
84 | border: 1px solid #ddd; }
85 |
86 | pre {
87 | margin: 0 0 1.275em;
88 | padding: .85em 1em;
89 | overflow: auto;
90 | background: #f7f7f7;
91 | font-size: .85em;
92 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
93 |
94 | code {
95 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
96 |
97 | .item-container p > code, .item-container li > code, .top-matter p > code, .top-matter li > code {
98 | background: #f7f7f7;
99 | padding: .2em; }
100 | .item-container p > code:before, .item-container p > code:after, .item-container li > code:before, .item-container li > code:after, .top-matter p > code:before, .top-matter p > code:after, .top-matter li > code:before, .top-matter li > code:after {
101 | letter-spacing: -.2em;
102 | content: "\00a0"; }
103 |
104 | pre code {
105 | padding: 0;
106 | white-space: pre; }
107 |
108 | .content-wrapper {
109 | display: flex;
110 | flex-direction: column; }
111 | @media (min-width: 768px) {
112 | .content-wrapper {
113 | flex-direction: row; } }
114 | .header {
115 | display: flex;
116 | padding: 8px;
117 | font-size: 0.875em;
118 | background: #444;
119 | color: #999; }
120 |
121 | .header-col {
122 | margin: 0;
123 | padding: 0 8px; }
124 |
125 | .header-col--primary {
126 | flex: 1; }
127 |
128 | .header-link {
129 | color: #fff; }
130 |
131 | .header-icon {
132 | padding-right: 6px;
133 | vertical-align: -4px;
134 | height: 16px; }
135 |
136 | .breadcrumbs {
137 | font-size: 0.875em;
138 | padding: 8px 16px;
139 | margin: 0;
140 | background: #fbfbfb;
141 | border-bottom: 1px solid #ddd; }
142 |
143 | .carat {
144 | height: 10px;
145 | margin: 0 5px; }
146 |
147 | .navigation {
148 | order: 2; }
149 | @media (min-width: 768px) {
150 | .navigation {
151 | order: 1;
152 | width: 25%;
153 | max-width: 300px;
154 | padding-bottom: 64px;
155 | overflow: hidden;
156 | word-wrap: normal;
157 | background: #fbfbfb;
158 | border-right: 1px solid #ddd; } }
159 | .nav-groups {
160 | list-style-type: none;
161 | padding-left: 0; }
162 |
163 | .nav-group-name {
164 | border-bottom: 1px solid #ddd;
165 | padding: 8px 0 8px 16px; }
166 |
167 | .nav-group-name-link {
168 | color: #333; }
169 |
170 | .nav-group-tasks {
171 | margin: 8px 0;
172 | padding: 0 0 0 8px; }
173 |
174 | .nav-group-task {
175 | font-size: 1em;
176 | list-style-type: none;
177 | white-space: nowrap; }
178 |
179 | .nav-group-task-link {
180 | color: #808080; }
181 |
182 | .main-content {
183 | order: 1; }
184 | @media (min-width: 768px) {
185 | .main-content {
186 | order: 2;
187 | flex: 1;
188 | padding-bottom: 60px; } }
189 | .section {
190 | padding: 0 32px;
191 | border-bottom: 1px solid #ddd; }
192 |
193 | .section-content {
194 | max-width: 834px;
195 | margin: 0 auto;
196 | padding: 16px 0; }
197 |
198 | .section-name {
199 | color: #666;
200 | display: block; }
201 | .section-name p {
202 | margin-bottom: inherit; }
203 |
204 | .declaration .highlight {
205 | overflow-x: initial;
206 | padding: 8px 0;
207 | margin: 0;
208 | background-color: transparent;
209 | border: none; }
210 |
211 | .task-group-section {
212 | border-top: 1px solid #ddd; }
213 |
214 | .task-group {
215 | padding-top: 0px; }
216 |
217 | .task-name-container a[name]:before {
218 | content: "";
219 | display: block; }
220 |
221 | .section-name-container {
222 | position: relative; }
223 | .section-name-container .section-name-link {
224 | position: absolute;
225 | top: 0;
226 | left: 0;
227 | bottom: 0;
228 | right: 0;
229 | margin-bottom: 0; }
230 | .section-name-container .section-name {
231 | position: relative;
232 | pointer-events: none;
233 | z-index: 1; }
234 | .section-name-container .section-name a {
235 | pointer-events: auto; }
236 |
237 | .item-container {
238 | padding: 0; }
239 |
240 | .item {
241 | padding-top: 8px;
242 | width: 100%;
243 | list-style-type: none; }
244 | .item a[name]:before {
245 | content: "";
246 | display: block; }
247 | .item .token, .item .direct-link {
248 | display: inline-block;
249 | text-indent: -20px;
250 | padding-left: 3px;
251 | margin-left: 20px;
252 | font-size: 1rem; }
253 | .item .declaration-note {
254 | font-size: .85em;
255 | color: #808080;
256 | font-style: italic; }
257 |
258 | .pointer-container {
259 | border-bottom: 1px solid #ddd;
260 | left: -23px;
261 | padding-bottom: 13px;
262 | position: relative;
263 | width: 110%; }
264 |
265 | .pointer {
266 | left: 21px;
267 | top: 7px;
268 | display: block;
269 | position: absolute;
270 | width: 12px;
271 | height: 12px;
272 | border-left: 1px solid #ddd;
273 | border-top: 1px solid #ddd;
274 | background: #fff;
275 | transform: rotate(45deg); }
276 |
277 | .height-container {
278 | display: none;
279 | position: relative;
280 | width: 100%;
281 | overflow: hidden; }
282 | .height-container .section {
283 | background: #fff;
284 | border: 1px solid #ddd;
285 | border-top-width: 0;
286 | padding-top: 10px;
287 | padding-bottom: 5px;
288 | padding: 8px 16px; }
289 |
290 | .aside, .language {
291 | padding: 6px 12px;
292 | margin: 12px 0;
293 | border-left: 5px solid #dddddd;
294 | overflow-y: hidden; }
295 | .aside .aside-title, .language .aside-title {
296 | font-size: 9px;
297 | letter-spacing: 2px;
298 | text-transform: uppercase;
299 | padding-bottom: 0;
300 | margin: 0;
301 | color: #aaa;
302 | -webkit-user-select: none; }
303 | .aside p:last-child, .language p:last-child {
304 | margin-bottom: 0; }
305 |
306 | .language {
307 | border-left: 5px solid #cde9f4; }
308 | .language .aside-title {
309 | color: #4183c4; }
310 |
311 | .aside-warning, .aside-deprecated, .aside-unavailable {
312 | border-left: 5px solid #ff6666; }
313 | .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title {
314 | color: #ff0000; }
315 |
316 | .graybox {
317 | border-collapse: collapse;
318 | width: 100%; }
319 | .graybox p {
320 | margin: 0;
321 | word-break: break-word;
322 | min-width: 50px; }
323 | .graybox td {
324 | border: 1px solid #ddd;
325 | padding: 5px 25px 5px 10px;
326 | vertical-align: middle; }
327 | .graybox tr td:first-of-type {
328 | text-align: right;
329 | padding: 7px;
330 | vertical-align: top;
331 | word-break: normal;
332 | width: 40px; }
333 |
334 | .slightly-smaller {
335 | font-size: 0.9em; }
336 |
337 | .footer {
338 | padding: 8px 16px;
339 | background: #444;
340 | color: #ddd;
341 | font-size: 0.8em; }
342 | .footer p {
343 | margin: 8px 0; }
344 | .footer a {
345 | color: #fff; }
346 |
347 | html.dash .header, html.dash .breadcrumbs, html.dash .navigation {
348 | display: none; }
349 |
350 | html.dash .height-container {
351 | display: block; }
352 |
353 | form[role=search] input {
354 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
355 | font-size: 14px;
356 | line-height: 24px;
357 | padding: 0 10px;
358 | margin: 0;
359 | border: none;
360 | border-radius: 1em; }
361 | .loading form[role=search] input {
362 | background: white url(../img/spinner.gif) center right 4px no-repeat; }
363 |
364 | form[role=search] .tt-menu {
365 | margin: 0;
366 | min-width: 300px;
367 | background: #fbfbfb;
368 | color: #333;
369 | border: 1px solid #ddd; }
370 |
371 | form[role=search] .tt-highlight {
372 | font-weight: bold; }
373 |
374 | form[role=search] .tt-suggestion {
375 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
376 | padding: 0 8px; }
377 | form[role=search] .tt-suggestion span {
378 | display: table-cell;
379 | white-space: nowrap; }
380 | form[role=search] .tt-suggestion .doc-parent-name {
381 | width: 100%;
382 | text-align: right;
383 | font-weight: normal;
384 | font-size: 0.9em;
385 | padding-left: 16px; }
386 |
387 | form[role=search] .tt-suggestion:hover,
388 | form[role=search] .tt-suggestion.tt-cursor {
389 | cursor: pointer;
390 | background-color: #4183c4;
391 | color: #fff; }
392 |
393 | form[role=search] .tt-suggestion:hover .doc-parent-name,
394 | form[role=search] .tt-suggestion.tt-cursor .doc-parent-name {
395 | color: #fff; }
396 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/img/carat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/docsets/Finite.docset/Contents/Resources/Documents/img/carat.png
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/img/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/docsets/Finite.docset/Contents/Resources/Documents/img/dash.png
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/img/gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/docsets/Finite.docset/Contents/Resources/Documents/img/gh.png
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/img/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/docsets/Finite.docset/Contents/Resources/Documents/img/spinner.gif
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | function toggleItem($link, $content) {
12 | var animationDuration = 300;
13 | $link.toggleClass('token-open');
14 | $content.slideToggle(animationDuration);
15 | }
16 |
17 | function itemLinkToContent($link) {
18 | return $link.parent().parent().next();
19 | }
20 |
21 | // On doc load + hash-change, open any targetted item
22 | function openCurrentItemIfClosed() {
23 | if (window.jazzy.docset) {
24 | return;
25 | }
26 | var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token');
27 | $content = itemLinkToContent($link);
28 | if ($content.is(':hidden')) {
29 | toggleItem($link, $content);
30 | }
31 | }
32 |
33 | $(openCurrentItemIfClosed);
34 | $(window).on('hashchange', openCurrentItemIfClosed);
35 |
36 | // On item link ('token') click, toggle its discussion
37 | $('.token').on('click', function(event) {
38 | if (window.jazzy.docset) {
39 | return;
40 | }
41 | var $link = $(this);
42 | toggleItem($link, itemLinkToContent($link));
43 |
44 | // Keeps the document from jumping to the hash.
45 | var href = $link.attr('href');
46 | if (history.pushState) {
47 | history.pushState({}, '', href);
48 | } else {
49 | location.hash = href;
50 | }
51 | event.preventDefault();
52 | });
53 |
54 | // Clicks on links to the current, closed, item need to open the item
55 | $("a:not('.token')").on('click', function() {
56 | if (location == this.href) {
57 | openCurrentItemIfClosed();
58 | }
59 | });
60 |
61 | // KaTeX rendering
62 | if ("katex" in window) {
63 | $($('.math').each( (_, element) => {
64 | katex.render(element.textContent, element, {
65 | displayMode: $(element).hasClass('m-block'),
66 | throwOnError: false,
67 | trust: true
68 | });
69 | }))
70 | }
71 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/js/jazzy.search.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | var $typeahead = $('[data-typeahead]');
3 | var $form = $typeahead.parents('form');
4 | var searchURL = $form.attr('action');
5 |
6 | function displayTemplate(result) {
7 | return result.name;
8 | }
9 |
10 | function suggestionTemplate(result) {
11 | var t = '';
12 | t += '' + result.name + ' ';
13 | if (result.parent_name) {
14 | t += '' + result.parent_name + ' ';
15 | }
16 | t += '
';
17 | return t;
18 | }
19 |
20 | $typeahead.one('focus', function() {
21 | $form.addClass('loading');
22 |
23 | $.getJSON(searchURL).then(function(searchData) {
24 | const searchIndex = lunr(function() {
25 | this.ref('url');
26 | this.field('name');
27 | this.field('abstract');
28 | for (const [url, doc] of Object.entries(searchData)) {
29 | this.add({url: url, name: doc.name, abstract: doc.abstract});
30 | }
31 | });
32 |
33 | $typeahead.typeahead(
34 | {
35 | highlight: true,
36 | minLength: 3,
37 | autoselect: true
38 | },
39 | {
40 | limit: 10,
41 | display: displayTemplate,
42 | templates: { suggestion: suggestionTemplate },
43 | source: function(query, sync) {
44 | const lcSearch = query.toLowerCase();
45 | const results = searchIndex.query(function(q) {
46 | q.term(lcSearch, { boost: 100 });
47 | q.term(lcSearch, {
48 | boost: 10,
49 | wildcard: lunr.Query.wildcard.TRAILING
50 | });
51 | }).map(function(result) {
52 | var doc = searchData[result.ref];
53 | doc.url = result.ref;
54 | return doc;
55 | });
56 | sync(results);
57 | }
58 | }
59 | );
60 | $form.removeClass('loading');
61 | $typeahead.trigger('focus');
62 | });
63 | });
64 |
65 | var baseURL = searchURL.slice(0, -"search.json".length);
66 |
67 | $typeahead.on('typeahead:select', function(e, result) {
68 | window.location = baseURL + result.url;
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/search.json:
--------------------------------------------------------------------------------
1 | {"Structs/Transition.html#/s:6Finite10TransitionV03nilB0ACyxGvpZ":{"name":"nilTransition","abstract":"Nil transitions will be ignored.
","parent_name":"Transition"},"Structs/Transition.html#/s:6Finite10TransitionV4fromxSgvp":{"name":"from","abstract":"The source state.
","parent_name":"Transition"},"Structs/Transition.html#/s:6Finite10TransitionV2toxSgvp":{"name":"to","abstract":"The targeted state.
","parent_name":"Transition"},"Structs/Transition.html#/s:6Finite10TransitionV4from2toACyxGxSg_AGtcfc":{"name":"init(from:to:)","abstract":"Constructs an absolute, relative or nil transition.
","parent_name":"Transition"},"Structs/Transition.html#/s:6Finite10TransitionV18generalTransitionsShyACyxGGvp":{"name":"generalTransitions","abstract":"All more general transitions include itself except the nil transition.
","parent_name":"Transition"},"Structs/Transition.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"Transition"},"Structs/Transition.html#/s:SH4hash4intoys6HasherVz_tF":{"name":"hash(into:)","parent_name":"Transition"},"Structs/StateMachine.html#/s:6Finite12StateMachineV9Operationa":{"name":"Operation","abstract":"An empty operation to be performed.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV16TransitionFiltera":{"name":"TransitionFilter","abstract":"Undocumented
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV5statexvp":{"name":"state","abstract":"The current state of the machine.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV7initial6configACyxGx_yAA0B4FlowVyxGzXEtcfc":{"name":"init(initial:config:)","abstract":"Instantiates a state machine by configuring the StateFlow instance.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV7initial9stateFlowACyxGx_AA0bF0VyxGtcfc":{"name":"init(initial:stateFlow:)","abstract":"Instantiates a state machine by passing an instance of StateFlow.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV10transition2to10completionyx_yyKcSgtKF":{"name":"transition(to:completion:)","abstract":"Triggers a transition to a given state and invokes a callback on completion.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV6allows2toSbx_tF":{"name":"allows(to:)","abstract":"Returns wether transitioning to a state is allowed.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions4like7performyAA10TransitionVyxG_yyKctF":{"name":"onTransitions(like:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV20subscribeTransitions4like7performAA19ReferenceDisposable_pAA10TransitionVyxG_yyKctF":{"name":"subscribeTransitions(like:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV11descriptionSSvp":{"name":"description","abstract":"Returns the graph for the state machine
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions4from2to7performyx_xyyKctF":{"name":"onTransitions(from:to:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV20subscribeTransitions4from2to7performAA19ReferenceDisposable_px_xyyKctF":{"name":"subscribeTransitions(from:to:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions4from7performyx_yyKctF":{"name":"onTransitions(from:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV20subscribeTransitions4from7performAA19ReferenceDisposable_px_yyKctF":{"name":"subscribeTransitions(from:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions2to7performyx_yyKctF":{"name":"onTransitions(to:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV20subscribeTransitions2to7performAA19ReferenceDisposable_px_yyKctF":{"name":"subscribeTransitions(to:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions10transition7performyAA10TransitionVyxG_yyKctF":{"name":"onTransitions(transition:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.","parent_name":"StateMachine"},"Structs/StateFlow.html#/s:6Finite9StateFlowV16TransitionFiltera":{"name":"TransitionFilter","abstract":"
Filters wether a transition is allowed to be performed.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV12Configuratora":{"name":"Configurator","abstract":"Configures the instance for immutable usage.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV6configACyxGyAEzXE_tcfc":{"name":"init(config:)","abstract":"Creates a new instance that can be mutated to be stored immutable.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowVACyxGycfc":{"name":"init()","abstract":"Creates a new instance to be used mutable.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow10transition6filteryAA10TransitionVyxG_SbAIcSgtF":{"name":"allow(transition:filter:)","abstract":"Allows all less-equal general transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV6allowsySbAA10TransitionVyxGF":{"name":"allows(_:)","abstract":"Returns wether a specific transition is allowed or not.","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV11descriptionSSvp":{"name":"description","abstract":"
Returns list of of transitions, sorted by the hash values of the","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from6filteryx_SbAA10TransitionVyxGcSgtF":{"name":"allow(from:filter:)","abstract":"
Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow2to6filteryx_SbAA10TransitionVyxGcSgtF":{"name":"allow(to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from2to6filteryx_xSbAA10TransitionVyxGcSgtF":{"name":"allow(from:to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from6filterySayxG_SbAA10TransitionVyxGcSgtF":{"name":"allow(from:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from2to6filterySayxG_xSbAA10TransitionVyxGcSgtF":{"name":"allow(from:to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow2to6filterySayxG_SbAA10TransitionVyxGcSgtF":{"name":"allow(to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from2to6filteryx_SayxGSbAA10TransitionVyxGcSgtF":{"name":"allow(from:to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from2to6filterySayxG_AHSbAA10TransitionVyxGcSgtF":{"name":"allow(from:to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html":{"name":"StateFlow","abstract":"Represents a configuration of a state machine.
"},"Structs/StateMachine.html":{"name":"StateMachine","abstract":"Represents a state machine.
"},"Structs/Transition.html":{"name":"Transition","abstract":"The Transition class represents a transition from a given state to a targeted state."},"Protocols/ReferenceDisposable.html#/s:6Finite19ReferenceDisposableP7disposeyyF":{"name":"dispose()","abstract":"
Disposes the current subscription. Current and future operations will be canceled.
","parent_name":"ReferenceDisposable"},"Protocols/ReferenceDisposable.html":{"name":"ReferenceDisposable","abstract":"A subsription reference which needs to be referenced strongly.
"},"Enums/TransitionError.html#/s:6Finite15TransitionErrorO6deniedyACyxGx_xtcAEmSHRzlF":{"name":"denied(from:to:)","abstract":"Represents a tried transition that is not allowed.
","parent_name":"TransitionError"},"Enums/TransitionError.html":{"name":"TransitionError","abstract":"Indicates that a transition failed.
"},"Enums.html":{"name":"Enumerations","abstract":"The following enumerations are available globally.
"},"Protocols.html":{"name":"Protocols","abstract":"The following protocols are available globally.
"},"Structs.html":{"name":"Structures","abstract":"The following structures are available globally.
"}}
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/Documents/undocumented.json:
--------------------------------------------------------------------------------
1 | {
2 | "warnings": [
3 | {
4 | "file": "/Users/vknabel/Developer/vknabel/Finite/Sources/StateMachine.swift",
5 | "line": 24,
6 | "symbol": "StateMachine.TransitionFilter",
7 | "symbol_kind": "source.lang.swift.decl.typealias",
8 | "warning": "undocumented"
9 | }
10 | ],
11 | "source_directory": "/Users/vknabel/Developer/vknabel/Finite"
12 | }
--------------------------------------------------------------------------------
/docs/docsets/Finite.docset/Contents/Resources/docSet.dsidx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/docsets/Finite.docset/Contents/Resources/docSet.dsidx
--------------------------------------------------------------------------------
/docs/docsets/Finite.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/docsets/Finite.tgz
--------------------------------------------------------------------------------
/docs/docsets/Finite.xml:
--------------------------------------------------------------------------------
1 | 4.0.0 https://vknabel.github.io/Finite/docsets/Finite.tgz
2 |
--------------------------------------------------------------------------------
/docs/img/carat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/img/carat.png
--------------------------------------------------------------------------------
/docs/img/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/img/dash.png
--------------------------------------------------------------------------------
/docs/img/gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/img/gh.png
--------------------------------------------------------------------------------
/docs/img/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vknabel/Finite/cbd5de6ebbabfb39a730d1357c1c3659f4301c45/docs/img/spinner.gif
--------------------------------------------------------------------------------
/docs/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | function toggleItem($link, $content) {
12 | var animationDuration = 300;
13 | $link.toggleClass('token-open');
14 | $content.slideToggle(animationDuration);
15 | }
16 |
17 | function itemLinkToContent($link) {
18 | return $link.parent().parent().next();
19 | }
20 |
21 | // On doc load + hash-change, open any targetted item
22 | function openCurrentItemIfClosed() {
23 | if (window.jazzy.docset) {
24 | return;
25 | }
26 | var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token');
27 | $content = itemLinkToContent($link);
28 | if ($content.is(':hidden')) {
29 | toggleItem($link, $content);
30 | }
31 | }
32 |
33 | $(openCurrentItemIfClosed);
34 | $(window).on('hashchange', openCurrentItemIfClosed);
35 |
36 | // On item link ('token') click, toggle its discussion
37 | $('.token').on('click', function(event) {
38 | if (window.jazzy.docset) {
39 | return;
40 | }
41 | var $link = $(this);
42 | toggleItem($link, itemLinkToContent($link));
43 |
44 | // Keeps the document from jumping to the hash.
45 | var href = $link.attr('href');
46 | if (history.pushState) {
47 | history.pushState({}, '', href);
48 | } else {
49 | location.hash = href;
50 | }
51 | event.preventDefault();
52 | });
53 |
54 | // Clicks on links to the current, closed, item need to open the item
55 | $("a:not('.token')").on('click', function() {
56 | if (location == this.href) {
57 | openCurrentItemIfClosed();
58 | }
59 | });
60 |
61 | // KaTeX rendering
62 | if ("katex" in window) {
63 | $($('.math').each( (_, element) => {
64 | katex.render(element.textContent, element, {
65 | displayMode: $(element).hasClass('m-block'),
66 | throwOnError: false,
67 | trust: true
68 | });
69 | }))
70 | }
71 |
--------------------------------------------------------------------------------
/docs/js/jazzy.search.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | var $typeahead = $('[data-typeahead]');
3 | var $form = $typeahead.parents('form');
4 | var searchURL = $form.attr('action');
5 |
6 | function displayTemplate(result) {
7 | return result.name;
8 | }
9 |
10 | function suggestionTemplate(result) {
11 | var t = '';
12 | t += '' + result.name + ' ';
13 | if (result.parent_name) {
14 | t += '' + result.parent_name + ' ';
15 | }
16 | t += '
';
17 | return t;
18 | }
19 |
20 | $typeahead.one('focus', function() {
21 | $form.addClass('loading');
22 |
23 | $.getJSON(searchURL).then(function(searchData) {
24 | const searchIndex = lunr(function() {
25 | this.ref('url');
26 | this.field('name');
27 | this.field('abstract');
28 | for (const [url, doc] of Object.entries(searchData)) {
29 | this.add({url: url, name: doc.name, abstract: doc.abstract});
30 | }
31 | });
32 |
33 | $typeahead.typeahead(
34 | {
35 | highlight: true,
36 | minLength: 3,
37 | autoselect: true
38 | },
39 | {
40 | limit: 10,
41 | display: displayTemplate,
42 | templates: { suggestion: suggestionTemplate },
43 | source: function(query, sync) {
44 | const lcSearch = query.toLowerCase();
45 | const results = searchIndex.query(function(q) {
46 | q.term(lcSearch, { boost: 100 });
47 | q.term(lcSearch, {
48 | boost: 10,
49 | wildcard: lunr.Query.wildcard.TRAILING
50 | });
51 | }).map(function(result) {
52 | var doc = searchData[result.ref];
53 | doc.url = result.ref;
54 | return doc;
55 | });
56 | sync(results);
57 | }
58 | }
59 | );
60 | $form.removeClass('loading');
61 | $typeahead.trigger('focus');
62 | });
63 | });
64 |
65 | var baseURL = searchURL.slice(0, -"search.json".length);
66 |
67 | $typeahead.on('typeahead:select', function(e, result) {
68 | window.location = baseURL + result.url;
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/docs/search.json:
--------------------------------------------------------------------------------
1 | {"Structs/Transition.html#/s:6Finite10TransitionV03nilB0ACyxGvpZ":{"name":"nilTransition","abstract":"Nil transitions will be ignored.
","parent_name":"Transition"},"Structs/Transition.html#/s:6Finite10TransitionV4fromxSgvp":{"name":"from","abstract":"The source state.
","parent_name":"Transition"},"Structs/Transition.html#/s:6Finite10TransitionV2toxSgvp":{"name":"to","abstract":"The targeted state.
","parent_name":"Transition"},"Structs/Transition.html#/s:6Finite10TransitionV4from2toACyxGxSg_AGtcfc":{"name":"init(from:to:)","abstract":"Constructs an absolute, relative or nil transition.
","parent_name":"Transition"},"Structs/Transition.html#/s:6Finite10TransitionV18generalTransitionsShyACyxGGvp":{"name":"generalTransitions","abstract":"All more general transitions include itself except the nil transition.
","parent_name":"Transition"},"Structs/Transition.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"Transition"},"Structs/Transition.html#/s:SH4hash4intoys6HasherVz_tF":{"name":"hash(into:)","parent_name":"Transition"},"Structs/StateMachine.html#/s:6Finite12StateMachineV9Operationa":{"name":"Operation","abstract":"An empty operation to be performed.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV16TransitionFiltera":{"name":"TransitionFilter","abstract":"Undocumented
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV5statexvp":{"name":"state","abstract":"The current state of the machine.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV7initial6configACyxGx_yAA0B4FlowVyxGzXEtcfc":{"name":"init(initial:config:)","abstract":"Instantiates a state machine by configuring the StateFlow instance.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV7initial9stateFlowACyxGx_AA0bF0VyxGtcfc":{"name":"init(initial:stateFlow:)","abstract":"Instantiates a state machine by passing an instance of StateFlow.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV10transition2to10completionyx_yyKcSgtKF":{"name":"transition(to:completion:)","abstract":"Triggers a transition to a given state and invokes a callback on completion.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV6allows2toSbx_tF":{"name":"allows(to:)","abstract":"Returns wether transitioning to a state is allowed.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions4like7performyAA10TransitionVyxG_yyKctF":{"name":"onTransitions(like:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV20subscribeTransitions4like7performAA19ReferenceDisposable_pAA10TransitionVyxG_yyKctF":{"name":"subscribeTransitions(like:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV11descriptionSSvp":{"name":"description","abstract":"Returns the graph for the state machine
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions4from2to7performyx_xyyKctF":{"name":"onTransitions(from:to:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV20subscribeTransitions4from2to7performAA19ReferenceDisposable_px_xyyKctF":{"name":"subscribeTransitions(from:to:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions4from7performyx_yyKctF":{"name":"onTransitions(from:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV20subscribeTransitions4from7performAA19ReferenceDisposable_px_yyKctF":{"name":"subscribeTransitions(from:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions2to7performyx_yyKctF":{"name":"onTransitions(to:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV20subscribeTransitions2to7performAA19ReferenceDisposable_px_yyKctF":{"name":"subscribeTransitions(to:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.
","parent_name":"StateMachine"},"Structs/StateMachine.html#/s:6Finite12StateMachineV13onTransitions10transition7performyAA10TransitionVyxG_yyKctF":{"name":"onTransitions(transition:perform:)","abstract":"Appends a transition handler for all more-equal general transitions.","parent_name":"StateMachine"},"Structs/StateFlow.html#/s:6Finite9StateFlowV16TransitionFiltera":{"name":"TransitionFilter","abstract":"
Filters wether a transition is allowed to be performed.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV12Configuratora":{"name":"Configurator","abstract":"Configures the instance for immutable usage.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV6configACyxGyAEzXE_tcfc":{"name":"init(config:)","abstract":"Creates a new instance that can be mutated to be stored immutable.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowVACyxGycfc":{"name":"init()","abstract":"Creates a new instance to be used mutable.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow10transition6filteryAA10TransitionVyxG_SbAIcSgtF":{"name":"allow(transition:filter:)","abstract":"Allows all less-equal general transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV6allowsySbAA10TransitionVyxGF":{"name":"allows(_:)","abstract":"Returns wether a specific transition is allowed or not.","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV11descriptionSSvp":{"name":"description","abstract":"
Returns list of of transitions, sorted by the hash values of the","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from6filteryx_SbAA10TransitionVyxGcSgtF":{"name":"allow(from:filter:)","abstract":"
Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow2to6filteryx_SbAA10TransitionVyxGcSgtF":{"name":"allow(to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from2to6filteryx_xSbAA10TransitionVyxGcSgtF":{"name":"allow(from:to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from6filterySayxG_SbAA10TransitionVyxGcSgtF":{"name":"allow(from:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from2to6filterySayxG_xSbAA10TransitionVyxGcSgtF":{"name":"allow(from:to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow2to6filterySayxG_SbAA10TransitionVyxGcSgtF":{"name":"allow(to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from2to6filteryx_SayxGSbAA10TransitionVyxGcSgtF":{"name":"allow(from:to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html#/s:6Finite9StateFlowV5allow4from2to6filterySayxG_AHSbAA10TransitionVyxGcSgtF":{"name":"allow(from:to:filter:)","abstract":"Convinience method that allows all less-equal general absolute transitions to be triggered.
","parent_name":"StateFlow"},"Structs/StateFlow.html":{"name":"StateFlow","abstract":"Represents a configuration of a state machine.
"},"Structs/StateMachine.html":{"name":"StateMachine","abstract":"Represents a state machine.
"},"Structs/Transition.html":{"name":"Transition","abstract":"The Transition class represents a transition from a given state to a targeted state."},"Protocols/ReferenceDisposable.html#/s:6Finite19ReferenceDisposableP7disposeyyF":{"name":"dispose()","abstract":"
Disposes the current subscription. Current and future operations will be canceled.
","parent_name":"ReferenceDisposable"},"Protocols/ReferenceDisposable.html":{"name":"ReferenceDisposable","abstract":"A subsription reference which needs to be referenced strongly.
"},"Enums/TransitionError.html#/s:6Finite15TransitionErrorO6deniedyACyxGx_xtcAEmSHRzlF":{"name":"denied(from:to:)","abstract":"Represents a tried transition that is not allowed.
","parent_name":"TransitionError"},"Enums/TransitionError.html":{"name":"TransitionError","abstract":"Indicates that a transition failed.
"},"Enums.html":{"name":"Enumerations","abstract":"The following enumerations are available globally.
"},"Protocols.html":{"name":"Protocols","abstract":"The following protocols are available globally.
"},"Structs.html":{"name":"Structures","abstract":"The following structures are available globally.
"}}
--------------------------------------------------------------------------------
/docs/undocumented.json:
--------------------------------------------------------------------------------
1 | {
2 | "warnings": [
3 | {
4 | "file": "/Users/vknabel/dev/Finite/Sources/StateMachine.swift",
5 | "line": 19,
6 | "symbol": "StateMachine.TransitionFilter",
7 | "symbol_kind": "source.lang.swift.decl.typealias",
8 | "warning": "undocumented"
9 | }
10 | ],
11 | "source_directory": "/Users/vknabel/dev/Finite"
12 | }
--------------------------------------------------------------------------------