Add publisher for sceneSize
This commit is contained in:
parent
9d0e2fc067
commit
cd661ba4ba
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import OpenCombineShim
|
||||
|
||||
/// A reconciler modeled after React's
|
||||
/// [Fiber reconciler](https://reactjs.org/docs/faq-internals.html#what-is-react-fiber)
|
||||
|
@ -38,6 +39,8 @@ public final class FiberReconciler<Renderer: FiberRenderer> {
|
|||
|
||||
private let caches: Caches
|
||||
|
||||
private var sceneSizeCancellable: AnyCancellable?
|
||||
|
||||
private var isReconciling = false
|
||||
public var afterReconcileActions = [() -> ()]()
|
||||
|
||||
|
@ -72,7 +75,7 @@ public final class FiberReconciler<Renderer: FiberRenderer> {
|
|||
subviews: Subviews,
|
||||
cache: inout ()
|
||||
) -> CGSize {
|
||||
renderer.sceneSize
|
||||
renderer.sceneSize.value
|
||||
}
|
||||
|
||||
func placeSubviews(
|
||||
|
@ -112,6 +115,11 @@ public final class FiberReconciler<Renderer: FiberRenderer> {
|
|||
// Start by building the initial tree.
|
||||
alternate = current.createAndBindAlternate?()
|
||||
reconcile(from: current)
|
||||
|
||||
sceneSizeCancellable = renderer.sceneSize.sink { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
self.reconcile(from: self.current)
|
||||
}
|
||||
}
|
||||
|
||||
public init<A: App>(_ renderer: Renderer, _ app: A) {
|
||||
|
@ -136,6 +144,10 @@ public final class FiberReconciler<Renderer: FiberRenderer> {
|
|||
// Start by building the initial tree.
|
||||
alternate = current.createAndBindAlternate?()
|
||||
reconcile(from: current)
|
||||
sceneSizeCancellable = renderer.sceneSize.sink { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
self.reconcile(from: self.current)
|
||||
}
|
||||
}
|
||||
|
||||
/// A visitor that performs each pass used by the `FiberReconciler`.
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import OpenCombineShim
|
||||
|
||||
/// A renderer capable of performing mutations specified by a `FiberReconciler`.
|
||||
public protocol FiberRenderer {
|
||||
|
@ -39,7 +40,7 @@ public protocol FiberRenderer {
|
|||
var defaultEnvironment: EnvironmentValues { get }
|
||||
|
||||
/// The size of the window we are rendering in.
|
||||
var sceneSize: CGSize { get }
|
||||
var sceneSize: CurrentValueSubject<CGSize, Never> { get }
|
||||
|
||||
/// Whether layout is enabled for this renderer.
|
||||
var useDynamicLayout: Bool { get }
|
||||
|
|
|
@ -35,7 +35,7 @@ struct LayoutPass: FiberReconcilerPass {
|
|||
fiber.layout?.placeSubviews(
|
||||
in: .init(
|
||||
origin: .zero,
|
||||
size: fiber.geometry?.dimensions.size ?? reconciler.renderer.sceneSize
|
||||
size: fiber.geometry?.dimensions.size ?? reconciler.renderer.sceneSize.value
|
||||
),
|
||||
proposal: fiber.geometry?.proposal ?? .unspecified,
|
||||
subviews: caches.layoutSubviews(for: fiber),
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
import Foundation
|
||||
import JavaScriptKit
|
||||
import OpenCombineShim
|
||||
@_spi(TokamakCore)
|
||||
import TokamakCore
|
||||
@_spi(TokamakStaticHTML)
|
||||
|
@ -79,9 +80,8 @@ protocol DOMNodeConvertible: HTMLConvertible {
|
|||
public struct DOMFiberRenderer: FiberRenderer {
|
||||
public let rootElement: DOMElement
|
||||
|
||||
public var sceneSize: CGSize {
|
||||
.init(width: body.clientWidth.number!, height: body.clientHeight.number!)
|
||||
}
|
||||
private let resizeObserver: JSObject?
|
||||
public let sceneSize: CurrentValueSubject<CGSize, Never>
|
||||
|
||||
public let useDynamicLayout: Bool
|
||||
|
||||
|
@ -117,6 +117,21 @@ public struct DOMFiberRenderer: FiberRenderer {
|
|||
_ = reference.style.setProperty("width", "100vw")
|
||||
_ = reference.style.setProperty("height", "100vh")
|
||||
_ = reference.style.setProperty("position", "relative")
|
||||
|
||||
let sceneSizePublisher = CurrentValueSubject<CGSize, Never>(
|
||||
.init(width: body.clientWidth.number!, height: body.clientHeight.number!)
|
||||
)
|
||||
sceneSize = sceneSizePublisher
|
||||
resizeObserver = JSObject.global.ResizeObserver.function!.new(JSClosure { _ in
|
||||
sceneSizePublisher.send(
|
||||
.init(width: body.clientWidth.number!, height: body.clientHeight.number!)
|
||||
)
|
||||
return .undefined
|
||||
})
|
||||
_ = resizeObserver?.observe?(body)
|
||||
} else {
|
||||
sceneSize = .init(.zero)
|
||||
resizeObserver = nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,7 +222,7 @@ public struct DOMFiberRenderer: FiberRenderer {
|
|||
}
|
||||
}
|
||||
return .zero
|
||||
case let .resizable(.named(name, bundle: bundle), capInsets, resizingMode):
|
||||
case let .resizable(.named(name, bundle: bundle), _, _):
|
||||
if proposal == .unspecified {
|
||||
if let intrinsicSize = image._intrinsicSize {
|
||||
return intrinsicSize
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import OpenCombineShim
|
||||
@_spi(TokamakCore)
|
||||
import TokamakCore
|
||||
|
||||
|
@ -161,7 +162,7 @@ extension LayoutView: HTMLConvertible {
|
|||
public struct StaticHTMLFiberRenderer: FiberRenderer {
|
||||
public let rootElement: HTMLElement
|
||||
public let defaultEnvironment: EnvironmentValues
|
||||
public let sceneSize: CGSize
|
||||
public let sceneSize: CurrentValueSubject<CGSize, Never>
|
||||
public let useDynamicLayout: Bool
|
||||
|
||||
public init() {
|
||||
|
@ -173,7 +174,7 @@ public struct StaticHTMLFiberRenderer: FiberRenderer {
|
|||
@_spi(TokamakStaticHTML)
|
||||
public init(useDynamicLayout: Bool, sceneSize: CGSize) {
|
||||
self.useDynamicLayout = useDynamicLayout
|
||||
self.sceneSize = sceneSize
|
||||
self.sceneSize = .init(sceneSize)
|
||||
rootElement = .init(
|
||||
tag: "body", attributes: ["style": "margin: 0;"], innerHTML: nil, children: []
|
||||
)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import OpenCombineShim
|
||||
@_spi(TokamakCore) import TokamakCore
|
||||
|
||||
public protocol TestFiberPrimitive {
|
||||
|
@ -125,7 +126,7 @@ public final class TestFiberElement: FiberElement, CustomStringConvertible {
|
|||
}
|
||||
|
||||
public struct TestFiberRenderer: FiberRenderer {
|
||||
public let sceneSize: CGSize
|
||||
public let sceneSize: CurrentValueSubject<CGSize, Never>
|
||||
public let useDynamicLayout: Bool
|
||||
|
||||
public func measureText(
|
||||
|
@ -150,7 +151,7 @@ public struct TestFiberRenderer: FiberRenderer {
|
|||
|
||||
public init(_ rootElement: ElementType, size: CGSize, useDynamicLayout: Bool = false) {
|
||||
self.rootElement = rootElement
|
||||
sceneSize = size
|
||||
sceneSize = .init(size)
|
||||
self.useDynamicLayout = useDynamicLayout
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue