I am developing a state management library. The original design only has 1 listener, which works great until I need to support multiple listeners.
The original design is here: Swift how to use generic protocol in generic class
This is what I have done to support multiple listeners:
public protocol StateObserver: AnyObject {
associatedtype State
func didUpdateState(_ state: State)
}
public final class StateStore<Observer: StateObserver> {
struct WeakRef<T: AnyObject> {
weak var value: T?
}
public private(set) var state: Observer.State
private var observers = [WeakRef<Observer>]()
public init(initialState: Observer.State) {
state = initialState
}
public func addObservers(_ observers: [Observer]) {
self.observers += observers.map { WeakRef(value: $0) }
}
public func update(_ block: (inout Observer.State) -> Void) {
var nextState = state
block(&nextState)
state = nextState
notify()
}
public func notify() {
for observer in observers {
observer.value?.didUpdateState(state)
}
}
}
Now I need to create the store with 2 observers:
class MyScene: SKScene {
init {
let leftPanel = LeftPanelSKNode()
let topBar = TopBarSKNode()
let store: StateStore<?> // How to make this support `LeftPanelSKNode `, `TopBarSKNode`, and `MyScene`?
store.addObservers([leftPanel, topBar, self])
}
Now I am stuck here. I need to create a StateStore<?> of something, which can be either MyScene
, LeftPanelSKNode
and TopBarSKNode
.