timeouts: rework effectschedule timeout tracking (#3870)
talked to @ds300 and decided that we needed to rework this latest bit to cleanup outside of `EffectScheduler` ### Change Type <!-- ❗ Please select a 'Scope' label ❗️ --> - [x] `sdk` — Changes the tldraw SDK - [ ] `dotcom` — Changes the tldraw.com web app - [ ] `docs` — Changes to the documentation, examples, or templates. - [ ] `vs code` — Changes to the vscode plugin - [ ] `internal` — Does not affect user-facing stuff <!-- ❗ Please select a 'Type' label ❗️ --> - [x] `bugfix` — Bug fix - [ ] `feature` — New feature - [ ] `improvement` — Improving existing features - [ ] `chore` — Updating dependencies, other boring stuff - [ ] `galaxy brain` — Architectural changes - [ ] `tests` — Changes to any test code - [ ] `tools` — Changes to infrastructure, CI, internal scripts, debugging tools, etc. - [ ] `dunno` — I don't know
This commit is contained in:
parent
aadc0aab4d
commit
e74d2470c5
2 changed files with 14 additions and 8 deletions
|
@ -35,7 +35,7 @@ interface EffectSchedulerOptions {
|
||||||
* @param execute - A function that will execute the effect.
|
* @param execute - A function that will execute the effect.
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
scheduleEffect?: (execute: () => void) => number | void | (() => void)
|
scheduleEffect?: (execute: () => void) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
class __EffectScheduler__<Result> {
|
class __EffectScheduler__<Result> {
|
||||||
|
@ -63,15 +63,13 @@ class __EffectScheduler__<Result> {
|
||||||
return this._scheduleCount
|
return this._scheduleCount
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
private maybeRaf: number | void | (() => void) = -1
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
readonly parentSet = new ArraySet<Signal<any, any>>()
|
readonly parentSet = new ArraySet<Signal<any, any>>()
|
||||||
/** @internal */
|
/** @internal */
|
||||||
readonly parentEpochs: number[] = []
|
readonly parentEpochs: number[] = []
|
||||||
/** @internal */
|
/** @internal */
|
||||||
readonly parents: Signal<any, any>[] = []
|
readonly parents: Signal<any, any>[] = []
|
||||||
private readonly _scheduleEffect?: (execute: () => void) => number | void | (() => void)
|
private readonly _scheduleEffect?: (execute: () => void) => void
|
||||||
constructor(
|
constructor(
|
||||||
public readonly name: string,
|
public readonly name: string,
|
||||||
private readonly runEffect: (lastReactedEpoch: number) => Result,
|
private readonly runEffect: (lastReactedEpoch: number) => Result,
|
||||||
|
@ -101,7 +99,7 @@ class __EffectScheduler__<Result> {
|
||||||
this._scheduleCount++
|
this._scheduleCount++
|
||||||
if (this._scheduleEffect) {
|
if (this._scheduleEffect) {
|
||||||
// if the effect should be deferred (e.g. until a react render), do so
|
// if the effect should be deferred (e.g. until a react render), do so
|
||||||
this.maybeRaf = this._scheduleEffect(this.maybeExecute)
|
this._scheduleEffect(this.maybeExecute)
|
||||||
} else {
|
} else {
|
||||||
// otherwise execute right now!
|
// otherwise execute right now!
|
||||||
this.execute()
|
this.execute()
|
||||||
|
@ -137,7 +135,6 @@ class __EffectScheduler__<Result> {
|
||||||
for (let i = 0, n = this.parents.length; i < n; i++) {
|
for (let i = 0, n = this.parents.length; i < n; i++) {
|
||||||
detach(this.parents[i], this)
|
detach(this.parents[i], this)
|
||||||
}
|
}
|
||||||
typeof this.maybeRaf === 'number' && cancelAnimationFrame(this.maybeRaf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
import { useEffect, useMemo } from 'react'
|
import { useEffect, useMemo, useRef } from 'react'
|
||||||
import { EffectScheduler } from '../core'
|
import { EffectScheduler } from '../core'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useReactor(name: string, reactFn: () => void, deps: undefined | any[] = []) {
|
export function useReactor(name: string, reactFn: () => void, deps: undefined | any[] = []) {
|
||||||
|
const raf = useRef(-1)
|
||||||
const scheduler = useMemo(
|
const scheduler = useMemo(
|
||||||
() => new EffectScheduler(name, reactFn, { scheduleEffect: (cb) => requestAnimationFrame(cb) }),
|
() =>
|
||||||
|
new EffectScheduler(name, reactFn, {
|
||||||
|
scheduleEffect: (cb) => {
|
||||||
|
const rafId = requestAnimationFrame(cb)
|
||||||
|
raf.current = rafId
|
||||||
|
return rafId
|
||||||
|
},
|
||||||
|
}),
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
deps
|
deps
|
||||||
)
|
)
|
||||||
|
@ -14,6 +22,7 @@ export function useReactor(name: string, reactFn: () => void, deps: undefined |
|
||||||
scheduler.execute()
|
scheduler.execute()
|
||||||
return () => {
|
return () => {
|
||||||
scheduler.detach()
|
scheduler.detach()
|
||||||
|
cancelAnimationFrame(raf.current)
|
||||||
}
|
}
|
||||||
}, [scheduler])
|
}, [scheduler])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue