Skip to content

Commit

Permalink
Merge pull request #83 from omochi/refactor-render
Browse files Browse the repository at this point in the history
リファクタリング
  • Loading branch information
omochi authored Apr 24, 2024
2 parents a5ed0a1 + 34496e1 commit 637eff7
Show file tree
Hide file tree
Showing 16 changed files with 381 additions and 363 deletions.
17 changes: 2 additions & 15 deletions Sources/React/Element/Component.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,15 @@ public protocol Component: Element {
var deps: Deps? { get }

func render() -> Node

static func _extractGhost(_ input: GhostInput<Self>) -> Ghost
}

extension Component {
public var key: AnyHashable? { nil }

public var deps: Deps? { nil }
}

static func extractGhostDefault(_ input: GhostInput<Self>) -> Ghost {
let hooks = extractHooks(input.component)

return Ghost(
component: input.component,
hooks: hooks
)
}

enum Components {
static func extractHooks(_ value: Any) -> [any _AnyHookWrapper] {
var hooks: [any _AnyHookWrapper] = []

Expand All @@ -40,8 +31,4 @@ extension Component {

return hooks
}

public static func _extractGhost(_ input: GhostInput<Self>) -> Ghost {
extractGhostDefault(input)
}
}
28 changes: 0 additions & 28 deletions Sources/React/Element/Ghost.swift

This file was deleted.

14 changes: 8 additions & 6 deletions Sources/React/Hooks/Context/ContextValueProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extension ContextValue {
public typealias Provider = ContextValueProvider<Self>
}

public struct ContextValueProvider<Value: ContextValue>: Component {
public struct ContextValueProvider<Value: ContextValue>: Component & _AnyContextValueProvider {
public init(
key: AnyHashable? = nil,
value: Value,
Expand All @@ -29,9 +29,11 @@ public struct ContextValueProvider<Value: ContextValue>: Component {
children
}

public static func _extractGhost(_ input: GhostInput<Self>) -> Ghost {
var ghost = extractGhostDefault(input)
ghost.contextValue = (type: Value.self, value: input.component.value)
return ghost
}
var _contextValueType: any ContextValue.Type { Value.self }
var _contextValue: any ContextValue { value }
}

internal protocol _AnyContextValueProvider {
var _contextValueType: any ContextValue.Type { get }
var _contextValue: any ContextValue { get }
}
5 changes: 5 additions & 0 deletions Sources/React/Hooks/Effect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public struct Effect: _AnyEffectHook {
shouldExecute = false
return Task(object: self, setup: setup)
}

func cleanupTask() -> Task? {
if cleanup == nil { return nil }
return Task(object: self, setup: nil)
}
}

final class Task {
Expand Down
5 changes: 5 additions & 0 deletions Sources/React/Image/Image.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public struct Image {

}


104 changes: 104 additions & 0 deletions Sources/React/Renderer/Instance.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import SRTDOM

package final class Instance {
final class ListenerBridge {
init() {}

var js: JSEventListener?
var swift: EventListener?
}

init() {

}

weak var owner: VNode?
var hooks: [any _AnyHookWrapper] = []
public var dom: JSNode?
var attributes: Attributes = [:]
var listeners: [String: ListenerBridge] = [:]
var contextValueHolder: ContextValueHolder?
var isDirty: Bool = false

var contextHooks: [any _AnyContextHook] {
hooks.compactMap { $0 as? any _AnyContextHook }
}

var stateHooks: [any _AnyStateHook] {
hooks.compactMap { $0 as? any _AnyStateHook }
}

var effectHooks: [any _AnyEffectHook] {
hooks.compactMap { $0 as? any _AnyEffectHook }
}

func renderDOMAttributes(
attributes newAttributes: Attributes
) throws {
let dom = try (self.dom?.asHTMLElement()).unwrap("dom.asHTMLElement")
let oldAttributes = self.attributes

for name in self.attributes.keys {
if newAttributes[name] == nil {
try dom.removeAttribute(name)
}
}

for (name, newValue) in newAttributes {
if newValue != oldAttributes[name] {
try dom.setAttribute(name, newValue)
}
}

self.attributes = newAttributes
}

func renderDOMListeners(
listeners newListeners: EventListeners
) throws {
let dom = try (self.dom?.asHTMLElement()).unwrap("dom.asHTMLElement")

// コピー必要なんだっけ?
for (type, bridge) in Array(self.listeners) {
if bridge.swift != newListeners[type] {
if let js = bridge.js {
try dom.removeEventListener(type, js)
}
self.listeners[type] = nil
}
}

for (type, newListener) in newListeners {
if let bridge = self.listeners[type] {
if newListener == bridge.swift {
continue
}

bridge.swift = newListener
} else {
let bridge = ListenerBridge()
self.listeners[type] = bridge

let js = JSEventListener { [weak bridge] (event) in
guard let bridge, let swift = bridge.swift else { return }
swift(event)
}

bridge.js = js
bridge.swift = newListener

try dom.addEventListener(type, js)
}
}
}

func markDirty() {
isDirty = true
}

func consumeDirty() -> Bool {
defer { isDirty = false }
return isDirty
}

}
Loading

0 comments on commit 637eff7

Please sign in to comment.