Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
muukii committed Jan 23, 2025
1 parent 0e4b1bc commit 553cd99
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 14 deletions.
1 change: 1 addition & 0 deletions Sources/Verge/Derived/Derived.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ public class Derived<Value: Equatable>: Store<Value, Never>, DerivedType, @unche
}

public final override func stateDidUpdate(newState: Changes<Value>) {
super.stateDidUpdate(newState: newState)
// projects this update into upstream state
if let _set, newState._transaction.isDerivedFromUpstream == false {
_set(newState.primitive)
Expand Down
25 changes: 21 additions & 4 deletions Sources/Verge/Store/Store.swift
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ open class Store<State: Equatable, Activity: Sendable>: EventEmitter<_StoreEvent
swap(&registrations.0, &registrations.1)

for registration in registrations.1 {

if registration.containsUpdates(state: newState) {
registration.onChange()
} else {
Expand Down Expand Up @@ -284,7 +285,10 @@ open class Store<State: Equatable, Activity: Sendable>: EventEmitter<_StoreEvent
}

public func tracking<T>(
_ apply: (inout StoreReaderComponents<State>.StateProxy) -> T, onChange: @escaping () -> Void
file: StaticString = #file,
line: UInt = #line,
_ apply: (inout StoreReaderComponents<State>.StateProxy) -> T,
onChange: @escaping @Sendable () -> Void
) -> T {

let currentState = state.primitiveBox
Expand All @@ -293,7 +297,14 @@ open class Store<State: Equatable, Activity: Sendable>: EventEmitter<_StoreEvent
let result = apply(&tracker)

registrations.modify {
$0.0.append(.init(detectors: tracker.detectors, onChange: onChange))
$0.0.append(
.init(
file: file,
line: line,
detectors: tracker.detectors,
onChange: onChange
)
)
}

return result
Expand All @@ -302,13 +313,19 @@ open class Store<State: Equatable, Activity: Sendable>: EventEmitter<_StoreEvent

private struct TrackingRegistration {

let file: StaticString
let line: UInt
let detectors: [PartialKeyPath<State>: (Changes<State>) -> Bool]
let onChange: () -> Void
let onChange: @Sendable () -> Void

init(
file: StaticString,
line: UInt,
detectors: [PartialKeyPath<State>: (Changes<State>) -> Bool],
onChange: @escaping () -> Void
onChange: @escaping @Sendable () -> Void
) {
self.file = file
self.line = line
self.detectors = detectors
self.onChange = onChange
}
Expand Down
29 changes: 19 additions & 10 deletions Sources/Verge/SwiftUI/StoreReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ public struct StoreReader<State: Equatable, Activity: Sendable, Content: View>:
private let store: Store<State, Activity>

@SwiftUI.State private var version: UInt64 = 0


private let file: StaticString
private let line: UInt

private let content: @MainActor (inout StoreReaderComponents<State>.StateProxy) -> Content

/// Initialize from `Store`
Expand All @@ -26,23 +29,31 @@ public struct StoreReader<State: Equatable, Activity: Sendable, Content: View>:
/// - store:
/// - content:
public init<Driver: StoreDriverType>(
file: StaticString = #file,
line: UInt = #line,
_ store: Driver,
@ViewBuilder content: @escaping @MainActor (inout StoreReaderComponents<State>.StateProxy) -> Content
) where State == Driver.TargetStore.State, Activity == Driver.TargetStore.Activity {

let store = store.store.asStore()

self.init(
file: file,
line: line,
store: store,
content: content
)

}

private init(
file: StaticString,
line: UInt,
store: Store<State, Activity>,
content: @escaping @MainActor (inout StoreReaderComponents<State>.StateProxy) -> Content
) {
self.file = file
self.line = line
self.store = store
self.content = content
}
Expand All @@ -54,13 +65,9 @@ public struct StoreReader<State: Equatable, Activity: Sendable, Content: View>:

let _content = store.tracking { state -> Content in
content(&state)
} onChange: {
if Thread.isMainThread {
} onChange: {
ImmediateMainActorTargetQueue.main.execute {
version &+= 1
} else {
Task { @MainActor in
version &+= 1
}
}
}

Expand All @@ -74,7 +81,7 @@ public enum StoreReaderComponents<StateType: Equatable> {
// Proxy
@dynamicMemberLookup
public struct StateProxy: ~Copyable {

typealias Detectors = [PartialKeyPath<StateType> : (Changes<StateType>) -> Bool]

private let wrapped: ReadonlyBox<StateType>
Expand All @@ -100,7 +107,9 @@ public enum StoreReaderComponents<StateType: Equatable> {
/**
✅ Equatable version
*/
public subscript<T>(dynamicMember keyPath: KeyPath<StateType, T>) -> T where T : Equatable {
public subscript<T>(
dynamicMember keyPath: KeyPath<StateType, T>
) -> T where T : Equatable {
mutating get {

if detectors[keyPath as PartialKeyPath<StateType>] == nil {
Expand All @@ -109,7 +118,7 @@ public enum StoreReaderComponents<StateType: Equatable> {

switch changes.modification {
case .determinate(let keyPaths):

/// modified but maybe value not changed.
let mayHasChanges = keyPaths.contains(keyPath)

Expand Down

0 comments on commit 553cd99

Please sign in to comment.