1- import Foundation
2-
31@usableFromInline
42@MainActor
53internal struct StoreContext {
@@ -90,7 +88,7 @@ internal struct StoreContext {
9088 let key = AtomKey ( atom, scopeKey: scopeKey)
9189
9290 if let cache = lookupCache ( of: atom, for: key) {
93- update ( atom: atom, for: key, value : value, cache: cache, order : . newValue )
91+ update ( atom: atom, for: key, newValue : value, cache: cache)
9492 }
9593 }
9694
@@ -103,7 +101,7 @@ internal struct StoreContext {
103101 if let cache = lookupCache ( of: atom, for: key) {
104102 var value = cache. value
105103 body ( & value)
106- update ( atom: atom, for: key, value : value, cache: cache, order : . newValue )
104+ update ( atom: atom, for: key, newValue : value, cache: cache)
107105 }
108106 }
109107
@@ -129,18 +127,12 @@ internal struct StoreContext {
129127 func watch< Node: Atom > (
130128 _ atom: Node ,
131129 subscriber: Subscriber ,
132- requiresObjectUpdate: Bool ,
133- notifyUpdate: @escaping ( ) -> Void
130+ subscription: Subscription
134131 ) -> Node . Loader . Value {
135132 let override = lookupOverride ( of: atom)
136133 let scopeKey = lookupScopeKey ( of: atom, isScopedOverriden: override? . isScoped ?? false )
137134 let key = AtomKey ( atom, scopeKey: scopeKey)
138135 let cache = getCache ( of: atom, for: key, override: override)
139- let subscription = Subscription (
140- location: subscriber. location,
141- requiresObjectUpdate: requiresObjectUpdate,
142- notifyUpdate: notifyUpdate
143- )
144136 let isNewSubscription = subscriber. subscribingKeys. insert ( key) . inserted
145137
146138 store. state. subscriptions [ key, default: [ : ] ] . updateValue ( subscription, forKey: subscriber. key)
@@ -178,7 +170,7 @@ internal struct StoreContext {
178170
179171 // Notify update unless it's cancelled or terminated by other operations.
180172 if !Task. isCancelled && !context. transaction. isTerminated {
181- update ( atom: atom, for: key, value : value, cache: cache, order : . newValue )
173+ update ( atom: atom, for: key, newValue : value, cache: cache)
182174 }
183175
184176 return value
@@ -199,7 +191,7 @@ internal struct StoreContext {
199191
200192 // Notify update unless it's cancelled or terminated by other operations.
201193 if !Task. isCancelled && !transaction. isTerminated {
202- update ( atom: atom, for: key, value : value, cache: cache, order : . newValue )
194+ update ( atom: atom, for: key, newValue : value, cache: cache)
203195 }
204196
205197 return value
@@ -214,7 +206,7 @@ internal struct StoreContext {
214206
215207 if let cache = lookupCache ( of: atom, for: key) {
216208 let newCache = makeCache ( of: atom, for: key, override: override)
217- update ( atom: atom, for: key, value : newCache. value, cache: cache, order : . newValue )
209+ update ( atom: atom, for: key, newValue : newCache. value, cache: cache)
218210 }
219211 }
220212
@@ -289,7 +281,7 @@ internal struct StoreContext {
289281 // Notify updates only for the subscriptions of restored atoms.
290282 if let subscriptions = store. state. subscriptions [ key] {
291283 for subscription in ContiguousArray ( subscriptions. values) {
292- subscription. notifyUpdate ( )
284+ subscription. update ( )
293285 }
294286 }
295287 }
@@ -336,54 +328,38 @@ private extension StoreContext {
336328 store: self ,
337329 transaction: transaction,
338330 coordinator: state. coordinator
339- ) { value , order in
340- guard let cache = lookupCache ( of: atom, for: key) else {
341- return
331+ ) { newValue in
332+ if let cache = lookupCache ( of: atom, for: key) {
333+ update ( atom : atom , for : key , newValue : newValue , cache : cache )
342334 }
343-
344- update (
345- atom: atom,
346- for: key,
347- value: value,
348- cache: cache,
349- order: order
350- )
351335 }
352336 }
353337
354338 func update< Node: Atom > (
355339 atom: Node ,
356340 for key: AtomKey ,
357- value: Node . Loader . Value ,
358- cache: AtomCache < Node > ,
359- order: UpdateOrder
341+ newValue: Node . Loader . Value ,
342+ cache: AtomCache < Node >
360343 ) {
361344 let oldValue = cache. value
345+ var cache = cache
362346
363- if case . newValue = order {
364- var cache = cache
365- cache. value = value
366- store. state. caches [ key] = cache
367- }
347+ cache. value = newValue
348+ store. state. caches [ key] = cache
368349
369- // Do not notify update if the new value and the old value are equivalent.
370- if !atom. _loader. shouldUpdate ( newValue: value, oldValue: oldValue) {
350+ guard atom. _loader. shouldUpdate ( newValue: newValue, oldValue: oldValue) else {
371351 return
372352 }
373353
374- // Notifying update to view subscriptions first.
375- if let subscriptions = store. state. subscriptions [ key] {
376- for subscription in ContiguousArray ( subscriptions. values) {
377- if case . objectWillChange = order, subscription. requiresObjectUpdate {
378- RunLoop . current. perform ( subscription. notifyUpdate)
379- }
380- else {
381- subscription. notifyUpdate ( )
354+ atom. _loader. performUpdate {
355+ // Notifies update to view subscriptions first.
356+ if let subscriptions = store. state. subscriptions [ key] {
357+ for subscription in ContiguousArray ( subscriptions. values) {
358+ subscription. update ( )
382359 }
383360 }
384- }
385361
386- func notifyUpdate ( ) {
362+ // Notifies update to downstream atoms.
387363 if let children = store. graph. children [ key] {
388364 for child in ContiguousArray ( children) {
389365 // Reset the atom value and then notifies downstream atoms.
@@ -398,21 +374,7 @@ private extension StoreContext {
398374
399375 let state = getState ( of: atom, for: key)
400376 let context = AtomCurrentContext ( store: self , coordinator: state. coordinator)
401- atom. updated ( newValue: value, oldValue: oldValue, context: context)
402- }
403-
404- switch order {
405- case . newValue:
406- notifyUpdate ( )
407-
408- case . objectWillChange:
409- // At the timing when `ObservableObject/objectWillChange` emits, its properties
410- // have not yet been updated and are still old when dependent atoms read it.
411- // As a workaround, the update is executed in the next run loop
412- // so that the downstream atoms can receive the object that's already updated.
413- RunLoop . current. perform {
414- notifyUpdate ( )
415- }
377+ atom. updated ( newValue: newValue, oldValue: oldValue, context: context)
416378 }
417379 }
418380
0 commit comments