Improving reliability of threaded rendering, separating JS Utils into separate files.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Adsooi 2024-10-28 18:45:34 +01:00
parent 49e94317d4
commit 687b14429a
Signed by: Ad5001
GPG key ID: EF45F9C6AFE20160
18 changed files with 285 additions and 197 deletions

View file

@ -19,7 +19,7 @@
import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
import * as MathLib from "../math/index.mjs"
import { escapeHTML } from "../utils.mjs"
import { escapeHTML } from "../utils/index.mjs"
import { Action } from "./common.mjs"
/**

View file

@ -18,10 +18,11 @@
import js from "./lib/polyfills/js.mjs"
import * as Modules from "./module/index.mjs"
export * as Utils from "./utils/index.mjs"
import * as ObjsAutoload from "./objs/autoload.mjs"
export * as Modules from "./module/index.mjs"
export * as MathLib from "./math/index.mjs"
export * as HistoryLib from "./history/index.mjs"
export * as Parsing from "./parsing/index.mjs"
export * as Utils from "./utils.mjs"

View file

@ -17,11 +17,11 @@
*/
import * as Utils from "../utils.mjs"
import * as Utils from "../utils/index.mjs"
import { ExprEvalExpression } from "../lib/expr-eval/expression.mjs"
import Latex from "../module/latex.mjs"
import ExprParser from "../module/expreval.mjs"
import Objects from "../module/objects.mjs"
import { ExprEvalExpression } from "../lib/expr-eval/expression.mjs"
const NUMBER_MATCHER = /^\d*\.\d+(e[+-]\d+)?$/

View file

@ -17,7 +17,7 @@
*/
import * as Expr from "./expression.mjs"
import * as Utils from "../utils.mjs"
import * as Utils from "../utils/index.mjs"
import Latex from "../module/latex.mjs"
import Objects from "../module/objects.mjs"
import ExprParser from "../module/expreval.mjs"

View file

@ -18,7 +18,7 @@
import { Module } from "./common.mjs"
import { CanvasInterface, DialogInterface } from "./interface.mjs"
import { textsup } from "../utils.mjs"
import { textsup } from "../utils/index.mjs"
import { Expression } from "../math/index.mjs"
import Latex from "./latex.mjs"
import Objects from "./objects.mjs"

View file

@ -97,6 +97,7 @@ class LatexAPI extends Module {
* true if latex has been enabled by the user, false otherwise.
*/
this.enabled = false
this.promises = new Set()
}
/**
@ -139,9 +140,12 @@ class LatexAPI extends Module {
if(!this.initialized) throw new Error("Attempting requestAsyncRender before initialize!")
let render
if(this.#latex.supportsAsyncRender) {
console.trace()
this.emit(new AsyncRenderStartedEvent(markup, fontSize, color))
render = await this.#latex.renderAsync(markup, fontSize, color)
// Storing promise so that it does not get dereferenced.
const promise = this.#latex.renderAsync(markup, fontSize, color)
this.promises.add(promise)
render = await promise
this.promises.delete(promise)
this.emit(new AsyncRenderFinishedEvent(markup, fontSize, color))
} else {
render = this.#latex.renderSync(markup, fontSize, color)

View file

@ -17,7 +17,7 @@
*/
import { Module } from "./common.mjs"
import { textsub } from "../utils.mjs"
import { textsub } from "../utils/index.mjs"
class ObjectsAPI extends Module {

View file

@ -16,9 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { getRandomColor } from "../utils.mjs"
import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
import { getRandomColor } from "../utils/index.mjs"
import { ensureTypeSafety, serializesByPropertyType } from "../parameters.mjs"
// This file contains the default data to be imported from all other objects

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { textsub } from "../utils.mjs"
import { textsub } from "../utils/index.mjs"
import Objects from "../module/objects.mjs"
import { ExecutableObject } from "./common.mjs"
import { parseDomain, Expression, SpecialDomain } from "../math/index.mjs"

View file

@ -16,151 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Add string methods
/**
* Replaces latin characters with their uppercase versions.
* @return {string}
*/
String.prototype.toLatinUppercase = function() {
return this.replace(/[a-z]/g, function(match) {
return match.toUpperCase()
})
}
/**
* Removes the first and last character of a string
* Used to remove enclosing characters like quotes, parentheses, brackets...
* @note Does NOT check for their existence ahead of time.
* @return {string}
*/
String.prototype.removeEnclosure = function() {
return this.substring(1, this.length - 1)
}
/**
* Rounds to a certain number of decimal places.
* From https://stackoverflow.com/a/48764436
*
* @param {number} decimalPlaces
* @return {number}
*/
Number.prototype.toDecimalPrecision = function(decimalPlaces = 0) {
const p = Math.pow(10, decimalPlaces)
const n = (this * p) * (1 + Number.EPSILON)
return Math.round(n) / p
}
const CHARACTER_TO_POWER = new Map([
["-", "⁻"],
["+", "⁺"],
["=", "⁼"],
[" ", ""],
["(", "⁽"],
[")", "⁾"],
["0", "⁰"],
["1", "¹"],
["2", "²"],
["3", "³"],
["4", "⁴"],
["5", "⁵"],
["6", "⁶"],
["7", "⁷"],
["8", "⁸"],
["9", "⁹"],
["a", "ᵃ"],
["b", "ᵇ"],
["c", "ᶜ"],
["d", "ᵈ"],
["e", "ᵉ"],
["f", "ᶠ"],
["g", "ᵍ"],
["h", "ʰ"],
["i", "ⁱ"],
["j", "ʲ"],
["k", "ᵏ"],
["l", "ˡ"],
["m", "ᵐ"],
["n", "ⁿ"],
["o", "ᵒ"],
["p", "ᵖ"],
["r", "ʳ"],
["s", "ˢ"],
["t", "ᵗ"],
["u", "ᵘ"],
["v", "ᵛ"],
["w", "ʷ"],
["x", "ˣ"],
["y", "ʸ"],
["z", "ᶻ"]
])
const CHARACTER_TO_INDICE = new Map([
["-", "₋"],
["+", "₊"],
["=", "₌"],
["(", "₍"],
[")", "₎"],
[" ", ""],
["0", "₀"],
["1", "₁"],
["2", "₂"],
["3", "₃"],
["4", "₄"],
["5", "₅"],
["6", "₆"],
["7", "₇"],
["8", "₈"],
["9", "₉"],
["a", "ₐ"],
["e", "ₑ"],
["h", "ₕ"],
["i", "ᵢ"],
["j", "ⱼ"],
["k", "ₖ"],
["l", "ₗ"],
["m", "ₘ"],
["n", "ₙ"],
["o", "ₒ"],
["p", "ₚ"],
["r", "ᵣ"],
["s", "ₛ"],
["t", "ₜ"],
["u", "ᵤ"],
["v", "ᵥ"],
["x", "ₓ"]
])
const EXPONENTS = [
"⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"
]
const EXPONENTS_REG = new RegExp("([" + EXPONENTS.join("") + "]+)", "g")
/**
* Put a text in sup position
* @param {string} text
* @return {string}
*/
export function textsup(text) {
let ret = ""
text = text.toString()
for(let letter of text)
ret += CHARACTER_TO_POWER.has(letter) ? CHARACTER_TO_POWER.get(letter) : letter
return ret
}
/**
* Put a text in sub position
* @param {string} text
* @return {string}
*/
export function textsub(text) {
let ret = ""
text = text.toString()
for(let letter of text)
ret += CHARACTER_TO_INDICE.has(letter) ? CHARACTER_TO_INDICE.get(letter) : letter
return ret
}
import { textsub, textsup } from "./subsup.mjs"
/**
* Simplifies (mathematically) a mathematical expression.
@ -400,35 +256,3 @@ export function parseName(str, removeUnallowed = true) {
return str
}
/**
* Creates a randomized color string.
* @returns {string}
*/
export function getRandomColor() {
let clrs = "0123456789ABCDEF"
let color = "#"
for(let i = 0; i < 6; i++) {
color += clrs[Math.floor(Math.random() * (16 - 5 * (i % 2 === 0)))]
}
return color
}
/**
* Escapes text to html entities.
* @param {string} str
* @returns {string}
*/
export function escapeHTML(str) {
return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
}
/**
* Parses exponents and replaces them with expression values
* @param {string} expression - The expression to replace in.
* @return {string} The parsed expression
*/
export function exponentsToExpression(expression) {
return expression.replace(EXPONENTS_REG, (m, exp) => "^" + exp.split("").map((x) => EXPONENTS.indexOf(x)).join(""))
}

View file

@ -0,0 +1,22 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export * from "./prototype.mjs"
export * from "./subsup.mjs"
export * from "./expression.mjs"
export * from "./other.mjs"

View file

@ -0,0 +1,41 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Creates a randomized color string.
* @returns {string}
*/
export function getRandomColor() {
let clrs = "0123456789ABCDEF"
let color = "#"
for(let i = 0; i < 6; i++) {
color += clrs[Math.floor(Math.random() * (16 - 5 * (i % 2 === 0)))]
}
return color
}
/**
* Escapes text to html entities.
* @param {string} str
* @returns {string}
*/
export function escapeHTML(str) {
return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
}

View file

@ -0,0 +1,51 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Add string methods
/**
* Replaces latin characters with their uppercase versions.
* @return {string}
*/
String.prototype.toLatinUppercase = function() {
return this.replace(/[a-z]/g, function(match) {
return match.toUpperCase()
})
}
/**
* Removes the first and last character of a string
* Used to remove enclosing characters like quotes, parentheses, brackets...
* @note Does NOT check for their existence ahead of time.
* @return {string}
*/
String.prototype.removeEnclosure = function() {
return this.substring(1, this.length - 1)
}
/**
* Rounds to a certain number of decimal places.
* From https://stackoverflow.com/a/48764436
*
* @param {number} decimalPlaces
* @return {number}
*/
Number.prototype.toDecimalPrecision = function(decimalPlaces = 0) {
const p = Math.pow(10, decimalPlaces)
const n = (this * p) * (1 + Number.EPSILON)
return Math.round(n) / p
}

140
common/src/utils/subsup.mjs Normal file
View file

@ -0,0 +1,140 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const CHARACTER_TO_POWER = new Map([
["-", "⁻"],
["+", "⁺"],
["=", "⁼"],
[" ", ""],
["(", "⁽"],
[")", "⁾"],
["0", "⁰"],
["1", "¹"],
["2", "²"],
["3", "³"],
["4", "⁴"],
["5", "⁵"],
["6", "⁶"],
["7", "⁷"],
["8", "⁸"],
["9", "⁹"],
["a", "ᵃ"],
["b", "ᵇ"],
["c", "ᶜ"],
["d", "ᵈ"],
["e", "ᵉ"],
["f", "ᶠ"],
["g", "ᵍ"],
["h", "ʰ"],
["i", "ⁱ"],
["j", "ʲ"],
["k", "ᵏ"],
["l", "ˡ"],
["m", "ᵐ"],
["n", "ⁿ"],
["o", "ᵒ"],
["p", "ᵖ"],
["r", "ʳ"],
["s", "ˢ"],
["t", "ᵗ"],
["u", "ᵘ"],
["v", "ᵛ"],
["w", "ʷ"],
["x", "ˣ"],
["y", "ʸ"],
["z", "ᶻ"]
])
const CHARACTER_TO_INDICE = new Map([
["-", "₋"],
["+", "₊"],
["=", "₌"],
["(", "₍"],
[")", "₎"],
[" ", ""],
["0", "₀"],
["1", "₁"],
["2", "₂"],
["3", "₃"],
["4", "₄"],
["5", "₅"],
["6", "₆"],
["7", "₇"],
["8", "₈"],
["9", "₉"],
["a", "ₐ"],
["e", "ₑ"],
["h", "ₕ"],
["i", "ᵢ"],
["j", "ⱼ"],
["k", "ₖ"],
["l", "ₗ"],
["m", "ₘ"],
["n", "ₙ"],
["o", "ₒ"],
["p", "ₚ"],
["r", "ᵣ"],
["s", "ₛ"],
["t", "ₜ"],
["u", "ᵤ"],
["v", "ᵥ"],
["x", "ₓ"]
])
const EXPONENTS = [
"⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"
]
const EXPONENTS_REG = new RegExp("([" + EXPONENTS.join("") + "]+)", "g")
/**
* Put a text in sup position
* @param {string} text
* @return {string}
*/
export function textsup(text) {
let ret = ""
text = text.toString()
for(let letter of text)
ret += CHARACTER_TO_POWER.has(letter) ? CHARACTER_TO_POWER.get(letter) : letter
return ret
}
/**
* Put a text in sub position
* @param {string} text
* @return {string}
*/
export function textsub(text) {
let ret = ""
text = text.toString()
for(let letter of text)
ret += CHARACTER_TO_INDICE.has(letter) ? CHARACTER_TO_INDICE.get(letter) : letter
return ret
}
/**
* Parses exponents and replaces them with expression values
* @param {string} expression - The expression to replace in.
* @return {string} The parsed expression
*/
export function exponentsToExpression(expression) {
return expression.replace(EXPONENTS_REG, (m, exp) => "^" + exp.split("").map((x) => EXPONENTS.indexOf(x)).join(""))
}

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { textsup, textsub, parseName, getRandomColor, escapeHTML, exponentsToExpression } from "../../src/utils.mjs"
import { textsup, textsub, parseName, getRandomColor, escapeHTML, exponentsToExpression } from "../../src/utils/index.mjs"
import { describe, it } from "mocha"

View file

@ -178,4 +178,4 @@ describe("Math/Expression", function() {
expect(() => executeExpression("x+n")).to.throw("Undefined variable n.")
})
})
})
})