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/BasicObjects/JSTimer.swift at main · aehlke/JavaScriptKit Expand file tree/ Copy pathJSTimer.swiftMore file actions 96 lines (89 loc) · 4.06 KB / Copy pathJSTimer.swiftFile metadata and controls96 lines (89 loc) · 4.06 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 /// This timer is an abstraction over [`setInterval`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval) /// / [`clearInterval`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval) and /// [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) /// / [`clearTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) /// JavaScript functions. It intentionally doesn't match the JavaScript API, as a special care is /// needed to hold a reference to the timer closure and to call `JSClosure.release()` on it when the /// timer is deallocated. As a user, you have to hold a reference to a `JSTimer` instance for it to stay /// valid. The `JSTimer` API is also intentionally trivial, the timer is started right away, and the /// only way to invalidate the timer is to bring the reference count of the `JSTimer` instance to zero. /// For invalidation you should either store the timer in an optional property and assign `nil` to it, /// or deallocate the object that owns the timer. public final class JSTimer { enum ClosureStorage { case oneshot(JSOneshotClosure) case repeating(JSClosure) var jsValue: JSValue { switch self { case .oneshot(let closure): return closure.jsValue case .repeating(let closure): return closure.jsValue } } func release() { switch self { case .oneshot(let closure): closure.release() case .repeating(let closure): #if JAVASCRIPTKIT_WITHOUT_WEAKREFS closure.release() #else break // no-op #endif } } } /// Indicates whether this timer instance calls its callback repeatedly at a given delay. public let isRepeating: Bool private let closure: ClosureStorage /** Node.js and browser APIs are slightly different. `setTimeout`/`setInterval` return an object in Node.js, while browsers return a number. Fortunately, clearTimeout and clearInterval take corresponding types as their arguments, and we can store either as JSValue, so we can treat both cases uniformly. */ private let value: JSValue private let global = JSObject.global /** Creates a new timer instance that calls `setInterval` or `setTimeout` JavaScript functions for you under the hood. - Parameters: - millisecondsDelay: the amount of milliseconds before the `callback` closure is executed. - isRepeating: when `true` the `callback` closure is executed repeatedly at given `millisecondsDelay` intervals indefinitely until the timer is deallocated. - callback: the closure to be executed after a given `millisecondsDelay` interval. */ public init(millisecondsDelay: Double, isRepeating: Bool = false, callback: @escaping () -> Void) { if isRepeating { closure = .repeating( JSClosure { _ in callback() return .undefined } ) } else { closure = .oneshot( JSOneshotClosure { _ in callback() return .undefined } ) } self.isRepeating = isRepeating if isRepeating { value = global.setInterval.object!(arguments: [closure.jsValue, millisecondsDelay.jsValue]) } else { value = global.setTimeout.object!(arguments: [closure.jsValue, millisecondsDelay.jsValue]) } } /** Makes a corresponding `clearTimeout` or `clearInterval` call, depending on whether this timer instance is repeating. The `closure` instance is released manually here, as it is required for bridged closure instances. */ deinit { if isRepeating { global.clearInterval.object!(value) } else { global.clearTimeout.object!(value) } closure.release() } } |
| 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. |