Skip to content

Commit

Permalink
highlighting
Browse files Browse the repository at this point in the history
  • Loading branch information
felixroos committed Dec 30, 2024
1 parent da89e5c commit 55a3ef9
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 33 deletions.
17 changes: 9 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@
"@codemirror/view": "^6.9.3",
"@flok-editor/cm-eval": "^1.0.1",
"@flok-editor/session": "^1.1.0",
"codemirror": "^6.0.1",
"y-codemirror.next": "^0.3.2",
"y-indexeddb": "^9.0.9",
"y-protocols": "^1.0.5",
"y-webrtc": "^10.2.5",
"y-websocket": "^1.5.0",
"yjs": "^13.5.51",
"@strudel/codemirror": "^1.1.0",
"@strudel/core": "^1.1.0",
"@strudel/draw": "^1.1.0",
"@strudel/mini": "^1.1.0",
"@strudel/soundfonts": "^1.1.0",
"@strudel/tonal": "^1.1.0",
"@strudel/transpiler": "^1.1.0",
"@strudel/webaudio": "^1.1.0"
"@strudel/webaudio": "^1.1.0",
"codemirror": "^6.0.1",
"y-codemirror.next": "^0.3.2",
"y-indexeddb": "^9.0.9",
"y-protocols": "^1.0.5",
"y-webrtc": "^10.2.5",
"y-websocket": "^1.5.0",
"yjs": "^13.5.51"
}
}
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { yCollab } from "y-codemirror.next";
import { Session } from "@flok-editor/session";
import { flashField, evalKeymap, remoteEvalFlash } from "@flok-editor/cm-eval";
import { UndoManager } from "yjs";
import { StrudelSession } from "./strudel";
import { highlightExtension } from "@strudel/codemirror";
import { StrudelSession, editorViews } from "./strudel";

import "./style.css";

Expand All @@ -23,6 +24,7 @@ const flokBasicSetup = (doc) => {

return [
flashField(),
highlightExtension,
remoteEvalFlash(doc),
Prec.high(evalKeymap(doc, { web, defaultMode: "document" })),
yCollab(text, doc.session.awareness, { undoManager }),
Expand Down Expand Up @@ -53,6 +55,7 @@ const createEditor = (doc) => {
state,
parent: editorEl,
});
editorViews.set(doc.id, view);

const targetEl = document.querySelector(`#${doc.id} .target`);
targetEl.value = doc.target;
Expand Down
88 changes: 64 additions & 24 deletions src/strudel.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
evaluate,
silence,
} from "@strudel/core";
// import { Framer } from "@strudel/draw";
import { Framer } from "@strudel/draw";
import { registerSoundfonts } from "@strudel/soundfonts";
import { transpiler } from "@strudel/transpiler";
import {
Expand All @@ -16,12 +16,17 @@ import {
samples,
webaudioOutput,
} from "@strudel/webaudio";
import {
highlightMiniLocations,
updateMiniLocations,
} from "@strudel/codemirror";

export const editorViews = new Map();
controls.createParam("docId");

export class StrudelSession {
constructor({ onError }) {
this.init().then(() => {
console.log("strudel init done", this.repl);
});
this.init();
this.patterns = {};
this.pPatterns = {};
this.allTransform = undefined;
Expand Down Expand Up @@ -62,20 +67,51 @@ export class StrudelSession {

this.repl = repl({
defaultOutput: webaudioOutput,
afterEval: (options) => {
// assumes docId is injected at end end as a comment
/* const docId = options.code.split("//").slice(-1)[0];
if (!docId) return;
const miniLocations = options.meta?.miniLocations;
updateDocumentsContext(docId, { miniLocations }); */
},
beforeEval: () => {},
onSchedulerError: (e) => this.onError(`${e}`),
onEvalError: (e) => this.onError(`${e}`),
getTime: () => getAudioContext().currentTime,
transpiler,
});
this.injectPatternMethods();

this.initHighlighting();
}

initHighlighting() {
let lastFrame /* : number | null */ = null;
this.framer = new Framer(
() => {
const phase = this.repl.scheduler.now();
if (lastFrame === null) {
lastFrame = phase;
return;
}
if (!this.repl.scheduler.pattern) {
return;
}
// queries the stack of strudel patterns for the current time
const allHaps = this.repl.scheduler.pattern.queryArc(
Math.max(lastFrame, phase - 1 / 10), // make sure query is not larger than 1/10 s
phase
);
// filter out haps that are not active right now
const currentFrame = allHaps.filter(
(hap) => phase >= hap.whole.begin && phase <= hap.endClipped
);
// iterate over each strudel doc
Object.keys(this.patterns).forEach((docId) => {
// filter out haps belonging to this document (docId is set in eval)
const haps = currentFrame.filter((h) => h.value.docId === docId);
// update codemirror view to highlight this frame's haps
const view = editorViews.get(docId);
console.log(docId, haps);
highlightMiniLocations(view, phase || 0, haps || []);
});
},
(err) => {
console.error("[strudel] draw error", err);
}
);
this.framer.start(); // tbd allow disabling highlighting
}

hush() {
Expand All @@ -93,7 +129,6 @@ export class StrudelSession {
// allows muting a pattern x with x_ or _x
return silence;
}
console.log("p", id);
if (id === "$") {
// allows adding anonymous patterns with $:
id = `$${self.anonymousIndex}`;
Expand Down Expand Up @@ -134,14 +169,16 @@ export class StrudelSession {
!conversational && this.hush();
const { body: code, docId } = msg;
// little hack that injects the docId at the end of the code to make it available in afterEval
/* const { pattern } = */ await evaluate(
//`${code}//${docId}`,
let { pattern, meta } = await evaluate(
code,
transpiler
// { id: '?' }
);
let pattern = silence;

const view = editorViews.get(docId);
updateMiniLocations(view, meta?.miniLocations || []);

// let pattern = silence;
if (Object.keys(this.pPatterns).length) {
let patterns = Object.values(this.pPatterns);
pattern = stack(...patterns);
Expand All @@ -150,14 +187,17 @@ export class StrudelSession {
pattern = this.allTransform(pattern);
}

console.log("eval done", this.pPatterns);
if (pattern) {
//this.patterns[docId] = pattern.docId(docId); // docId is needed for highlighting
this.patterns[docId] = pattern; // docId is needed for highlighting
console.log("this.patterns", this.patterns);
const allPatterns = stack(...Object.values(this.patterns));
await this.repl.scheduler.setPattern(allPatterns, true);
if (!pattern) {
return;
}
console.log("evaluated patterns", this.pPatterns);
this.patterns[docId] = pattern.docId(docId); // docId is needed for highlighting
console.log("this.patterns", this.patterns);
const allPatterns = stack(...Object.values(this.patterns));

await this.repl.scheduler.setPattern(allPatterns, true);

console.log("afterEval", meta);
} catch (err) {
console.error(err);
this.onError(`${err}`);
Expand Down
4 changes: 4 additions & 0 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ body {
.slot .title {
font-weight: 600;
}

:root {
--foreground: #eeeeee80;
}

0 comments on commit 55a3ef9

Please sign in to comment.