From 5e60504de56d7a523e7d647b59e758755121867d Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Sun, 21 Apr 2024 17:52:07 +0200 Subject: [PATCH] strip much of complexity from evaluator --- src/API/API.ts | 9 ++-- src/API/Time/Filters.ts | 8 +++ src/DOM/WindowBehavior.ts | 8 +-- src/Evaluator.ts | 106 +++++--------------------------------- 4 files changed, 29 insertions(+), 102 deletions(-) diff --git a/src/API/API.ts b/src/API/API.ts index 4cd761b..a351f7d 100644 --- a/src/API/API.ts +++ b/src/API/API.ts @@ -24,7 +24,6 @@ import { InputOptions } from "../Classes/ZPlayer"; import { type ShapeObject } from "../API/DOM/Canvas"; import { nearScales } from "zifferjs"; import { MidiConnection } from "../IO/MidiConnection"; -import { evaluateOnce } from "../Evaluator"; import { DrunkWalk } from "../Utils/Drunk"; import { Editor } from "../main"; import { LRUCache } from "lru-cache"; @@ -42,6 +41,7 @@ import { } from "superdough"; import { getScaleNotes } from "zifferjs"; import drums from "../tidal-drum-machines.json"; +import { updatePlayPauseIcon } from '../DOM/UILogic'; export async function loadSamples() { return Promise.all([ @@ -395,7 +395,7 @@ export class UserAPI { this.almostAlways = Probability.almostAlways(this); this.always = Probability.always(); this.dice = Probability.dice(this); - this.osc = OSC.osc(); + this.osc = OSC.osc(this.app); this.getOSC = OSC.getOSC(); this.gif = Canvas.gif(this.app); this.scope = Canvas.scope(this.app); @@ -479,9 +479,8 @@ export class UserAPI { this.patternCache.clear(); if (this.app.isPlaying) { } else { - this.app.setButtonHighlighting("play", true); - this.app.isPlaying = !this.app.isPlaying; - this.app.clock.start(); + this.app.clock.resume(); + updatePlayPauseIcon(this.app, "play"); this.app.api.MidiConnection.sendStartMessage(); } diff --git a/src/API/Time/Filters.ts b/src/API/Time/Filters.ts index 2b4ab16..452b41c 100644 --- a/src/API/Time/Filters.ts +++ b/src/API/Time/Filters.ts @@ -59,6 +59,14 @@ export const beat = (app: Editor) => (n: number | number[] = 1, nudge: number = return results.some((value) => value === true); }; +// export const beat = (app: Editor) => (n: number | number[] = 1, nudge: number = 0): boolean => { +// const nArray = !Array.isArray(n) ? [n] : n; +// return nArray.some( +// (value) => +// !((app.clock.time_position.grain - nudge * app.clock.time_position.ppqn) % Math.floor(value * app.clock.time_position.ppqn)) +// ); +// }; + export const bar = (app: Editor) => (n: number | number[] = 1, nudge: number = 0): boolean => { const nArray = Array.isArray(n) ? n : [n]; const barLength = app.clock.time_position.num * app.clock.ppqn; diff --git a/src/DOM/WindowBehavior.ts b/src/DOM/WindowBehavior.ts index 3d54a0a..643e810 100644 --- a/src/DOM/WindowBehavior.ts +++ b/src/DOM/WindowBehavior.ts @@ -44,10 +44,10 @@ export const installWindowBehaviors = ( window.addEventListener("resize", () => handleResize(app.interface.scope as HTMLCanvasElement), ); - window.addEventListener("beforeunload", (event) => { - event.preventDefault(); - saveBeforeExit(app); - }); + // window.addEventListener("beforeunload", (event) => { + // event.preventDefault(); + // saveBeforeExit(app); + // }); window.addEventListener("visibilitychange", (event) => { event.preventDefault(); saveState(app); diff --git a/src/Evaluator.ts b/src/Evaluator.ts index 988b656..8b0a561 100644 --- a/src/Evaluator.ts +++ b/src/Evaluator.ts @@ -1,112 +1,32 @@ import type { Editor } from "./main"; import type { File } from "./Editor/FileManagement"; -const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); -const codeReplace = (code: string): string => code.replace(/->|::/g, "&&"); -const cache = new Map(); -const MAX_CACHE_SIZE = 40; - async function tryCatchWrapper(application: Editor, code: string): Promise { - /** - * Wraps the provided code in a try-catch block and executes it. - * - * @param application - The editor application. - * @param code - The code to be executed. - * @returns A promise that resolves to a boolean indicating whether the code executed successfully or not. - */ try { - await new Function(`"use strict"; ${codeReplace(code)}`).call(application.api); + await new Function(`"use strict"; ${code}`).call(application.api); return true; } catch (error) { - application.interface["error_line"].innerHTML = error as string; - application.api._reportError(error as string); + console.error(error); return false; } } -const addFunctionToCache = (code: string, fn: Function) => { - /** - * Adds a function to the cache. - * @param code - The code associated with the function. - * @param fn - The function to be added to the cache. - */ - if (cache.size >= MAX_CACHE_SIZE) { - cache.delete(cache.keys().next().value); - } - cache.set(code, fn); -}; - - -export async function tryEvaluate(application: Editor, code: File, timeout = 5000): Promise { - /** - * Tries to evaluate the provided code within a specified timeout period. - * Increments the evaluation count of the code file. - * If the code is valid, updates the committed code and adds the evaluated function to the cache. - * If the code is invalid, retries the evaluation. - * @param application - The editor application. - * @param code - The code file to evaluate. - * @param timeout - The timeout period in milliseconds (default: 5000). - * @returns A Promise that resolves when the evaluation is complete. - */ - code.evaluations!++; - - const cachedFunction = cache.get(code.candidate); - if (cachedFunction) { - cachedFunction.call(application.api); - return; - } - +export async function tryEvaluate(application: Editor, code: File): Promise { const wrappedCode = `let i = ${code.evaluations}; ${code.candidate}`; - const isCodeValid = await Promise.race([ - tryCatchWrapper(application, wrappedCode), - delay(timeout) - ]); - + const isCodeValid = await tryCatchWrapper(application, wrappedCode); if (isCodeValid) { code.committed = code.candidate; - const newFunction = new Function(`"use strict"; ${codeReplace(wrappedCode)}`); - addFunctionToCache(code.candidate, newFunction); } else { - application.api.logOnce("Compilation error!"); - await delay(100); - await tryEvaluate(application, code, timeout); + console.error("Compilation error!"); } } -export async function evaluate(application: Editor, code: File, timeout = 1000): Promise { - /** - * Evaluates the given code using the provided application and timeout. - * @param application The editor application. - * @param code The code file to evaluate. - * @param timeout The timeout value in milliseconds (default: 1000). - * @returns A Promise that resolves when the evaluation is complete. - */ - try { - await Promise.race([ - tryCatchWrapper(application, code.committed as string), - delay(timeout) - ]); - code.evaluations!++; - } catch (error) { - application.interface["error_line"].innerHTML = error as string; - console.error(error); +export async function evaluateOnce(application: Editor, code: File): Promise { + const wrappedCode = `let i = ${code.evaluations}; ${code.candidate}`; + const isCodeValid = await tryCatchWrapper(application, wrappedCode); + if (isCodeValid) { + code.committed = code.candidate; + } else { + console.error("Compilation error!"); } -} - -export const evaluateOnce = async ( - application: Editor, - code: string, -): Promise => { - /** - * Evaluates the code once without any caching or error-handling mechanisms besides the tryCatchWrapper. - * - * @param application - The application object that contains the Editor API. - * @param code - The code to be evaluated. - * @returns A promise that resolves when the code has been evaluated. - */ - await tryCatchWrapper(application, code); -}; - - - - +} \ No newline at end of file