Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert to use StateObject instead of State in ViewContext #162

Merged
merged 2 commits into from
Jan 22, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 24 additions & 50 deletions Sources/Atoms/PropertyWrapper/ViewContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,72 +32,46 @@ import SwiftUI
///
@propertyWrapper
public struct ViewContext: DynamicProperty {
private let file: StaticString
private let location: SourceLocation

@Environment(\.store)
private var _store

private let file: StaticString
private let location: SourceLocation
@StateObject
private var state = State()

/// Creates a view context.
public init(file: StaticString = #file, fileID: String = #fileID, line: UInt = #line) {
self.file = file
self.location = SourceLocation(fileID: fileID, line: line)
}

/// The underlying view context to interact with atoms.
///
/// This property provides primary access to the view context. However you don't
/// access ``wrappedValue`` directly.
/// Instead, you use the property variable created with the `@ViewContext` attribute.
#if compiler(>=6) || hasFeature(DisableOutwardActorInference)
@State
private var signal = false
@State
private var subscriberState = SubscriberState()

/// The underlying view context to interact with atoms.
///
/// This property provides primary access to the view context. However you don't
/// access ``wrappedValue`` directly.
/// Instead, you use the property variable created with the `@ViewContext` attribute.
@MainActor
public var wrappedValue: AtomViewContext {
let signal = _signal

// Initializes State and starts observing for updates.
_ = signal.wrappedValue

return AtomViewContext(
store: store,
subscriber: Subscriber(subscriberState),
subscription: Subscription(location: location) {
signal.wrappedValue.toggle()
}
)
}

#else
@MainActor
private final class State: ObservableObject {
let subscriberState = SubscriberState()
}

@StateObject
private var state = State()

/// The underlying view context to interact with atoms.
///
/// This property provides primary access to the view context. However you don't
/// access ``wrappedValue`` directly.
/// Instead, you use the property variable created with the `@ViewContext` attribute.
public var wrappedValue: AtomViewContext {
AtomViewContext(
store: store,
subscriber: Subscriber(state.subscriberState),
subscription: Subscription(location: location) { [weak state] in
state?.objectWillChange.send()
}
)
}
#endif
public var wrappedValue: AtomViewContext {
AtomViewContext(
store: store,
subscriber: Subscriber(state.subscriberState),
subscription: Subscription(location: location) { [weak state] in
state?.objectWillChange.send()
}
)
}
}

private extension ViewContext {
@MainActor
final class State: ObservableObject {
let subscriberState = SubscriberState()
}

@MainActor
var store: StoreContext {
guard let _store else {
Expand Down
Loading