Search code examples
swiftstate-machinegamekit

Request for a simple example for GKStateMachine?


I've been researching Apple's state machine for Swift and found several examples, but none of them really dead simple.

Could someone whip up a super simple GKStateMachine, perhaps with two states, in Swift, preferably all in one Swift file? Thanks!


Solution

  • Here is an example of a state machine for a traffic light as they work in the USA. A traffic light moves from green -> yellow -> red -> green.

    In an app, you might have the didEnter(from:) routines update an onscreen graphic, or allow another actor to move.

    import UIKit
    import GameKit
    
    class Green: GKState {
    
        override func isValidNextState(_ stateClass: AnyClass) -> Bool {
            return stateClass is Yellow.Type
        }
    
        override func didEnter(from previousState: GKState?) {
            print("Traffic light is green")
        }
    }
    
    class Yellow: GKState {
        override func isValidNextState(_ stateClass: AnyClass) -> Bool {
            return stateClass is Red.Type
        }
    
        override func didEnter(from previousState: GKState?) {
            print("Traffic light is yellow")
        }
    
    }
    
    class Red: GKState {
        override func isValidNextState(_ stateClass: AnyClass) -> Bool {
            return stateClass is Green.Type
        }
    
        override func didEnter(from previousState: GKState?) {
            print("Traffic light is red")
        }
    }
    
    class ViewController: UIViewController {
    
        var stateMachine: GKStateMachine?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Create the states            
            let green = Green()
            let yellow = Yellow()
            let red = Red()
    
            // Initialize the state machine            
            stateMachine = GKStateMachine(states: [green, yellow, red])
    
            // Try entering various states...            
            if stateMachine?.enter(Green.self) == false {
                print("failed to move to green")
            }
            if stateMachine?.enter(Red.self) == false {
                print("failed to move to red")
            }
            if stateMachine?.enter(Yellow.self) == false {
                print("failed to move to yellow")
            }
            if stateMachine?.enter(Green.self) == false {
                print("failed to move to green")
            }
            if stateMachine?.enter(Red.self) == false {
                print("failed to move to red")
            }
    
        }
    
    }
    

    Output:

    Traffic light is green
    failed to move to red
    Traffic light is yellow
    failed to move to green
    Traffic light is red