I have a class, StateMachine, that is generic to allow for different sets of states to be implemented as, for example, an enum. I want to use a StateMachineDelegate protocol to notify a delegate when the state machine enters a new state.
But this doesn't work since the delegate protocol is also generic with type requirements. The error shows where the delegate property is declared.
protocol StateType: Hashable {}
protocol StateMachineDelegate: class {
typealias S: StateType
func stateMachine(stateMachine: StateMachine<S>, didEnterState newState: S)
}
class StateMachine<S: StateType> {
typealias State = S
weak var delegate: StateMachineDelegate?
//~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
//Protocol 'StateMachineDelegate' can only be used as a generic constraint because it has Self or associated type requirements
var currentState: State {...}
init(initialState: State) {...}
func applyState(toState: State) -> Bool {
...
currentState = toState
delegate?.stateMachine(self, didEnterState: toState)
...
}
}
I need to somehow associate that StateMachineDelegate.S == S in the StateMachine class, but I'm not sure how to do this, or if it's possible. I tried:
class StateMachine<S: StateType, D: StateMachineDelegate where D.S == S> {
...
weak var delegate: D?
...
}
but then I get stuck trying to rework the protocol to properly declare the generic type of StateMachine. And it doesn't seem right to have to declare the type of the delegate up front when creating a StateMachine.