Implement a basic benchmark test, and deprecate derivation.map()/flatMap()
This starts a new workspace at `packages/benchmarks` where future benchmarks are going to sit. For now, it only contains a basic profile of a `sequence.play()` setup. It also removes all uses of `AbstractDerivation.map()/flatMap()` and uses prisms instead.
This commit is contained in:
parent
45b548660c
commit
ae8be59366
26 changed files with 37584 additions and 56 deletions
|
@ -12,9 +12,9 @@ import type {PointerType} from '@theatre/dataverse'
|
|||
import {isPointer} from '@theatre/dataverse'
|
||||
import {isDerivation, valueDerivation} from '@theatre/dataverse'
|
||||
import type {$IntentionalAny, VoidFn} from '@theatre/shared/utils/types'
|
||||
import coreTicker from './coreTicker'
|
||||
import type {ProjectId} from '@theatre/shared/utils/ids'
|
||||
import {_coreLogger} from './_coreLogger'
|
||||
import {getCoreTicker} from './coreTicker'
|
||||
export {notify} from '@theatre/shared/notify'
|
||||
export {types}
|
||||
|
||||
|
@ -156,9 +156,9 @@ export function onChange<P extends PointerType<$IntentionalAny>>(
|
|||
): VoidFn {
|
||||
if (isPointer(pointer)) {
|
||||
const derivation = valueDerivation(pointer)
|
||||
return derivation.tapImmediate(coreTicker, callback as $IntentionalAny)
|
||||
return derivation.tapImmediate(getCoreTicker(), callback as $IntentionalAny)
|
||||
} else if (isDerivation(pointer)) {
|
||||
return pointer.tapImmediate(coreTicker, callback as $IntentionalAny)
|
||||
return pointer.tapImmediate(getCoreTicker(), callback as $IntentionalAny)
|
||||
} else {
|
||||
throw new Error(
|
||||
`Called onChange(p) where p is neither a pointer nor a derivation.`,
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
import {Ticker} from '@theatre/dataverse'
|
||||
|
||||
const coreTicker = Ticker.raf
|
||||
let coreTicker: Ticker
|
||||
|
||||
export default coreTicker
|
||||
export function setCoreTicker(ticker: Ticker) {
|
||||
if (coreTicker) {
|
||||
throw new Error(`coreTicker is already set`)
|
||||
}
|
||||
coreTicker = ticker
|
||||
}
|
||||
|
||||
export function getCoreTicker(): Ticker {
|
||||
if (!coreTicker) {
|
||||
coreTicker = Ticker.raf
|
||||
}
|
||||
return coreTicker
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import type Project from '@theatre/core/projects/Project'
|
||||
import coreTicker from '@theatre/core/coreTicker'
|
||||
import type Sheet from '@theatre/core/sheets/Sheet'
|
||||
import type {SequenceAddress} from '@theatre/shared/utils/addresses'
|
||||
import didYouMean from '@theatre/shared/utils/didYouMean'
|
||||
import {InvalidArgumentError} from '@theatre/shared/utils/errors'
|
||||
import type {IBox, IDerivation, Pointer} from '@theatre/dataverse'
|
||||
import {pointer} from '@theatre/dataverse'
|
||||
import {Box, prism, val, valueDerivation} from '@theatre/dataverse'
|
||||
import {Box, prism, val} from '@theatre/dataverse'
|
||||
import {padStart} from 'lodash-es'
|
||||
import type {
|
||||
IPlaybackController,
|
||||
|
@ -17,6 +16,7 @@ import TheatreSequence from './TheatreSequence'
|
|||
import type {ILogger} from '@theatre/shared/logger'
|
||||
import type {ISequence} from '..'
|
||||
import {notify} from '@theatre/shared/notify'
|
||||
import {getCoreTicker} from '@theatre/core/coreTicker'
|
||||
|
||||
export type IPlaybackRange = [from: number, to: number]
|
||||
|
||||
|
@ -63,20 +63,22 @@ export default class Sequence {
|
|||
this.publicApi = new TheatreSequence(this)
|
||||
|
||||
this._playbackControllerBox = new Box(
|
||||
playbackController ?? new DefaultPlaybackController(coreTicker),
|
||||
playbackController ?? new DefaultPlaybackController(getCoreTicker()),
|
||||
)
|
||||
|
||||
this._statePointerDerivation = this._playbackControllerBox.derivation.map(
|
||||
(playbackController) => playbackController.statePointer,
|
||||
this._statePointerDerivation = prism(
|
||||
() => this._playbackControllerBox.derivation.getValue().statePointer,
|
||||
)
|
||||
|
||||
this._positionD = this._statePointerDerivation.flatMap((statePointer) =>
|
||||
valueDerivation(statePointer.position),
|
||||
)
|
||||
this._positionD = prism(() => {
|
||||
const statePointer = this._statePointerDerivation.getValue()
|
||||
return val(statePointer.position)
|
||||
})
|
||||
|
||||
this._positionFormatterD = this._subUnitsPerUnitD.map(
|
||||
(subUnitsPerUnit) => new TimeBasedPositionFormatter(subUnitsPerUnit),
|
||||
)
|
||||
this._positionFormatterD = prism(() => {
|
||||
const subUnitsPerUnit = val(this._subUnitsPerUnitD)
|
||||
return new TimeBasedPositionFormatter(subUnitsPerUnit)
|
||||
})
|
||||
}
|
||||
|
||||
getIdentityDerivation(path: Array<string | number>): IDerivation<unknown> {
|
||||
|
|
|
@ -3,7 +3,7 @@ import {defer} from '@theatre/shared/utils/defer'
|
|||
import type Sequence from './Sequence'
|
||||
import type {IPlaybackDirection, IPlaybackRange} from './Sequence'
|
||||
import AudioPlaybackController from './playbackControllers/AudioPlaybackController'
|
||||
import coreTicker from '@theatre/core/coreTicker'
|
||||
import {getCoreTicker} from '@theatre/core/coreTicker'
|
||||
import type {Pointer} from '@theatre/dataverse'
|
||||
import {notify} from '@theatre/shared/notify'
|
||||
|
||||
|
@ -289,7 +289,7 @@ export default class TheatreSequence implements ISequence {
|
|||
await resolveAudioBuffer(args)
|
||||
|
||||
const playbackController = new AudioPlaybackController(
|
||||
coreTicker,
|
||||
getCoreTicker(),
|
||||
decodedBuffer,
|
||||
audioContext,
|
||||
gainNode,
|
||||
|
|
|
@ -4,7 +4,7 @@ import type {
|
|||
TrackData,
|
||||
} from '@theatre/core/projects/store/types/SheetState_Historic'
|
||||
import type {IDerivation, Pointer} from '@theatre/dataverse'
|
||||
import {ConstantDerivation, prism, val} from '@theatre/dataverse'
|
||||
import {prism, val} from '@theatre/dataverse'
|
||||
import type {IUtilContext} from '@theatre/shared/logger'
|
||||
import type {SerializableValue} from '@theatre/shared/utils/types'
|
||||
import UnitBezier from 'timing-function/lib/UnitBezier'
|
||||
|
@ -36,12 +36,12 @@ export default function interpolationTripleAtPosition(
|
|||
'driver',
|
||||
() => {
|
||||
if (!track) {
|
||||
return new ConstantDerivation(undefined)
|
||||
return prism(() => undefined)
|
||||
} else if (track.type === 'BasicKeyframedTrack') {
|
||||
return _forKeyframedTrack(ctx, track, timeD)
|
||||
} else {
|
||||
ctx.logger.error(`Track type not yet supported.`)
|
||||
return new ConstantDerivation(undefined)
|
||||
return prism(() => undefined)
|
||||
}
|
||||
},
|
||||
[track],
|
||||
|
@ -79,7 +79,7 @@ function _forKeyframedTrack(
|
|||
})
|
||||
}
|
||||
|
||||
const undefinedConstD = new ConstantDerivation(undefined)
|
||||
const undefinedConstD = prism(() => undefined)
|
||||
|
||||
function updateState(
|
||||
ctx: IUtilContext,
|
||||
|
@ -159,7 +159,7 @@ const states = {
|
|||
started: true,
|
||||
validFrom: -Infinity,
|
||||
validTo: kf.position,
|
||||
der: new ConstantDerivation({left: kf.value, progression: 0}),
|
||||
der: prism(() => ({left: kf.value, progression: 0})),
|
||||
}
|
||||
},
|
||||
lastKeyframe(kf: Keyframe): IStartedState {
|
||||
|
@ -167,7 +167,7 @@ const states = {
|
|||
started: true,
|
||||
validFrom: kf.position,
|
||||
validTo: Infinity,
|
||||
der: new ConstantDerivation({left: kf.value, progression: 0}),
|
||||
der: prism(() => ({left: kf.value, progression: 0})),
|
||||
}
|
||||
},
|
||||
between(
|
||||
|
@ -180,7 +180,7 @@ const states = {
|
|||
started: true,
|
||||
validFrom: left.position,
|
||||
validTo: right.position,
|
||||
der: new ConstantDerivation({left: left.value, progression: 0}),
|
||||
der: prism(() => ({left: left.value, progression: 0})),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -228,7 +228,8 @@ export default class SheetObjectTemplate {
|
|||
*/
|
||||
getMapOfValidSequenceTracks_forStudio(): IDerivation<IPropPathToTrackIdTree> {
|
||||
return this._cache.get('getMapOfValidSequenceTracks_forStudio', () =>
|
||||
this.getArrayOfValidSequenceTracks().map((arr) => {
|
||||
prism(() => {
|
||||
const arr = val(this.getArrayOfValidSequenceTracks())
|
||||
let map = {}
|
||||
|
||||
for (const {pathToProp, trackId} of arr) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {privateAPI, setPrivateAPI} from '@theatre/core/privateAPIs'
|
||||
import type {IProject} from '@theatre/core/projects/TheatreProject'
|
||||
import coreTicker from '@theatre/core/coreTicker'
|
||||
import {getCoreTicker} from '@theatre/core/coreTicker'
|
||||
import type {ISheet} from '@theatre/core/sheets/TheatreSheet'
|
||||
import type {SheetObjectAddress} from '@theatre/shared/utils/addresses'
|
||||
import SimpleCache from '@theatre/shared/utils/SimpleCache'
|
||||
|
@ -158,7 +158,7 @@ export default class TheatreSheetObject<
|
|||
}
|
||||
|
||||
onValuesChange(fn: (values: this['value']) => void): VoidFn {
|
||||
return this._valuesDerivation().tapImmediate(coreTicker, fn)
|
||||
return this._valuesDerivation().tapImmediate(getCoreTicker(), fn)
|
||||
}
|
||||
|
||||
// internal: Make the deviration keepHot if directly read
|
||||
|
|
|
@ -7,7 +7,7 @@ import type {
|
|||
} from '@theatre/core/sheets/TheatreSheet'
|
||||
import TheatreSheet from '@theatre/core/sheets/TheatreSheet'
|
||||
import type {SheetAddress} from '@theatre/shared/utils/addresses'
|
||||
import {Atom, valueDerivation} from '@theatre/dataverse'
|
||||
import {Atom, prism, val} from '@theatre/dataverse'
|
||||
import type SheetTemplate from './SheetTemplate'
|
||||
import type {ObjectAddressKey, SheetInstanceId} from '@theatre/shared/utils/ids'
|
||||
import type {StrictRecord} from '@theatre/shared/utils/types'
|
||||
|
@ -88,15 +88,21 @@ export default class Sheet {
|
|||
|
||||
getSequence(): Sequence {
|
||||
if (!this._sequence) {
|
||||
const lengthD = valueDerivation(
|
||||
this.project.pointers.historic.sheetsById[this.address.sheetId].sequence
|
||||
.length,
|
||||
).map(sanitizeSequenceLength)
|
||||
const lengthD = prism(() => {
|
||||
const unsanitized = val(
|
||||
this.project.pointers.historic.sheetsById[this.address.sheetId]
|
||||
.sequence.length,
|
||||
)
|
||||
return sanitizeSequenceLength(unsanitized)
|
||||
})
|
||||
|
||||
const subUnitsPerUnitD = valueDerivation(
|
||||
this.project.pointers.historic.sheetsById[this.address.sheetId].sequence
|
||||
.subUnitsPerUnit,
|
||||
).map(sanitizeSequenceSubUnitsPerUnit)
|
||||
const subUnitsPerUnitD = prism(() => {
|
||||
const unsanitized = val(
|
||||
this.project.pointers.historic.sheetsById[this.address.sheetId]
|
||||
.sequence.subUnitsPerUnit,
|
||||
)
|
||||
return sanitizeSequenceSubUnitsPerUnit(unsanitized)
|
||||
})
|
||||
|
||||
this._sequence = new Sequence(
|
||||
this.template.project,
|
||||
|
|
|
@ -6,7 +6,7 @@ import type {ProjectState_Historic} from '@theatre/core/projects/store/storeType
|
|||
import type {SheetState_Historic} from '@theatre/core/projects/store/types/SheetState_Historic'
|
||||
import * as t from '@theatre/core/propTypes'
|
||||
import getStudio from '@theatre/studio/getStudio'
|
||||
import coreTicker from '@theatre/core/coreTicker'
|
||||
import {getCoreTicker} from '@theatre/core/coreTicker'
|
||||
import globals from './globals'
|
||||
import type {SheetId} from './utils/ids'
|
||||
/* eslint-enable no-restricted-syntax */
|
||||
|
@ -42,7 +42,7 @@ export async function setupTestSheet(sheetState: SheetState_Historic) {
|
|||
state: projectState,
|
||||
})
|
||||
|
||||
const ticker = coreTicker
|
||||
const ticker = getCoreTicker()
|
||||
|
||||
ticker.tick()
|
||||
await project.ready
|
||||
|
|
|
@ -109,7 +109,7 @@ export default function useKeyboardShortcuts() {
|
|||
)
|
||||
|
||||
const playbackPromise = seq.playDynamicRange(
|
||||
controlledPlaybackStateD.map(({range}) => range),
|
||||
prism(() => val(controlledPlaybackStateD).range),
|
||||
)
|
||||
|
||||
const playbackStateBox = getPlaybackStateBox(seq)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue