From 4619444ed11abf715d24f13b1a3a621a899dae91 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Thu, 12 Feb 2026 21:09:48 -0500 Subject: [PATCH] Cache sorted layer indices on Art --- playscii/art.py | 13 +++++++++++++ playscii/renderable.py | 4 +--- playscii/ui_art_dialog.py | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/playscii/art.py b/playscii/art.py index 9120e98..57bb523 100644 --- a/playscii/art.py +++ b/playscii/art.py @@ -141,6 +141,7 @@ class Art: self.instances = [] "List of ArtInstances using us as their source" # init frames and layers - ArtFromDisk has its own logic for this + self._sorted_layers = None self.init_layers() self.init_frames() # support non-square characters: @@ -177,6 +178,14 @@ class Art: self.layers_visibility = [True] self.layer_names = ["Layer 1"] + def get_sorted_layers(self): + "Return layer indices sorted by Z depth, cached until invalidated." + if self._sorted_layers is None: + self._sorted_layers = tuple( + sorted(range(self.layers), key=lambda i: self.layers_z[i]) + ) + return self._sorted_layers + def init_frames(self): self.frames = 0 # current frame being edited @@ -309,6 +318,7 @@ class Art: self.layer_names.append(new_name) # rebuild geo with added verts for new layer self.geo_changed = True + self._sorted_layers = None # set new layer as active if self is self.app.ui.active_art: self.app.ui.set_active_layer(self.layers - 1) @@ -346,6 +356,7 @@ class Art: self.layer_names.pop(index) self.layers -= 1 self.geo_changed = True + self._sorted_layers = None self.mark_all_frames_changed() if self.active_layer > self.layers - 1: self.app.ui.set_active_layer(self.layers - 1) @@ -1316,6 +1327,7 @@ class ArtInstance(Art): self.renderables = [] # instances shouldn't have instances; cause user problems if attempted self.instances = None + self._sorted_layers = None self.restore_from_source() self.source.instances.append(self) @@ -1339,6 +1351,7 @@ class ArtInstance(Art): setattr(self, prop, getattr(self.source, prop)) # copy lists self.layers_z = self.source.layers_z[:] + self._sorted_layers = None self.layers_visibility = self.source.layers_visibility[:] self.layer_names = self.source.layer_names[:] self.frame_delays = self.source.frame_delays[:] diff --git a/playscii/renderable.py b/playscii/renderable.py index ea17f69..bec00c4 100644 --- a/playscii/renderable.py +++ b/playscii/renderable.py @@ -528,9 +528,7 @@ class TileRenderable: GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) # draw all specified layers if no list given if layers is None: - # sort layers in Z depth - layers = list(range(self.art.layers)) - layers.sort(key=lambda i: self.art.layers_z[i], reverse=False) + layers = self.art.get_sorted_layers() # handle a single int param elif type(layers) is int: layers = [layers] diff --git a/playscii/ui_art_dialog.py b/playscii/ui_art_dialog.py index 320b417..7f9df82 100644 --- a/playscii/ui_art_dialog.py +++ b/playscii/ui_art_dialog.py @@ -693,6 +693,7 @@ class SetLayerZDialog(UIDialog): return new_z = float(self.field_texts[0]) self.ui.active_art.layers_z[self.ui.active_art.active_layer] = new_z + self.ui.active_art._sorted_layers = None self.ui.active_art.set_unsaved_changes(True) self.ui.app.grid.reset() self.dismiss()