From 78999281c3fd4b56ee673350e2013c70b627b7ff Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 5 Nov 2023 17:42:27 +0800 Subject: [PATCH] Add StateObject implementation --- .../ModelData/State/ObservedObject.swift | 1 - .../ModelData/State/State.swift | 8 +-- .../ModelData/State/StateObject.swift | 60 +++++++++++++++++++ 3 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 Sources/OpenSwiftUI/DataAndStorage/ModelData/State/StateObject.swift diff --git a/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/ObservedObject.swift b/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/ObservedObject.swift index 4132929..2dbacf5 100644 --- a/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/ObservedObject.swift +++ b/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/ObservedObject.swift @@ -11,7 +11,6 @@ import Combine #else import OpenCombine #endif -internal import OpenSwiftUIShims @propertyWrapper @frozen diff --git a/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/State.swift b/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/State.swift index 30d478b..74a181f 100644 --- a/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/State.swift +++ b/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/State.swift @@ -46,15 +46,11 @@ public struct State { } return Binding(value: value, location: _location) } - - } extension State: DynamicProperty { - // TODO - // public static func _makeProperty(in _: inout _DynamicPropertyBuffer, container _: _GraphValue, fieldOffset _: Swift.Int, inputs _: inout _GraphInputs) { - // - // } + // TODO: + public static func _makeProperty(in _: inout _DynamicPropertyBuffer, container _: _GraphValue, fieldOffset _: Swift.Int, inputs _: inout _GraphInputs) {} } extension State where Value: ExpressibleByNilLiteral { diff --git a/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/StateObject.swift b/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/StateObject.swift new file mode 100644 index 0000000..86f14a3 --- /dev/null +++ b/Sources/OpenSwiftUI/DataAndStorage/ModelData/State/StateObject.swift @@ -0,0 +1,60 @@ +// +// StateObject.swift +// OpenSwiftUI +// +// Created by Kyle on 2023/11/5. +// Lastest Version: iOS 15.5 +// Status: Blocked by DynamicProperty + +#if OPENSWIFTUI_USE_COMBINE +import Combine +#else +import OpenCombine +#endif + +@frozen +@propertyWrapper +public struct StateObject where ObjectType: ObservableObject { + @usableFromInline + @frozen + enum Storage { + case initially(() -> ObjectType) + case object(ObservedObject) + } + + @usableFromInline + var storage: StateObject.Storage + + @inlinable + public init(wrappedValue thunk: @autoclosure @escaping () -> ObjectType) { + storage = .initially(thunk) + } + + public var wrappedValue: ObjectType { + objectValue.wrappedValue + } + + public var projectedValue: ObservedObject.Wrapper { + objectValue.projectedValue + } +} + +extension StateObject: DynamicProperty { + public static func _makeProperty(in _: inout _DynamicPropertyBuffer, container _: _GraphValue, fieldOffset _: Int, inputs _: inout _GraphInputs) { + // TODO: + } + + public static var _propertyBehaviors: UInt32 { 2 } +} + +extension StateObject { + var objectValue: ObservedObject { + switch storage { + case let .initially(thunk): + Log.runtimeIssues("Accessing StateObject's object without being installed on a View. This will create a new instance each time.") + return ObservedObject(wrappedValue: thunk()) + case let .object(value): + return value + } + } +}