Remove Derivation.tapImmediate()

This is now just an extra flag on `Derivation.onChange()`
This commit is contained in:
Aria Minaei 2022-12-01 13:45:27 +01:00
parent f2bb24ef99
commit a24a149a52
10 changed files with 60 additions and 59 deletions

View file

@ -18,9 +18,13 @@ export interface IDerivation<V> {
isHot: boolean isHot: boolean
/** /**
* Returns a `Tappable` of the changes of this derivation. * Calls `listener` with a fresh value every time the prism _has_ a new value, throttled by Ticker.
*/ */
onChange(ticker: Ticker, listener: (v: V) => void): VoidFn onChange(
ticker: Ticker,
listener: (v: V) => void,
immediate?: boolean,
): VoidFn
onStale(cb: () => void): VoidFn onStale(cb: () => void): VoidFn
@ -29,17 +33,6 @@ export interface IDerivation<V> {
*/ */
keepHot(): VoidFn keepHot(): VoidFn
/**
* Convenience method that taps (subscribes to) the derivation using `this.changes(ticker).tap(fn)` and immediately calls
* the callback with the current value.
*
* @param ticker - The ticker to use for batching.
* @param fn - The callback to call on update.
*
* @see onChange
*/
tapImmediate(ticker: Ticker, fn: (cb: V) => void): VoidFn
/** /**
* Add a derivation as a dependent of this derivation. * Add a derivation as a dependent of this derivation.
* *

View file

@ -222,8 +222,18 @@ class PrismDerivation<V> implements IDerivation<V> {
return this._state.hot return this._state.hot
} }
onChange(ticker: Ticker, listener: (v: V) => void): VoidFn { onChange(
return new DerivationEmitter(this, ticker).tappable().tap(listener) ticker: Ticker,
listener: (v: V) => void,
immediate: boolean = false,
): VoidFn {
const unsubscribe = new DerivationEmitter(this, ticker)
.tappable()
.tap(listener)
if (immediate) {
listener(this.getValue())
}
return unsubscribe
} }
/** /**
@ -245,21 +255,6 @@ class PrismDerivation<V> implements IDerivation<V> {
return this.onStale(() => {}) return this.onStale(() => {})
} }
/**
* Convenience method that taps (subscribes to) the derivation using `this.changes(ticker).tap(fn)` and immediately calls
* the callback with the current value.
*
* @param ticker - The ticker to use for batching.
* @param fn - The callback to call on update.
*
* @see onChange
*/
tapImmediate(ticker: Ticker, fn: (cb: V) => void): VoidFn {
const untap = this.onChange(ticker, fn)
fn(this.getValue())
return untap
}
/** /**
* Add a derivation as a dependent of this derivation. * Add a derivation as a dependent of this derivation.
* *

View file

@ -72,13 +72,6 @@ export default class Tappable<V> {
} }
} }
/*
* tapImmediate(cb: Listener<V>): Untap {
* const ret = this.tap(cb)
* return ret
* }
*/
private _removeTapperById(id: number) { private _removeTapperById(id: number) {
this._tappers.delete(id) this._tappers.delete(id)
this._check() this._check()

View file

@ -13,9 +13,9 @@ import {Box, prism, Ticker, val} from '@theatre/dataverse'
* *
* Without going into the details of `prism`, `Ticker`, and `val`, note that by wrapping our `ToolsetConfig` in a prism, our * Without going into the details of `prism`, `Ticker`, and `val`, note that by wrapping our `ToolsetConfig` in a prism, our
* ```ts * ```ts
* ... .tapImmediate(Ticker.raf, (toolset) => { * ... .onChange(Ticker.raf, (toolset) => {
* set(toolset) * set(toolset)
* }) * }, true)
* ``` * ```
* code will be called whenever `val(obj.props.exampleProp)` changes (whenever the user clicks the switch and the `onChange` callback is called). * code will be called whenever `val(obj.props.exampleProp)` changes (whenever the user clicks the switch and the `onChange` callback is called).
* This will ensure that our switch's value matches its state and is reflected in the UI via `set(toolset)`. * This will ensure that our switch's value matches its state and is reflected in the UI via `set(toolset)`.
@ -56,9 +56,13 @@ studio.extend({
}, },
]) ])
// listen to changes to this derivation using the requestAnimationFrame shared ticker // listen to changes to this derivation using the requestAnimationFrame shared ticker
.tapImmediate(Ticker.raf, (value) => { .onChange(
Ticker.raf,
(value) => {
set(value) set(value)
}) },
true,
)
return untapFn return untapFn
}, },

View file

@ -35,9 +35,13 @@ const r3fExtension: IExtension = {
}, },
] ]
}) })
return calc.tapImmediate(Ticker.raf, () => { return calc.onChange(
Ticker.raf,
() => {
set(calc.getValue()) set(calc.getValue())
}) },
true,
)
}, },
'snapshot-editor': (set, studio) => { 'snapshot-editor': (set, studio) => {
const {createSnapshot} = useExtensionStore.getState() const {createSnapshot} = useExtensionStore.getState()
@ -136,9 +140,13 @@ const r3fExtension: IExtension = {
}, },
] ]
}) })
return calc.tapImmediate(Ticker.raf, () => { return calc.onChange(
Ticker.raf,
() => {
set(calc.getValue()) set(calc.getValue())
}) },
true,
)
}, },
}, },
panes: [ panes: [

View file

@ -156,9 +156,13 @@ export function onChange<P extends PointerType<$IntentionalAny>>(
): VoidFn { ): VoidFn {
if (isPointer(pointer)) { if (isPointer(pointer)) {
const derivation = valueDerivation(pointer) const derivation = valueDerivation(pointer)
return derivation.tapImmediate(getCoreTicker(), callback as $IntentionalAny) return derivation.onChange(
getCoreTicker(),
callback as $IntentionalAny,
true,
)
} else if (isDerivation(pointer)) { } else if (isDerivation(pointer)) {
return pointer.tapImmediate(getCoreTicker(), callback as $IntentionalAny) return pointer.onChange(getCoreTicker(), callback as $IntentionalAny, true)
} else { } else {
throw new Error( throw new Error(
`Called onChange(p) where p is neither a pointer nor a derivation.`, `Called onChange(p) where p is neither a pointer nor a derivation.`,

View file

@ -158,7 +158,7 @@ export default class TheatreSheetObject<
} }
onValuesChange(fn: (values: this['value']) => void): VoidFn { onValuesChange(fn: (values: this['value']) => void): VoidFn {
return this._valuesDerivation().tapImmediate(getCoreTicker(), fn) return this._valuesDerivation().onChange(getCoreTicker(), fn, true)
} }
// internal: Make the deviration keepHot if directly read // internal: Make the deviration keepHot if directly read

View file

@ -440,7 +440,7 @@ export default class TheatreStudio implements IStudio {
} }
onSelectionChange(fn: (s: (ISheetObject | ISheet)[]) => void): VoidFn { onSelectionChange(fn: (s: (ISheetObject | ISheet)[]) => void): VoidFn {
return this._getSelectionDerivation().tapImmediate(studioTicker, fn) return this._getSelectionDerivation().onChange(studioTicker, fn, true)
} }
get selection(): Array<ISheetObject | ISheet> { get selection(): Array<ISheetObject | ISheet> {

View file

@ -75,12 +75,16 @@ const FrameGrid: React.FC<{
fps: sequence.subUnitsPerUnit, fps: sequence.subUnitsPerUnit,
snapToGrid: (n: number) => sequence.closestGridPosition(n), snapToGrid: (n: number) => sequence.closestGridPosition(n),
} }
}).tapImmediate(studioTicker, (p) => { }).onChange(
studioTicker,
(p) => {
ctx.save() ctx.save()
ctx.scale(ratio!, ratio!) ctx.scale(ratio!, ratio!)
drawGrid(p) drawGrid(p)
ctx.restore() ctx.restore()
}) },
true,
)
return () => { return () => {
untap() untap()

View file

@ -86,7 +86,7 @@ const StampsGrid: React.FC<{
sequencePositionFormatter: sequence.positionFormatter, sequencePositionFormatter: sequence.positionFormatter,
snapToGrid: (n: number) => sequence.closestGridPosition(n), snapToGrid: (n: number) => sequence.closestGridPosition(n),
} }
}).tapImmediate(studioTicker, drawStamps) }).onChange(studioTicker, drawStamps, true)
}, [fullSecondStampsContainer, width, layoutP]) }, [fullSecondStampsContainer, width, layoutP])
return ( return (