Skip to content

Commit

Permalink
Doc
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Usbergo committed Feb 28, 2021
1 parent f865af2 commit fb88de4
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"repositoryURL": "https://github.com/alexdrone/Store",
"state": {
"branch": "master",
"revision": "6e7c14c6433d8a3f056606728700114cd90d6ea5",
"revision": "f865af25d460688e9f744331de726d58116bfe38",
"version": null
}
},
Expand All @@ -24,8 +24,8 @@
"repositoryURL": "https://github.com/apple/swift-log.git",
"state": {
"branch": null,
"revision": "173f567a2dfec11d74588eea82cecea555bdc0bc",
"version": "1.4.0"
"revision": "12d3a8651d32295794a850307f77407f95b8c881",
"version": "1.4.1"
}
}
]
Expand Down
20 changes: 13 additions & 7 deletions Sources/Store/action/KeyPath+Introspection.swift
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
extension KeyPath {
import Foundation

public extension KeyPath {

/// Returns the human readable name for the property pointed at.
var readableFormat: String? {
guard let offset = MemoryLayout<Root>.offset(of: self) else {
return nil
}
let typePtr = unsafeBitCast(Root.self, to: UnsafeMutableRawPointer.self)
let metadata = typePtr.assumingMemoryBound(to: StructMetadata.self)
let kind = metadata.pointee._kind

// see https://github.com/apple/swift/blob/main/include/swift/ABI/MetadataKind.def
guard kind == 1 || kind == 0x200 else {
assertionFailure()
return nil
}

let typeDescriptor = metadata.pointee.typeDescriptor
let numberOfFields = Int(typeDescriptor.pointee.numberOfFields)
let offsets = typeDescriptor.pointee
.offsetToTheFieldOffsetVector
let offsets = typeDescriptor.pointee.offsetToTheFieldOffsetVector
.buffer(metadata: typePtr, count: numberOfFields)

guard let fieldIndex = offsets.firstIndex(of: Int32(offset)) else {
return nil
}
Expand All @@ -26,7 +32,8 @@ extension KeyPath {
}
}

// MARK: - Layout
// MARK: - Internal Layout

private struct StructMetadata {
var _kind: Int
var typeDescriptor: UnsafeMutablePointer<StructTypeDescriptor>
Expand Down Expand Up @@ -67,9 +74,8 @@ private struct Buffer<Element> {
var element: Element

mutating func pointer() -> UnsafeMutablePointer<Element> {
return withUnsafePointer(to: &self) {
UnsafeMutableRawPointer(mutating: UnsafeRawPointer($0))
.assumingMemoryBound(to: Element.self)
withUnsafePointer(to: &self) {
UnsafeMutableRawPointer(mutating: UnsafeRawPointer($0)).assumingMemoryBound(to: Element.self)
}
}
}
Expand Down
24 changes: 14 additions & 10 deletions Sources/Store/store/BindingProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,20 @@ public func ?? <T>(lhs: Binding<T?>, rhs: T) -> Binding<T> {
)
}

/// Bridges any binding to a `String` binding.
public func BindingAsString<T>(
_ binding: Binding<T>,
_ encode: @escaping (T) -> String = { "\($0)" },
_ decode: @escaping (String) -> T
) -> Binding<String> {
Binding(
get: { encode(binding.wrappedValue) },
set: { binding.wrappedValue = decode($0) }
)
extension Binding {

/// When the `Binding`'s `wrappedValue` changes, the given closure is executed.
///
/// - Parameter closure: Chunk of code to execute whenever the value changes.
/// - Returns: New `Binding`.
func onUpdate(_ closure: @escaping () -> Void) -> Binding<Value> {
Binding(
get: { wrappedValue },
set: {
wrappedValue = $0
closure()
})
}
}

#endif
18 changes: 13 additions & 5 deletions Sources/Store/store/ModelStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import OpenCombineDispatch
/// It provides observability and thread-safe access to the underlying model.
///
/// Abstract base class for `ModelStorage` and `ChildModelStorage`.
@dynamicMemberLookup open class ModelStorageBase<M>: ObservableObject {
@dynamicMemberLookup
open class ModelStorageBase<M>: ObservableObject {

/// A publisher that publishes changes from observable objects.
public let objectWillChange = ObservableObjectPublisher()
Expand Down Expand Up @@ -40,8 +41,9 @@ import OpenCombineDispatch
fileprivate var _parentObjectWillChangeObserver: AnyCancellable?
}


@dynamicMemberLookup public final class ModelStorage<M>: ModelStorageBase<M> {
/// Concrete implementation for `ModelStorageBase`.
@dynamicMemberLookup
public final class ModelStorage<M>: ModelStorageBase<M> {

override public var model: M { _model }

Expand All @@ -66,7 +68,10 @@ import OpenCombineDispatch
}
}

@dynamicMemberLookup public final class ChildModelStorage<P, M>: ModelStorageBase<M> {
/// Create a model storage from a `ModelStorage` model subtree defined by a key path.
/// The model for this store is shared with the parent.
@dynamicMemberLookup
public final class ChildModelStorage<P, M>: ModelStorageBase<M> {

override public var model: M { _parent[dynamicMember: _keyPath] }

Expand All @@ -93,7 +98,10 @@ import OpenCombineDispatch
}
}

@dynamicMemberLookup public final class UnownedChildModelStorage<P, M>: ModelStorageBase<M> {
/// Whenever this object change the parent model is reconciled with the change (and will
/// subsequently emit an `objectWillChange` notification).
@dynamicMemberLookup
public final class UnownedChildModelStorage<P, M>: ModelStorageBase<M> {
private let _parent: ModelStorageBase<P>
private var _model: M
private let _merge: (inout P, M) -> Void
Expand Down
3 changes: 1 addition & 2 deletions Sources/Store/store/Store.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ open class Store<M>: ReducibleStore, ObservableObject, Identifiable {
didUpdateModel(transaction: transaction, old: old, new: new)
}

public func reduceSync(closure: @escaping (inout M) -> Void) {
public func reduceSynchronous(closure: @escaping (inout M) -> Void) {
let action = Reduce<M>(reduce: closure)
run(actions: [action], mode: .sync, handler: nil)
}
Expand All @@ -177,7 +177,6 @@ open class Store<M>: ReducibleStore, ObservableObject, Identifiable {
_performWithoutNotifyingObservers = false
}


// MARK: Middleware

public func notifyMiddleware(transaction: AnyTransaction) {
Expand Down
4 changes: 2 additions & 2 deletions Tests/StoreTests/StoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ final class StoreTests: XCTestCase {
XCTAssert(store.modelStorage.count == 3)
}

func testReduceSync() {
func testreduceSynchronous() {
let store = CodableStore(model: TestModel(), diffing: .sync)
store.reduceSync { $0.count = 3 }
store.reduceSynchronous { $0.count = 3 }
XCTAssert(store.modelStorage.count == 3)
}

Expand Down

0 comments on commit fb88de4

Please sign in to comment.