fixing timing issues
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import css from "./ScriptDeviceEditor.sass?inline"
|
||||
import {DeviceBoxAdapter, DeviceHost, ParameterAdapterSet, ScriptCompiler, ScriptParamDeclaration} from "@opendaw/studio-adapters"
|
||||
import {asInstanceOf, Editing, EmptyExec, isDefined, Lifecycle, MutableObservableValue, Nullable, ObservableValue, Observer, Subscription, Terminable, Terminator, UUID} from "@opendaw/lib-std"
|
||||
import {asInstanceOf, Editing, EmptyExec, isDefined, Lifecycle, MutableObservableValue, Nullable, Observable, ObservableValue, Observer, Subscription, Terminable, Terminator, UUID} from "@opendaw/lib-std"
|
||||
import {AutomatableParameterFieldAdapter} from "@opendaw/studio-adapters"
|
||||
import {Promises} from "@opendaw/lib-runtime"
|
||||
import {createElement} from "@opendaw/lib-jsx"
|
||||
@@ -37,6 +37,7 @@ const boolModel = (editing: Editing, parameter: AutomatableParameterFieldAdapter
|
||||
type ScriptAdapter = DeviceBoxAdapter & {
|
||||
readonly box: ScriptCompiler.DeviceBox
|
||||
readonly parameters: ParameterAdapterSet
|
||||
readonly codeChanged: Observable<void>
|
||||
}
|
||||
|
||||
export type ScriptDeviceEditorConfig = {
|
||||
@@ -67,15 +68,21 @@ export const ScriptDeviceEditor = ({lifecycle, service, adapter, deviceHost, con
|
||||
const box = adapter.box
|
||||
const storedCode = box.code.getValue()
|
||||
const userCode = storedCode.length > 0 ? compiler.stripHeader(storedCode) : config.defaultCode
|
||||
let compiling = false
|
||||
const compile = async (code: string) => {
|
||||
const result = await Promises.tryCatch(compiler.compile(service.audioContext, editing, box, code))
|
||||
if (result.status === "resolved") {
|
||||
errorIcon.classList.add("hidden")
|
||||
errorIcon.title = ""
|
||||
} else {
|
||||
errorIcon.classList.remove("hidden")
|
||||
errorIcon.title = String(result.error)
|
||||
throw result.error
|
||||
compiling = true
|
||||
try {
|
||||
const result = await Promises.tryCatch(compiler.compile(service.audioContext, editing, box, code))
|
||||
if (result.status === "resolved") {
|
||||
errorIcon.classList.add("hidden")
|
||||
errorIcon.title = ""
|
||||
} else {
|
||||
errorIcon.classList.remove("hidden")
|
||||
errorIcon.title = String(result.error)
|
||||
throw result.error
|
||||
}
|
||||
} finally {
|
||||
compiling = false
|
||||
}
|
||||
}
|
||||
if (storedCode.length > 0) {
|
||||
@@ -132,6 +139,9 @@ export const ScriptDeviceEditor = ({lifecycle, service, adapter, deviceHost, con
|
||||
if (isActive) {service.closeCodeEditor()}
|
||||
}
|
||||
},
|
||||
adapter.codeChanged.subscribe(() => {
|
||||
if (!compiling) {compiler.load(service.audioContext, box).finally(EmptyExec)}
|
||||
}),
|
||||
service.activeCodeEditor.catchupAndSubscribe(option => {
|
||||
const isActive = option.map(state => UUID.equals(state.handler.uuid, adapter.uuid)).unwrapOrElse(false)
|
||||
toggleEditorButton.classList.toggle("active", isActive)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {asInstanceOf, isDefined, Nullable, StringMapping, Terminable, ValueMapping} from "@opendaw/lib-std"
|
||||
import {asInstanceOf, isDefined, Notifier, Nullable, Observable, StringMapping, Terminable, ValueMapping} from "@opendaw/lib-std"
|
||||
import {Field, StringField} from "@opendaw/lib-box"
|
||||
import {Pointers} from "@opendaw/studio-enums"
|
||||
import {WerkstattParameterBox} from "@opendaw/studio-boxes"
|
||||
@@ -182,11 +182,17 @@ export namespace ScriptParamDeclaration {
|
||||
stringMapping: resolveStringMapping(declaration)
|
||||
})
|
||||
|
||||
export type ScriptParamsBinding = {
|
||||
readonly terminable: Terminable
|
||||
readonly codeChanged: Observable<void>
|
||||
}
|
||||
|
||||
export const subscribeScriptParams = (parametric: ParameterAdapterSet,
|
||||
codeField: StringField,
|
||||
parametersField: Field<Pointers.Parameter>): Terminable => {
|
||||
parametersField: Field<Pointers.Parameter>): ScriptParamsBinding => {
|
||||
const cachedDeclarations = new Map<string, ParamDeclaration>()
|
||||
return Terminable.many(
|
||||
const codeChangedNotifier = new Notifier<void>()
|
||||
const terminable = Terminable.many(
|
||||
parametersField.pointerHub.catchupAndSubscribe({
|
||||
onAdded: (({box: parameterBox}) => {
|
||||
const paramBox = asInstanceOf(parameterBox, WerkstattParameterBox)
|
||||
@@ -219,7 +225,10 @@ export namespace ScriptParamDeclaration {
|
||||
adapter.updateMappings(valueMapping, stringMapping)
|
||||
cachedDeclarations.set(adapter.name, newDeclaration)
|
||||
}
|
||||
})
|
||||
codeChangedNotifier.notify()
|
||||
}),
|
||||
codeChangedNotifier
|
||||
)
|
||||
return {terminable, codeChanged: codeChangedNotifier}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Option, Terminator, UUID} from "@opendaw/lib-std"
|
||||
import {Observable, Option, Terminator, UUID} from "@opendaw/lib-std"
|
||||
import {Address, BooleanField, Int32Field, PointerField, StringField} from "@opendaw/lib-box"
|
||||
import {WerkstattDeviceBox} from "@opendaw/studio-boxes"
|
||||
import {Pointers} from "@opendaw/studio-enums"
|
||||
@@ -20,12 +20,15 @@ export class WerkstattDeviceBoxAdapter implements AudioEffectDeviceAdapter {
|
||||
readonly #context: BoxAdaptersContext
|
||||
readonly #box: WerkstattDeviceBox
|
||||
readonly #parametric: ParameterAdapterSet
|
||||
readonly #codeChanged: Observable<void>
|
||||
|
||||
constructor(context: BoxAdaptersContext, box: WerkstattDeviceBox) {
|
||||
this.#context = context
|
||||
this.#box = box
|
||||
this.#parametric = this.#terminator.own(new ParameterAdapterSet(this.#context))
|
||||
this.#terminator.own(ScriptParamDeclaration.subscribeScriptParams(this.#parametric, box.code, box.parameters))
|
||||
const {terminable, codeChanged} = ScriptParamDeclaration.subscribeScriptParams(this.#parametric, box.code, box.parameters)
|
||||
this.#terminator.own(terminable)
|
||||
this.#codeChanged = codeChanged
|
||||
}
|
||||
|
||||
get box(): WerkstattDeviceBox {return this.#box}
|
||||
@@ -37,6 +40,7 @@ export class WerkstattDeviceBoxAdapter implements AudioEffectDeviceAdapter {
|
||||
get minimizedField(): BooleanField {return this.#box.minimized}
|
||||
get host(): PointerField<Pointers.AudioEffectHost> {return this.#box.host}
|
||||
get parameters(): ParameterAdapterSet {return this.#parametric}
|
||||
get codeChanged(): Observable<void> {return this.#codeChanged}
|
||||
|
||||
deviceHost(): DeviceHost {
|
||||
return this.#context.boxAdapters
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Option, Terminator, UUID} from "@opendaw/lib-std"
|
||||
import {Observable, Option, Terminator, UUID} from "@opendaw/lib-std"
|
||||
import {Address, BooleanField, StringField} from "@opendaw/lib-box"
|
||||
import {ApparatDeviceBox} from "@opendaw/studio-boxes"
|
||||
import {DeviceHost, Devices, InstrumentDeviceBoxAdapter} from "../../DeviceAdapter"
|
||||
@@ -20,12 +20,15 @@ export class ApparatDeviceBoxAdapter implements InstrumentDeviceBoxAdapter {
|
||||
readonly #context: BoxAdaptersContext
|
||||
readonly #box: ApparatDeviceBox
|
||||
readonly #parametric: ParameterAdapterSet
|
||||
readonly #codeChanged: Observable<void>
|
||||
|
||||
constructor(context: BoxAdaptersContext, box: ApparatDeviceBox) {
|
||||
this.#context = context
|
||||
this.#box = box
|
||||
this.#parametric = this.#terminator.own(new ParameterAdapterSet(this.#context))
|
||||
this.#terminator.own(ScriptParamDeclaration.subscribeScriptParams(this.#parametric, box.code, box.parameters))
|
||||
const {terminable, codeChanged} = ScriptParamDeclaration.subscribeScriptParams(this.#parametric, box.code, box.parameters)
|
||||
this.#terminator.own(terminable)
|
||||
this.#codeChanged = codeChanged
|
||||
}
|
||||
|
||||
get box(): ApparatDeviceBox {return this.#box}
|
||||
@@ -38,6 +41,7 @@ export class ApparatDeviceBoxAdapter implements InstrumentDeviceBoxAdapter {
|
||||
get minimizedField(): BooleanField {return this.#box.minimized}
|
||||
get acceptsMidiEvents(): boolean {return true}
|
||||
get parameters(): ParameterAdapterSet {return this.#parametric}
|
||||
get codeChanged(): Observable<void> {return this.#codeChanged}
|
||||
|
||||
deviceHost(): DeviceHost {
|
||||
return this.#context.boxAdapters
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Option, Terminator, UUID} from "@opendaw/lib-std"
|
||||
import {Observable, Option, Terminator, UUID} from "@opendaw/lib-std"
|
||||
import {Address, BooleanField, Int32Field, PointerField, StringField} from "@opendaw/lib-box"
|
||||
import {SpielwerkDeviceBox} from "@opendaw/studio-boxes"
|
||||
import {Pointers} from "@opendaw/studio-enums"
|
||||
@@ -19,12 +19,15 @@ export class SpielwerkDeviceBoxAdapter implements MidiEffectDeviceAdapter {
|
||||
readonly #context: BoxAdaptersContext
|
||||
readonly #box: SpielwerkDeviceBox
|
||||
readonly #parametric: ParameterAdapterSet
|
||||
readonly #codeChanged: Observable<void>
|
||||
|
||||
constructor(context: BoxAdaptersContext, box: SpielwerkDeviceBox) {
|
||||
this.#context = context
|
||||
this.#box = box
|
||||
this.#parametric = this.#terminator.own(new ParameterAdapterSet(this.#context))
|
||||
this.#terminator.own(ScriptParamDeclaration.subscribeScriptParams(this.#parametric, box.code, box.parameters))
|
||||
const {terminable, codeChanged} = ScriptParamDeclaration.subscribeScriptParams(this.#parametric, box.code, box.parameters)
|
||||
this.#terminator.own(terminable)
|
||||
this.#codeChanged = codeChanged
|
||||
}
|
||||
|
||||
get box(): SpielwerkDeviceBox {return this.#box}
|
||||
@@ -36,6 +39,7 @@ export class SpielwerkDeviceBoxAdapter implements MidiEffectDeviceAdapter {
|
||||
get minimizedField(): BooleanField {return this.#box.minimized}
|
||||
get host(): PointerField<Pointers.MIDIEffectHost> {return this.#box.host}
|
||||
get parameters(): ParameterAdapterSet {return this.#parametric}
|
||||
get codeChanged(): Observable<void> {return this.#codeChanged}
|
||||
|
||||
deviceHost(): DeviceHost {
|
||||
return this.#context.boxAdapters
|
||||
|
||||
Reference in New Issue
Block a user