Improving stability of asynchronous LaTeX renderer.

This commit is contained in:
Adsooi 2024-10-15 03:52:06 +02:00
parent cf73b35a9a
commit 5313428250
Signed by: Ad5001
GPG key ID: EF45F9C6AFE20160
3 changed files with 18 additions and 7 deletions

View file

@ -30,16 +30,18 @@ class CanvasAPI extends Module {
#canvas = null
/** @type {CanvasRenderingContext2D} */
#ctx = null
/** Lock to prevent asynchronous stuff from printing stuff that is outdated. */
#redrawCount = 0
/** @type {{show(string, string, string)}} */
#drawingErrorDialog = null
constructor() {
super("Canvas", {
canvas: CanvasInterface,
drawingErrorDialog: DialogInterface
})
/**
*
* @type {Object.<string, {expression: Expression, value: number, maxDraw: number}>}
@ -207,6 +209,7 @@ class CanvasAPI extends Module {
*/
redraw() {
if(!this.initialized) throw new Error("Attempting redraw before initialize!")
this.#redrawCount = (this.#redrawCount + 1) % 10000
this.#ctx = this.#canvas.getContext("2d")
this._computeAxes()
this._reset()
@ -519,15 +522,18 @@ class CanvasAPI extends Module {
* @param {function(LatexRenderResult|{width: number, height: number, source: string})} callback
*/
renderLatexImage(ltxText, color, callback) {
const currentRedrawCount = this.#redrawCount
const onRendered = (imgData) => {
if(!this.#canvas.isImageLoaded(imgData.source) && !this.#canvas.isImageLoading(imgData.source)) {
// Wait until the image is loaded to callback.
this.#canvas.loadImageAsync(imgData.source).then(() => {
callback(imgData)
if(this.#redrawCount === currentRedrawCount)
callback(imgData)
})
} else {
// Callback directly
callback(imgData)
if(this.#redrawCount === currentRedrawCount)
callback(imgData)
}
}
const prerendered = Latex.findPrerendered(ltxText, this.textsize, color)

View file

@ -47,7 +47,7 @@ class EnableLatex extends BoolSetting {
}
const ENABLE_LATEX_ASYNC = new BoolSetting(
qsTranslate("general", "Enable asynchronous LaTeX renderer (experimental)"),
qsTranslate("general", "Enable asynchronous LaTeX renderer"),
"enable_latex_async",
"new"
)

View file

@ -53,7 +53,12 @@ class PyPromiseRunner(QRunnable):
raise InvalidReturnValue("Must return either a primitive, a valid QObject, JS Value, or None.")
self.promise.finished.emit(data)
except Exception as e:
self.promise.errored.emit(repr(e))
try:
self.promise.errored.emit(repr(e))
except RuntimeError as e2:
# Happens when the PyPromise has already been garbage collected.
# In other words, nothing to report to nowhere.
pass
class PyPromise(QObject):