Skip to content

Commit

Permalink
Observer refactoring (#92)
Browse files Browse the repository at this point in the history
* observer refactoring

* refactoring

* minor internals refactoring
  • Loading branch information
KazaiMazai authored Sep 8, 2024
1 parent 7551781 commit 333c70d
Show file tree
Hide file tree
Showing 22 changed files with 234 additions and 299 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@

import Foundation

class AnyCancellableEffect {
class EffectStateObserver { }
class CancellableObserver {
private class AnyStateObserver { }

var observer: AnyObject = EffectStateObserver()
var observer: AnyObject = AnyStateObserver()

init(_ observer: AnyObject) {
self.observer = observer
}

init() {
self.observer = EffectStateObserver()
self.observer = AnyStateObserver()
}

func cancel() {
observer = EffectStateObserver()
observer = AnyStateObserver()
}
}
80 changes: 39 additions & 41 deletions Sources/Puredux/SideEffects/SideEffects.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ public extension Store {

subscribe(observer: Observer(
storeObject(),
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState, complete in
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState in
let effect = state[keyPath: keyPath]
effectOperator.run(effect, on: queue) { _ in
create(state, weakStore.dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

Expand Down Expand Up @@ -136,13 +136,13 @@ public extension Store {

subscribe(observer: Observer(
storeObject(),
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState, complete in
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState in
let effect: Effect.State = prevState == nil ? .idle() : .running()
effectOperator.run(effect, on: queue) { _ in
create(state, weakStore.dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

Expand Down Expand Up @@ -201,13 +201,13 @@ public extension Store {

subscribe(observer: Observer(
storeObject(),
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState, complete in
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState in
let isRunning = state[keyPath: keyPath]
effectOperator.run(isRunning, on: queue) { _ in
create(state, weakStore.dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

Expand Down Expand Up @@ -276,14 +276,13 @@ public extension Store {

subscribe(observer: Observer(
storeObject(),
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState, complete in

removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState in
let allEffects = state[keyPath: keyPath]
effectOperator.run(allEffects, on: queue) { effectState in
create(state, effectState, weakStore.dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

Expand All @@ -304,12 +303,12 @@ extension Store {

subscribe(observer: Observer(
storeObject(),
removeStateDuplicates: removeStateDuplicates) { [effectOperator] state, prevState, complete in
removeStateDuplicates: removeStateDuplicates) { [effectOperator] state, prevState in
effectOperator.run(.running(delay: timeInterval), on: queue) { _ in
create(state, weakStore.dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

Expand All @@ -318,17 +317,16 @@ extension Store {
}

extension Store {

@discardableResult
func effect(_ cancellable: AnyCancellableEffect,
func effect(_ cancellable: CancellableObserver,
on queue: DispatchQueue = .main,
create: @escaping CreateEffect) -> Self where State == Effect.State {

effect(cancellable, \.self, on: queue, create: create)
}

@discardableResult
func effectCollection(_ cancellable: AnyCancellableEffect,
func effectCollection(_ cancellable: CancellableObserver,
on queue: DispatchQueue = .main,
create: @escaping CreateEffectForState) -> Self

Expand All @@ -340,7 +338,7 @@ extension Store {
}

@discardableResult
func effectOnChange(_ cancellable: AnyCancellableEffect,
func effectOnChange(_ cancellable: CancellableObserver,
on queue: DispatchQueue = .main,
create: @escaping CreateEffect) -> Self
where State: Equatable {
Expand All @@ -349,7 +347,7 @@ extension Store {
}

@discardableResult
func effectToggle(_ cancellable: AnyCancellableEffect,
func effectToggle(_ cancellable: CancellableObserver,
on queue: DispatchQueue = .main,
create: @escaping CreateEffect) -> Self where State == Bool {

Expand All @@ -359,7 +357,7 @@ extension Store {

extension Store {
@discardableResult
func effect<Effects>(_ cancellable: AnyCancellableEffect,
func effect<Effects>(_ cancellable: CancellableObserver,
collection keyPath: KeyPath<State, Effects>,
on queue: DispatchQueue = .main,
create: @escaping CreateEffectForState) -> Self
Expand All @@ -372,22 +370,22 @@ extension Store {

subscribe(observer: Observer(
cancellable.observer,
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState, complete in
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState in

let allEffects = state[keyPath: keyPath]
effectOperator.run(allEffects, on: queue) { effectState in
create(state, effectState, weakStore.dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

return self
}

@discardableResult
func effect(_ cancellable: AnyCancellableEffect,
func effect(_ cancellable: CancellableObserver,
_ keyPath: KeyPath<State, Effect.State>,
on queue: DispatchQueue = .main,
create: @escaping CreateEffect) -> Self {
Expand All @@ -396,22 +394,22 @@ extension Store {

subscribe(observer: Observer(
cancellable.observer,
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState, complete in
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState in

let effect = state[keyPath: keyPath]
effectOperator.run(effect, on: queue) { _ in
create(state, dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

return self
}

@discardableResult
func effect<T>(_ cancellable: AnyCancellableEffect,
func effect<T>(_ cancellable: CancellableObserver,
onChange keyPath: KeyPath<State, T>,
on queue: DispatchQueue = .main,
create: @escaping CreateEffect) -> Self where T: Equatable {
Expand All @@ -420,21 +418,21 @@ extension Store {

subscribe(observer: Observer(
cancellable.observer,
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState, complete in
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState in
let effect: Effect.State = prevState == nil ? .idle() : .running()
effectOperator.run(effect, on: queue) { _ in
create(state, dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

return self
}

@discardableResult
func effect(_ cancellable: AnyCancellableEffect,
func effect(_ cancellable: CancellableObserver,
toggle keyPath: KeyPath<State, Bool>,
on queue: DispatchQueue = .main,
create: @escaping CreateEffect) -> Self {
Expand All @@ -443,21 +441,21 @@ extension Store {

subscribe(observer: Observer(
cancellable.observer,
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState, complete in
removeStateDuplicates: .keyPath(keyPath)) { [effectOperator] state, prevState in
let isRunning = state[keyPath: keyPath]
effectOperator.run(isRunning, on: queue) { _ in
create(state, dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

return self
}

@discardableResult
func effect(_ cancellable: AnyCancellableEffect,
func effect(_ cancellable: CancellableObserver,
withDelay timeInterval: TimeInterval,
removeStateDuplicates: Equating<State>?,
on queue: DispatchQueue = .main,
Expand All @@ -467,12 +465,12 @@ extension Store {

subscribe(observer: Observer(
cancellable.observer,
removeStateDuplicates: removeStateDuplicates) { [effectOperator] state, prevState, complete in
removeStateDuplicates: removeStateDuplicates) { [effectOperator] state, prevState in
effectOperator.run(.running(delay: timeInterval), on: queue) { _ in
create(state, dispatch)
}
complete(.active)
return effectOperator.isSynced ? state : prevState

return (.active, effectOperator.isSynced ? state : prevState)
}
)

Expand Down
8 changes: 4 additions & 4 deletions Sources/Puredux/Store/AnyStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ public extension AnyStore {
AnyStore<T, Action>(
dispatcher: dispatchHandler,
subscribe: { localStateObserver in
subscribe(observer: Observer<State>(id: localStateObserver.id) { state, complete in
subscribe(observer: Observer<State>(id: localStateObserver.id) { state in
let localState = transform(state)
localStateObserver.send(localState, complete: complete)
return localStateObserver.send(localState)
})
},
referenced: referencedStore.map { $0.map(transform) }
Expand All @@ -73,9 +73,9 @@ public extension AnyStore {
AnyStore<T?, Action>(
dispatcher: dispatchHandler,
subscribe: { localStateObserver in
subscribe(observer: Observer<State>(id: localStateObserver.id) { state, complete in
subscribe(observer: Observer<State>(id: localStateObserver.id) { state in
let localState = transform(state)
localStateObserver.send(localState, complete: complete)
return localStateObserver.send(localState)
})
},
referenced: referencedStore.map { $0.map(transform) }
Expand Down
11 changes: 5 additions & 6 deletions Sources/Puredux/Store/Core/CoreStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,11 @@ extension CoreStore: StoreObjectProtocol {
private extension CoreStore {

func send(_ state: State, to observer: Observer<State>) {
observer.send(state) { [weak self] status in
guard status == .dead else {
return
}

self?.syncUnsubscribe(observer: observer)
let status = observer.send(state)
guard status == .dead else {
return
}

syncUnsubscribe(observer: observer)
}
}
25 changes: 11 additions & 14 deletions Sources/Puredux/Store/Core/StoreNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,22 @@ final class StoreNode<ParentStore, LocalState, State, Action> where ParentStore:
}

private lazy var parentObserver: Observer<ParentStore.State> = {
Observer(self, removeStateDuplicates: .neverEqual) { [weak self] parentState, complete in
Observer(self, removeStateDuplicates: .neverEqual) { [weak self] parentState,_ in
guard let self else {
complete(.dead)
return
return (.dead, parentState)
}
self.observe(parentState)
complete(.active)
return (.active, parentState)
}
}()

private lazy var localObserver: Observer<LocalState> = {
Observer(self, removeStateDuplicates: .neverEqual) { [weak self] _, complete in
Observer(self, removeStateDuplicates: .neverEqual) { [weak self] localState,_ in
guard let self else {
complete(.dead)
return
return (.dead, localState)
}

complete(.active)
return (.active, localState)
}
}()
}
Expand Down Expand Up @@ -149,12 +147,11 @@ private extension StoreNode {
}

func send(_ state: State, to observer: Observer<State>) {
observer.send(state) { [weak self] status in
guard status == .dead else {
return
}

self?.syncUnsubscribe(observer: observer)
let status = observer.send(state)
guard status == .dead else {
return
}

syncUnsubscribe(observer: observer)
}
}
Loading

0 comments on commit 333c70d

Please sign in to comment.