improve scope memory footprint

This commit is contained in:
Felix Roos 2024-03-17 01:58:30 +01:00
parent cdc200e1da
commit 16506c5ae2
3 changed files with 26 additions and 18 deletions

View File

@ -1,10 +1,8 @@
import { StateEffect, StateField } from '@codemirror/state'; import { StateEffect, StateField } from '@codemirror/state';
import { Decoration, EditorView, WidgetType } from '@codemirror/view'; import { Decoration, EditorView, WidgetType } from '@codemirror/view';
import { registerWidgetType } from '@strudel/transpiler'; import { getWidgetID, registerWidgetType } from '@strudel/transpiler';
import { Pattern } from '@strudel/core'; import { Pattern } from '@strudel/core';
const getWidgetID = (from) => `widget_${from}`;
export const addWidget = StateEffect.define({ export const addWidget = StateEffect.define({
map: ({ from, to }, change) => { map: ({ from, to }, change) => {
return { from: change.mapPos(from), to: change.mapPos(to) }; return { from: change.mapPos(from), to: change.mapPos(to) };
@ -20,12 +18,12 @@ function getWidgets(widgetConfigs) {
widgetConfigs widgetConfigs
// codemirror throws an error if we don't sort // codemirror throws an error if we don't sort
.sort((a, b) => a.to - b.to) .sort((a, b) => a.to - b.to)
.map(({ to, type }) => { .map((widgetConfig) => {
return Decoration.widget({ return Decoration.widget({
widget: new BlockWidget(to, type), widget: new BlockWidget(widgetConfig),
side: 0, side: 0,
block: true, block: true,
}).range(to); }).range(widgetConfig.to);
}) })
); );
} }
@ -62,16 +60,15 @@ export function setWidget(id, el) {
} }
export class BlockWidget extends WidgetType { export class BlockWidget extends WidgetType {
constructor(col, type) { constructor(widgetConfig) {
super(); super();
this.col = col; this.widgetConfig = widgetConfig;
this.type = type;
} }
eq() { eq() {
return true; return true;
} }
toDOM() { toDOM() {
const id = getWidgetID(this.col); // matches id generated in transpiler const id = getWidgetID(this.widgetConfig);
const el = widgetElements[id]; const el = widgetElements[id];
return el; return el;
} }

View File

@ -220,6 +220,7 @@ export let analysers = {},
export function getAnalyserById(id, fftSize = 1024) { export function getAnalyserById(id, fftSize = 1024) {
if (!analysers[id]) { if (!analysers[id]) {
// make sure this doesn't happen too often as it piles up garbage
const analyserNode = getAudioContext().createAnalyser(); const analyserNode = getAudioContext().createAnalyser();
analyserNode.fftSize = fftSize; analyserNode.fftSize = fftSize;
// getDestination().connect(analyserNode); // getDestination().connect(analyserNode);

View File

@ -53,12 +53,13 @@ export function transpiler(input, options = {}) {
return this.replace(sliderWithLocation(node)); return this.replace(sliderWithLocation(node));
} }
if (isWidgetMethod(node)) { if (isWidgetMethod(node)) {
emitWidgets && const widgetConfig = {
widgets.push({ to: node.end,
to: node.end, index: widgets.length,
type: node.callee.property.name, type: node.callee.property.name,
}); };
return this.replace(widgetWithLocation(node)); emitWidgets && widgets.push(widgetConfig);
return this.replace(widgetWithLocation(node, widgetConfig));
} }
if (isBareSamplesCall(node, parent)) { if (isBareSamplesCall(node, parent)) {
return this.replace(withAwait(node)); return this.replace(withAwait(node));
@ -140,8 +141,17 @@ function sliderWithLocation(node) {
return node; return node;
} }
function widgetWithLocation(node) { export function getWidgetID(widgetConfig) {
const id = 'widget_' + node.end; // the widget id is used as id for the dom element + as key for eventual resources
// for example, for each scope widget, a new analyser + buffer (large) is created
// that means, if we use the index index of line position as id, less garbage is generated
// return `widget_${widgetConfig.to}`; // more gargabe
//return `widget_${widgetConfig.index}_${widgetConfig.to}`; // also more garbage
return `widget_${widgetConfig.index}`; // less garbage
}
function widgetWithLocation(node, widgetConfig) {
const id = getWidgetID(widgetConfig);
// add loc as identifier to first argument // add loc as identifier to first argument
// the sliderWithID function is assumed to be sliderWithID(id, value, min?, max?) // the sliderWithID function is assumed to be sliderWithID(id, value, min?, max?)
node.arguments.unshift({ node.arguments.unshift({