feat: add extend() method to ListStore

This commit is contained in:
aclist committed 2026-02-23 06:22:32 +09:00
1 parent 3859188ade
commit d6fd7b2494
6 files changed
+94 -42

No files matched your search

+82 -12
View File
@@ -1,9 +1,9 @@
from dataclasses import dataclass
from typing import Any
from dzgui.const.enum import HELP_MENU_ROWS
from dzgui.util.redact import redact_log
from dzgui.util.strings import delimiter
from dzgui.views.dialogs.generic import ExceptionDialog
import gi
@@ -11,6 +11,27 @@ gi.require_version("Gtk", "3.0")
from gi.repository.Gtk import ListStore # noqa E402
from gi.repository import GObject # noqa E402
GTYPE_TO_PYTHON = {
GObject.type_from_name(GObject.type_name(ptype)): ptype
for ptype in (int, float, str, bool, object)
}
@dataclass(slots=True, frozen=True)
class ServerCols:
name: str
_map: str
perspective: str
gametime: str
players: int
_max: int
queue: int
ip: str
qport: int
ping: int
provider: str
modded: bool
@dataclass(slots=True, frozen=True)
class ModCols:
@@ -38,7 +59,7 @@ class ServerModCols:
@dataclass(slots=True, frozen=True)
class MenuCols:
name: str
name: GObject.TYPE_STRING # str
hidden: GObject.TYPE_PYOBJECT
@@ -46,10 +67,52 @@ class FastInsertListStore(ListStore):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
def _is_same_length(self, lists: list[list[Any]]) -> bool:
first_len = len(lists[0])
if not all(len(sublist) == first_len for sublist in lists):
return False
return True
def _is_type_homogeneous(self, lists: list[list[Any]]) -> bool:
transposed = zip(*lists)
for column in transposed:
first_type = type(column[0])
if not all(type(item) is first_type for item in column):
return False
return True
def extend(self, rows: list[list[Any]]) -> None:
"""
Compared to calling append() directly, introduces negligible overhead,
but guarantees type and length equivalence prior to insertion
"""
n_cols = self.get_n_columns()
expected_types = [
GTYPE_TO_PYTHON[self.get_column_type(i)] for i in range(n_cols)
]
if not self._is_same_length(rows):
raise ValueError("Sublists are not of uniform length")
if not self._is_type_homogeneous(rows):
raise TypeError("Sublists are not type homogeneous")
if not all(isinstance(a, b) for a, b in zip(rows[0], expected_types)):
raise TypeError("Sublist types are not same as ListStore")
if len(rows[0]) != n_cols:
raise ValueError("Sublist column length is not same as ListStore")
for row in rows:
self.append(row)
def append(self, row) -> None:
"""
Optimized for speed, but makes no assurances about row homogeneity
and may segfault if types and length are not identical to ListStore.
For this reason, it is recommended to use the extend() method to insert
an entire list of lists
"""
total = len(row)
i = len(self)
tree_iter = self.insert_with_values(i, tuple(range(0, total)), row)
tree_iter = self.insert_with_values(i, tuple(range(total)), row)
return tree_iter
@@ -62,7 +125,7 @@ class ModelFactory:
with open(path, "r") as f:
lines = [line.split(delimiter) for line in f.read().splitlines()]
for record in lines:
# NOTE: strip PII and API keys
# NOTE: strips PII and API keys
clean = redact_log(record)
store.append(clean)
return store
@@ -73,21 +136,28 @@ class ModelFactory:
)
return store
def make_map_store(self) -> ListStore:
def make_map_store(self) -> FastInsertListStore:
return ListStore(str)
def make_help_store(self) -> ListStore:
def make_help_store(self) -> FastInsertListStore:
store = self.new_model_from_class(MenuCols)
for row in HELP_MENU_ROWS:
label = row.dict["label"]
store.append([label, row])
rows = [[row.dict["label"], row] for row in HELP_MENU_ROWS]
# for row in rows:HELP_MENU_ROWS:
# print(type(row) is object)
store.extend(rows)
# for row in HELP_MENU_ROWS:
# label = row.dict["label"]
# store.append([label, row])
return store
def make_mod_store(self) -> ListStore:
def make_mod_store(self) -> FastInsertListStore:
return self.new_model_from_class(ModCols)
def make_log_store(self) -> ListStore:
def make_log_store(self) -> FastInsertListStore:
return self.new_model_from_class(LogCols)
def make_server_mod_store(self) -> ListStore:
def make_server_mod_store(self) -> FastInsertListStore:
return self.new_model_from_class(ServerModCols)
def make_server_store(self) -> FastInsertListStore:
return self.new_model_from_class(ServerCols)