Simplify Derivation.onChange()
It no longer uses `DerivationEmitter`.
This commit is contained in:
parent
a24a149a52
commit
194de8d833
3 changed files with 27 additions and 71 deletions
|
@ -1,64 +0,0 @@
|
|||
import type Ticker from '../Ticker'
|
||||
import Emitter from '../utils/Emitter'
|
||||
import type {default as Tappable} from '../utils/Tappable'
|
||||
import type {IDerivation} from './IDerivation'
|
||||
|
||||
/**
|
||||
* An event emitter that emits events on changes to a derivation.
|
||||
*/
|
||||
export default class DerivationEmitter<V> {
|
||||
private _derivation: IDerivation<V>
|
||||
private _ticker: Ticker
|
||||
private _emitter: Emitter<V>
|
||||
private _lastValue: undefined | V
|
||||
private _lastValueRecorded: boolean
|
||||
private _hadTappers: boolean
|
||||
|
||||
/**
|
||||
* @param derivation - The derivation to emit events for.
|
||||
* @param ticker - The ticker to use to batch events.
|
||||
*/
|
||||
constructor(derivation: IDerivation<V>, ticker: Ticker) {
|
||||
this._derivation = derivation
|
||||
this._ticker = ticker
|
||||
this._emitter = new Emitter()
|
||||
this._emitter.onNumberOfTappersChange(() => {
|
||||
this._reactToNumberOfTappersChange()
|
||||
})
|
||||
this._hadTappers = false
|
||||
this._lastValueRecorded = false
|
||||
this._lastValue = undefined
|
||||
return this
|
||||
}
|
||||
|
||||
private _possiblyMarkAsStale = () => {
|
||||
this._ticker.onThisOrNextTick(this._refresh)
|
||||
}
|
||||
|
||||
private _reactToNumberOfTappersChange() {
|
||||
const hasTappers = this._emitter.hasTappers()
|
||||
if (hasTappers !== this._hadTappers) {
|
||||
this._hadTappers = hasTappers
|
||||
if (hasTappers) {
|
||||
this._derivation.addDependent(this._possiblyMarkAsStale)
|
||||
} else {
|
||||
this._derivation.removeDependent(this._possiblyMarkAsStale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The tappable associated with the emitter. You can use it to tap (subscribe to) the underlying derivation.
|
||||
*/
|
||||
tappable(): Tappable<V> {
|
||||
return this._emitter.tappable
|
||||
}
|
||||
|
||||
private _refresh = () => {
|
||||
const newValue = this._derivation.getValue()
|
||||
if (newValue === this._lastValue && this._lastValueRecorded === true) return
|
||||
this._lastValue = newValue
|
||||
this._lastValueRecorded = true
|
||||
this._emitter.emit(newValue)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import type Ticker from '../../Ticker'
|
||||
import type {$IntentionalAny, VoidFn} from '../../types'
|
||||
import Stack from '../../utils/Stack'
|
||||
import DerivationEmitter from '../DerivationEmitter'
|
||||
import type {IDerivation} from '../IDerivation'
|
||||
import {isDerivation} from '../IDerivation'
|
||||
import {
|
||||
|
@ -200,6 +199,8 @@ class HotHandle<V> {
|
|||
}
|
||||
}
|
||||
|
||||
const emptyObject = {}
|
||||
|
||||
class PrismDerivation<V> implements IDerivation<V> {
|
||||
/**
|
||||
* Whether the object is a derivation.
|
||||
|
@ -227,12 +228,31 @@ class PrismDerivation<V> implements IDerivation<V> {
|
|||
listener: (v: V) => void,
|
||||
immediate: boolean = false,
|
||||
): VoidFn {
|
||||
const unsubscribe = new DerivationEmitter(this, ticker)
|
||||
.tappable()
|
||||
.tap(listener)
|
||||
if (immediate) {
|
||||
listener(this.getValue())
|
||||
const dependent = () => {
|
||||
ticker.onThisOrNextTick(refresh)
|
||||
}
|
||||
|
||||
let lastValue = emptyObject
|
||||
|
||||
const refresh = () => {
|
||||
const newValue = this.getValue()
|
||||
if (newValue === lastValue) return
|
||||
|
||||
lastValue = newValue
|
||||
listener(newValue)
|
||||
}
|
||||
|
||||
this.addDependent(dependent)
|
||||
|
||||
if (immediate) {
|
||||
lastValue = this.getValue()
|
||||
listener(lastValue as $IntentionalAny as V)
|
||||
}
|
||||
|
||||
const unsubscribe = () => {
|
||||
this.removeDependent(dependent)
|
||||
}
|
||||
|
||||
return unsubscribe
|
||||
}
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ export const Scene: React.FC<{project: IProject}> = ({project}) => {
|
|||
return studio.onSelectionChange((newState) => {
|
||||
setSelection(newState)
|
||||
})
|
||||
})
|
||||
}, [])
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null!)
|
||||
|
||||
|
|
Loading…
Reference in a new issue