Improving stability of asynchronous LaTeX renderer.
This commit is contained in:
parent
cf73b35a9a
commit
5313428250
3 changed files with 18 additions and 7 deletions
|
@ -30,16 +30,18 @@ class CanvasAPI extends Module {
|
||||||
#canvas = null
|
#canvas = null
|
||||||
/** @type {CanvasRenderingContext2D} */
|
/** @type {CanvasRenderingContext2D} */
|
||||||
#ctx = null
|
#ctx = null
|
||||||
|
/** Lock to prevent asynchronous stuff from printing stuff that is outdated. */
|
||||||
|
#redrawCount = 0
|
||||||
/** @type {{show(string, string, string)}} */
|
/** @type {{show(string, string, string)}} */
|
||||||
#drawingErrorDialog = null
|
#drawingErrorDialog = null
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super("Canvas", {
|
super("Canvas", {
|
||||||
canvas: CanvasInterface,
|
canvas: CanvasInterface,
|
||||||
drawingErrorDialog: DialogInterface
|
drawingErrorDialog: DialogInterface
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {Object.<string, {expression: Expression, value: number, maxDraw: number}>}
|
* @type {Object.<string, {expression: Expression, value: number, maxDraw: number}>}
|
||||||
|
@ -207,6 +209,7 @@ class CanvasAPI extends Module {
|
||||||
*/
|
*/
|
||||||
redraw() {
|
redraw() {
|
||||||
if(!this.initialized) throw new Error("Attempting redraw before initialize!")
|
if(!this.initialized) throw new Error("Attempting redraw before initialize!")
|
||||||
|
this.#redrawCount = (this.#redrawCount + 1) % 10000
|
||||||
this.#ctx = this.#canvas.getContext("2d")
|
this.#ctx = this.#canvas.getContext("2d")
|
||||||
this._computeAxes()
|
this._computeAxes()
|
||||||
this._reset()
|
this._reset()
|
||||||
|
@ -519,15 +522,18 @@ class CanvasAPI extends Module {
|
||||||
* @param {function(LatexRenderResult|{width: number, height: number, source: string})} callback
|
* @param {function(LatexRenderResult|{width: number, height: number, source: string})} callback
|
||||||
*/
|
*/
|
||||||
renderLatexImage(ltxText, color, callback) {
|
renderLatexImage(ltxText, color, callback) {
|
||||||
|
const currentRedrawCount = this.#redrawCount
|
||||||
const onRendered = (imgData) => {
|
const onRendered = (imgData) => {
|
||||||
if(!this.#canvas.isImageLoaded(imgData.source) && !this.#canvas.isImageLoading(imgData.source)) {
|
if(!this.#canvas.isImageLoaded(imgData.source) && !this.#canvas.isImageLoading(imgData.source)) {
|
||||||
// Wait until the image is loaded to callback.
|
// Wait until the image is loaded to callback.
|
||||||
this.#canvas.loadImageAsync(imgData.source).then(() => {
|
this.#canvas.loadImageAsync(imgData.source).then(() => {
|
||||||
callback(imgData)
|
if(this.#redrawCount === currentRedrawCount)
|
||||||
|
callback(imgData)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Callback directly
|
// Callback directly
|
||||||
callback(imgData)
|
if(this.#redrawCount === currentRedrawCount)
|
||||||
|
callback(imgData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const prerendered = Latex.findPrerendered(ltxText, this.textsize, color)
|
const prerendered = Latex.findPrerendered(ltxText, this.textsize, color)
|
||||||
|
|
|
@ -47,7 +47,7 @@ class EnableLatex extends BoolSetting {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ENABLE_LATEX_ASYNC = new BoolSetting(
|
const ENABLE_LATEX_ASYNC = new BoolSetting(
|
||||||
qsTranslate("general", "Enable asynchronous LaTeX renderer (experimental)"),
|
qsTranslate("general", "Enable asynchronous LaTeX renderer"),
|
||||||
"enable_latex_async",
|
"enable_latex_async",
|
||||||
"new"
|
"new"
|
||||||
)
|
)
|
||||||
|
|
|
@ -53,7 +53,12 @@ class PyPromiseRunner(QRunnable):
|
||||||
raise InvalidReturnValue("Must return either a primitive, a valid QObject, JS Value, or None.")
|
raise InvalidReturnValue("Must return either a primitive, a valid QObject, JS Value, or None.")
|
||||||
self.promise.finished.emit(data)
|
self.promise.finished.emit(data)
|
||||||
except Exception as e:
|
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):
|
class PyPromise(QObject):
|
||||||
|
|
Loading…
Reference in a new issue