From fb9e846220acef932bd23a3a2f8d4900e2cbbdc0 Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Thu, 25 Feb 2021 15:17:20 +0000 Subject: [PATCH] Sorting the drawind buffers to improve the performances --- TermTk/TTkCore/helper.py | 49 ++++++++++++++++++++++++++++++++-------- TermTk/TTkCore/ttk.py | 16 +++++++++++-- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/TermTk/TTkCore/helper.py b/TermTk/TTkCore/helper.py index f18d8664..cb1d8f12 100644 --- a/TermTk/TTkCore/helper.py +++ b/TermTk/TTkCore/helper.py @@ -52,29 +52,58 @@ class TTkHelper: @staticmethod def paintAll(): + ''' + _updateBuffer = list widgets that require a repaint [paintEvent] + _updateWidget = list widgets that need to be pushed below + ''' if TTkHelper._rootCanvas is None: return - #processed = [] - pushToTerminal = False - for widget in TTkHelper._updateBuffer: + # Build a list of buffers to be repainted + updateBuffers = [w for w in TTkHelper._updateBuffer] + updateWidgets = [w for w in TTkHelper._updateWidget] + + for widget in TTkHelper._updateWidget: + parent = widget.parentWidget() + while parent is not None: + if parent not in updateBuffers: + updateBuffers.append(parent) + if parent not in updateWidgets: + updateWidgets.append(parent) + parent = parent.parentWidget() + + TTkHelper._updateBuffer = [] + TTkHelper._updateWidget = [] + + # Paint all the canvas + for widget in updateBuffers: if not widget.isVisible(): continue # Resize the canvas just before the paintEvent # to avoid too many allocations widget.getCanvas().updateSize() + widget.getCanvas().clean() widget.paintEvent() - TTkHelper._updateBuffer = [] - for widget in TTkHelper._updateWidget: + + # Compose all the canvas to the parents + # From the deepest childs to the bottom + pushToTerminal = False + sortedUpdateWidget = [ (w, TTkHelper.widgetDepth(w)) for w in updateWidgets] + sortedUpdateWidget = sorted(sortedUpdateWidget, key=lambda w: -w[1]) + for w in sortedUpdateWidget: + widget = w[0] if not widget.isVisible(): continue pushToTerminal = True - #processed.append(widget) widget.paintChildCanvas() - #p = widget.parentWidget() - #if p in TTkHelper._updateWidget and p not in processed: - widget.paintNotifyParent() - TTkHelper._updateWidget = [] + if pushToTerminal: TTkHelper._rootCanvas.pushToTerminal(0, 0, TTkGlbl.term_w, TTkGlbl.term_h) + + @staticmethod + def widgetDepth(widget) -> int: + if widget is None: + return 0 + return 1 + TTkHelper.widgetDepth(widget.parentWidget()) + @staticmethod def absPos(widget) -> (int,int): ppos = TTkHelper.absParentPos(widget) diff --git a/TermTk/TTkCore/ttk.py b/TermTk/TTkCore/ttk.py index b07502de..4bba3f9a 100644 --- a/TermTk/TTkCore/ttk.py +++ b/TermTk/TTkCore/ttk.py @@ -68,6 +68,17 @@ class TTk(TTkWidget): self.setFocusPolicy(TTkWidget.ClickFocus) TTkHelper.registerRootCanvas(self._canvas) + frame = 0 + time = time.time() + def _fps(self): + curtime = time.time() + self.frame+=1 + delta = curtime - self.time + if delta > 3: + TTkLog.debug(f"fps: {int(self.frame/delta)}") + self.frame = 0 + self.time = curtime + def mainloop(self): TTkLog.debug("Starting Main Loop...") # Register events @@ -85,7 +96,7 @@ class TTk(TTkWidget): threading.Thread(target=self._input_thread, daemon=True).start() self._timerEvent = threading.Event() self._timerEvent.set() - self._timer = TTkTimer(self._time_event, 0.02, self._timerEvent) + self._timer = TTkTimer(self._time_event, 0.03, self._timerEvent) self._timer.start() self.running = True @@ -110,10 +121,11 @@ class TTk(TTkWidget): elif evt is TTkK.TIME_EVENT: TTkHelper.paintAll() self._timerEvent.set() + self._fps() pass elif evt is TTkK.SCREEN_EVENT: self.setGeometry(0,0,TTkGlbl.term_w,TTkGlbl.term_h) - TTkLog.info(f"Resize: w:{TTkGlbl.term_w}, h:{TTkGlbl.term_h}") + #TTkLog.info(f"Resize: w:{TTkGlbl.term_w}, h:{TTkGlbl.term_h}") elif evt is TTkK.QUIT_EVENT: TTkLog.debug(f"Quit.") break