« get me outta code hell

WIP better rendering - tui-lib - Pure Node.js library for making visual command-line programs (ala vim, ncdu)
about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2019-09-16 11:19:30 -0300
committerFlorrie <towerofnix@gmail.com>2019-09-16 11:27:48 -0300
commit49eb24099f0a6088976972df5ecb7c927c78a110 (patch)
treea5b78dc77549f3ddd62c77507a23ccf88f655454
parenteb3b83fa2d56f3c85ac0d5c9b62223f6bd297940 (diff)
WIP better rendering
I think this'll take some serious attention before it even works and
saves any performance.
-rw-r--r--ui/DisplayElement.js45
-rw-r--r--ui/Root.js25
2 files changed, 56 insertions, 14 deletions
diff --git a/ui/DisplayElement.js b/ui/DisplayElement.js
index fab957e..8720142 100644
--- a/ui/DisplayElement.js
+++ b/ui/DisplayElement.js
@@ -44,10 +44,37 @@ module.exports = class DisplayElement extends Element {
     // Like drawTo, but only calls drawTo if the element is visible. Use this
     // with your root element, not drawTo.
 
-    if (this.visible) {
+    if (!this.visible) {
+      return
+    }
+
+    const causeRenderEl = this.shouldRender()
+    if (causeRenderEl) {
       this.drawTo(writable)
-      this.drawChildrenTo(writable)
+      this.renderChildrenTo(writable)
       this.didRenderTo(writable)
+    } else {
+      this.renderChildrenTo(writable)
+    }
+  }
+
+  shouldRender() {
+    // WIP! Until this implementation is finished, always return true (or else
+    // lots of rendering breaks).
+    /*
+    return (
+      this[DisplayElement.scheduledDraw] ||
+      [...this.directAncestors].find(el => el.shouldRender())
+    )
+    */
+    return true
+  }
+
+  renderChildrenTo(writable) {
+    // Renders all of the children to a writable.
+
+    for (const child of this.children) {
+      child.renderTo(writable)
     }
   }
 
@@ -75,19 +102,19 @@ module.exports = class DisplayElement extends Element {
     }
   }
 
-  drawChildrenTo(writable) {
-    // Draws all of the children to a writable.
-
-    for (const child of this.children) {
-      child.renderTo(writable)
+  confirmDrawValuesExists() {
+    if (!this[DisplayElement.drawValues]) {
+      this[DisplayElement.drawValues] = {}
     }
   }
 
   getDep(key) {
+    this.confirmDrawValuesExists()
     return this[DisplayElement.drawValues][key]
   }
 
   setDep(key, value) {
+    this.confirmDrawValuesExists()
     const oldValue = this[DisplayElement.drawValues][key]
     if (value !== this[DisplayElement.drawValues][key]) {
       this[DisplayElement.drawValues][key] = value
@@ -237,6 +264,10 @@ module.exports = class DisplayElement extends Element {
   get visible() { return this.getDep('visible') }
   set visible(v) { return this.setDep('visible', v) }
 
+  // Commented out because this doesn't fix any problems (at least ATM).
+  // get parent() { return this.getDep('parent') }
+  // set parent(v) { return this.setDep('parent', v) }
+
   get absX() {
     if (this.parent) {
       return this.parent.contentX + this.x
diff --git a/ui/Root.js b/ui/Root.js
index fd81fed..2b13203 100644
--- a/ui/Root.js
+++ b/ui/Root.js
@@ -92,7 +92,7 @@ module.exports = class Root extends DisplayElement {
   }
 
   renderTo(writable) {
-    if (this.shouldRenderTo(writable)) {
+    if (this.anyDescendantShouldRender()) {
       this.renderNowTo(writable)
     }
   }
@@ -101,27 +101,38 @@ module.exports = class Root extends DisplayElement {
     if (writable) {
       this.renderCount++
       super.renderTo(writable)
+      // Since shouldRender is false, super.renderTo won't call didRenderTo for
+      // us. We need to do that ourselves.
+      this.didRenderTo(writable)
     }
   }
 
-  shouldRenderTo(writable) {
+  anyDescendantShouldRender() {
     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()
+        return
       }
-      el.updateLastDrawValues()
+      render = el.hasScheduledDraw()
     })
     return render
   }
 
+  shouldRender() {
+    // We need to return false here because otherwise all children will render,
+    // since they'll see the root as an ancestor who needs to be rendered. Bad!
+    return false
+  }
+
   didRenderTo(writable) {
+    this.eachDescendant(el => {
+      el.unscheduleDraw()
+      el.updateLastDrawValues()
+    })
+
     /*
     writable.write(ansi.moveCursorRaw(1, 1))
     writable.write('Renders: ' + this.renderCount)