diff options
author | Florrie <towerofnix@gmail.com> | 2019-09-15 16:55:53 -0300 |
---|---|---|
committer | Florrie <towerofnix@gmail.com> | 2019-09-15 17:09:31 -0300 |
commit | 3f76094c554c23ee3519f41458a04d348f4f75a3 (patch) | |
tree | 5b87c588651b52aec6136e651e73d9f1d747c638 /ui/Root.js | |
parent | 878e55e7c2a203d89fb1dad83ba6d6d8751b521a (diff) |
(!!) Only render when draw-dependency props change
This is a very large change and probably breaks most applications not built to work with it. (Obviously, I'm not really being that responsible with this sort of thing.) I've tested with mtui and it works fine, but some elements may need tweaks before being 100% adjusted to the new scheduled-render system we're using with this commit. Also, any elements which have custom draw behavior will likely need updating so that they appropriately schedule renders.
Diffstat (limited to 'ui/Root.js')
-rw-r--r-- | ui/Root.js | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/ui/Root.js b/ui/Root.js index 8242f7a..fd81fed 100644 --- a/ui/Root.js +++ b/ui/Root.js @@ -9,10 +9,11 @@ module.exports = class Root extends DisplayElement { // An element to be used as the root of a UI. Handles lots of UI and // socket stuff. - constructor(interfacer) { + constructor(interfacer, writable = null) { super() this.interfacer = interfacer + this.writable = writable || interfacer this.selectedElement = null @@ -21,10 +22,8 @@ module.exports = class Root extends DisplayElement { this.oldSelectionStates = [] interfacer.on('inputData', buf => this.handleData(buf)) - } - render() { - this.renderTo(this.interfacer) + this.renderCount = 0 } handleData(buffer) { @@ -74,7 +73,60 @@ module.exports = class Root extends DisplayElement { writable.write(' '.repeat(this.w * this.h)) } + scheduleRender() { + if (!this.scheduledRender) { + setTimeout(() => { + this.scheduledRender = false + this.render() + }) + this.scheduledRender = true + } + } + + render() { + this.renderTo(this.writable) + } + + renderNow() { + this.renderNowTo(this.writable) + } + + renderTo(writable) { + if (this.shouldRenderTo(writable)) { + this.renderNowTo(writable) + } + } + + renderNowTo(writable) { + if (writable) { + this.renderCount++ + super.renderTo(writable) + } + } + + shouldRenderTo(writable) { + let render = false + this.eachDescendant(el => { + // If we already know we're going to render, checking the element's + // scheduled-draw status (which involves iterating over each of its draw + // dependency properties) is redundant. + if (render) { + el.unscheduleDraw() + } else if (el.hasScheduledDraw()) { + render = true + el.unscheduleDraw() + } + el.updateLastDrawValues() + }) + return render + } + didRenderTo(writable) { + /* + writable.write(ansi.moveCursorRaw(1, 1)) + writable.write('Renders: ' + this.renderCount) + */ + // Render the cursor, based on the cursorX and cursorY of the currently // selected element. if (this.selectedElement && this.selectedElement.cursorVisible) { @@ -94,6 +146,8 @@ module.exports = class Root extends DisplayElement { } else { writable.write(ansi.hideCursor()) } + + this.emit('rendered') } cursorMoved() { @@ -209,4 +263,7 @@ module.exports = class Root extends DisplayElement { if (this.selectedElement.directAncestors.includes(el)) return true return false } + + get selectedElement() { return this.getDep('selectedElement') } + set selectedElement(v) { return this.setDep('selectedElement', v) } } |