GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — JavaScriptKit/Sources/JavaScriptKit/JSTracing.swift at main · cuberoot/JavaScriptKit Expand file tree/ Copy pathJSTracing.swiftMore file actions 133 lines (111 loc) · 4.09 KB / Copy pathJSTracing.swiftFile metadata and controls133 lines (111 loc) · 4.09 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 #if Tracing /// Hooks for tracing Swift <-> JavaScript bridge calls. public struct JSTracing: Sendable { public static let `default` = JSTracing() public enum JSCallInfo { case function(function: JSObject, arguments: [JSValue]) case method(receiver: JSObject, methodName: String?, arguments: [JSValue]) } /// Register a hook for Swift to JavaScript calls. /// /// The hook is invoked at the start of the call. Return a closure to run when /// the call finishes, or `nil` to skip the end hook. /// /// - Returns: A cleanup closure that unregisters the hook. @discardableResult public func addJSCallHook( _ hook: @escaping (_ info: JSCallInfo) -> (() -> Void)? ) -> () -> Void { JSTracingHooks.addJSCallHook(hook) } public struct JSClosureCallInfo { /// The file identifier where the called `JSClosure` was created. public let fileID: String /// The line number where the called `JSClosure` was created. public let line: UInt } /// Register a hook for JavaScript to Swift calls via `JSClosure`. /// /// The hook is invoked at the start of the call. Return a closure to run when /// the call finishes, or `nil` to skip the end hook. /// /// - Returns: A cleanup closure that unregisters the hook. @discardableResult public func addJSClosureCallHook( _ hook: @escaping (_ info: JSClosureCallInfo) -> (() -> Void)? ) -> () -> Void { JSTracingHooks.addJSClosureCallHook(hook) } } enum JSTracingHooks { typealias HookEnd = () -> Void typealias JSCallHook = (JSTracing.JSCallInfo) -> HookEnd? typealias JSClosureCallHook = (JSTracing.JSClosureCallInfo) -> HookEnd? private final class HookList<Hook> { private var hooks: [(id: UInt, hook: Hook)] = [] private var nextID: UInt = 0 var isEmpty: Bool { hooks.isEmpty } func add(_ hook: Hook) -> UInt { let id = nextID nextID &+= 1 hooks.append((id, hook)) return id } func remove(id: UInt) { hooks.removeAll { $0.id == id } } func forEach(_ body: (Hook) -> Void) { for entry in hooks { body(entry.hook) } } } private final class Storage { let jsCallHooks = HookList<JSCallHook>() let jsClosureCallHooks = HookList<JSClosureCallHook>() } private static let storage = LazyThreadLocal(initialize: Storage.init) static func addJSCallHook(_ hook: @escaping JSCallHook) -> () -> Void { let storage = storage.wrappedValue let id = storage.jsCallHooks.add(hook) return { storage.jsCallHooks.remove(id: id) } } static func addJSClosureCallHook(_ hook: @escaping JSClosureCallHook) -> () -> Void { let storage = storage.wrappedValue let id = storage.jsClosureCallHooks.add(hook) return { storage.jsClosureCallHooks.remove(id: id) } } static func beginJSCall(_ info: JSTracing.JSCallInfo) -> HookEnd? { let storage = storage.wrappedValue guard !storage.jsCallHooks.isEmpty else { return nil } var callbacks: [HookEnd] = [] storage.jsCallHooks.forEach { hook in if let callback = hook(info) { callbacks.append(callback) } } guard !callbacks.isEmpty else { return nil } return { for callback in callbacks.reversed() { callback() } } } static func beginJSClosureCall(_ info: JSTracing.JSClosureCallInfo) -> HookEnd? { let storage = storage.wrappedValue guard !storage.jsClosureCallHooks.isEmpty else { return nil } var callbacks: [HookEnd] = [] storage.jsClosureCallHooks.forEach { hook in if let callback = hook(info) { callbacks.append(callback) } } guard !callbacks.isEmpty else { return nil } return { for callback in callbacks.reversed() { callback() } } } } #endif |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |