From 8053f12b63e272cc9119a30f9ddc480b5ea75641 Mon Sep 17 00:00:00 2001 From: Florrie Date: Sun, 15 Sep 2019 17:17:31 -0300 Subject: Only render when stuff on-screen actually changes! This means we can basically guarantee 0% CPU usage when nothing on the screen is changing! There may still be some kinks to work out, but I've tested most features and fixed any apparent bugs (including an unrelated bug in the suspend feature which made it crash when resuming the process). --- ui.js | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'ui.js') diff --git a/ui.js b/ui.js index c6bb448..f425048 100644 --- a/ui.js +++ b/ui.js @@ -1471,12 +1471,13 @@ class GrouplikeListingForm extends ListScrollForm { } set curIndex(newIndex) { - this._curIndex = newIndex + this.setDep('curIndex', newIndex) this.emit('selected input', this.inputs[this.curIndex]) + return newIndex } get curIndex() { - return this._curIndex + return this.getDep('curIndex') } get firstItemIndex() { @@ -1889,6 +1890,14 @@ class InlineListPickerElement extends FocusElement { } } +// Quite hacky, but ATM I can't think of any way to neatly tie getDep/setDep +// into the slider and toggle elements. +const drawAfter = (fn, thisObj) => (...args) => { + const ret = fn(...args) + thisObj.scheduleDrawWithoutPropertyChange() + return ret +} + class SliderElement extends FocusElement { // Same general principle and usage as InlineListPickerElement, but for // changing a numeric value. @@ -1896,7 +1905,7 @@ class SliderElement extends FocusElement { constructor(labelText, {setValue, getValue, maxValue = 100, percent = true, getEnabled = () => true}) { super() this.labelText = labelText - this.setValue = setValue + this.setValue = drawAfter(setValue, this) this.getValue = getValue this.getEnabled = getEnabled this.maxValue = maxValue @@ -2036,7 +2045,7 @@ class ToggleControl extends FocusElement { constructor(labelText, {setValue, getValue, getEnabled = () => true}) { super() this.labelText = labelText - this.setValue = setValue + this.setValue = drawAfter(setValue, this) this.getValue = getValue this.getEnabled = getEnabled this.keyboardIdentifier = this.labelText @@ -2549,8 +2558,12 @@ class PlaybackInfoElement extends DisplayElement { } updateProgress(timeData, player) { - this.timeData = timeData const {timeDone, duration, lenSecTotal, curSecTotal} = timeData + this.timeData = timeData + this.curSecTotal = curSecTotal + this.lenSecTotal = lenSecTotal + this.volume = player.volume + this.isLooping = player.isLooping this.progressBarLabel.text = '-'.repeat(Math.floor(this.w / lenSecTotal * curSecTotal)) this.progressTextLabel.text = timeDone + ' / ' + duration @@ -2585,6 +2598,15 @@ class PlaybackInfoElement extends DisplayElement { this.timeData = {} this.fixLayout() } + + get curSecTotal() { return this.getDep('curSecTotal') } + set curSecTotal(v) { return this.setDep('curSecTotal', v) } + get lenSecTotal() { return this.getDep('lenSecTotal') } + set lenSecTotal(v) { return this.setDep('lenSecTotal', v) } + get volume() { return this.getDep('volume') } + set volume(v) { return this.setDep('volume', v) } + get isLooping() { return this.getDep('isLooping') } + set isLooping(v) { return this.setDep('isLooping', v) } } class OpenPlaylistDialog extends Dialog { @@ -3310,6 +3332,10 @@ class PartyBanner extends DisplayElement { drawTo(writable) { writable.write(ansi.moveCursor(this.absTop, this.absLeft)) + // TODO: Figure out how to connect this to the draw dependency system. + // Currently the party banner doesn't schedule any renders itself (meaning + // if you have nothing playing or otherwise rendering, it'll just stay + // still). const timerNum = Date.now() / 2000 * this.direction let lastAttribute = '' const updateAttribute = offsetNum => { -- cgit 1.3.0-6-gf8a5