Use a Deque for roomEvents's ListModel

- Take a custom container callable for ListModel __init__ (defaults to
  list, must be a MutableSequence)

- Use a Deque for roomEvents, which is much faster for inserting
  new items at the beginning.
This commit is contained in:
miruka 2019-04-17 17:07:20 -04:00
parent f0dab1801a
commit 9e5e2c6718
4 changed files with 31 additions and 28 deletions

View File

@ -1,6 +1,7 @@
import logging
from typing import (
Any, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple, Union
Any, Callable, Dict, Iterable, List, Mapping, MutableSequence, Optional,
Sequence, Tuple, Union
)
from namedlist import namedlist
@ -18,22 +19,23 @@ class ListModel(QAbstractListModel):
def __init__(self,
initial_data: Optional[List[NewValue]] = None,
container: Callable[..., MutableSequence] = list,
parent: Optional[QObject] = None) -> None:
super().__init__(parent)
self._ref_namedlist = None
self._roles: Tuple[str, ...] = ()
self._list: list = []
self._data: MutableSequence = container()
if initial_data:
self.extend(initial_data)
def __repr__(self) -> str:
return "%s[%s]" % (type(self).__name__,
", ".join((repr(i) for i in self)))
return "%s(%r)" % (type(self).__name__, self._data)
def __getitem__(self, index):
return self._list[index]
return self._data[index]
def __setitem__(self, index, value) -> None:
@ -57,11 +59,11 @@ class ListModel(QAbstractListModel):
if role <= Qt.UserRole:
return None
return self._list[index.row()][role - Qt.UserRole - 1]
return self._data[index.row()][role - Qt.UserRole - 1]
def rowCount(self, _: QModelIndex = QModelIndex()) -> int:
return len(self._list)
return len(self._data)
def _convert_new_value(self, value: NewValue) -> Any:
@ -98,12 +100,12 @@ class ListModel(QAbstractListModel):
@pyqtSlot(int, result="QVariantMap")
def get(self, index: int) -> ReturnItem:
return self._list[index]._asdict()
return self._data[index]._asdict()
@pyqtSlot(str, "QVariant", result=int)
def indexWhere(self, prop: str, is_value: Any) -> int:
for i, item in enumerate(self._list):
for i, item in enumerate(self._data):
if getattr(item, prop) == is_value:
return i
@ -120,7 +122,7 @@ class ListModel(QAbstractListModel):
def insert(self, index: int, value: NewValue) -> None:
value = self._convert_new_value(value)
self.beginInsertRows(QModelIndex(), index, index)
self._list.insert(index, value)
self._data.insert(index, value)
self.endInsertRows()
self.changed.emit()
@ -140,14 +142,14 @@ class ListModel(QAbstractListModel):
def set(self, index: int, value: NewValue) -> None:
qidx = QAbstractListModel.index(self, index, 0)
value = self._convert_new_value(value)
self._list[index] = value
self._data[index] = value
self.dataChanged.emit(qidx, qidx, self.roleNames())
self.changed.emit()
@pyqtSlot(int, str, "QVariant")
def setProperty(self, index: int, prop: str, value: Any) -> None:
self._list[index][self._roles.index(prop)] = value
self._data[index][self._roles.index(prop)] = value
qidx = QAbstractListModel.index(self, index, 0)
self.dataChanged.emit(qidx, qidx, self.roleNames())
self.changed.emit()
@ -175,9 +177,9 @@ class ListModel(QAbstractListModel):
return
last = from_ + n
cut = self._list[from_:last]
del self._list[from_:last]
self._list[to:to] = cut
cut = self._data[from_:last]
del self._data[from_:last]
self._data[to:to] = cut
self.endMoveRows()
self.changed.emit()
@ -186,7 +188,7 @@ class ListModel(QAbstractListModel):
@pyqtSlot(int)
def remove(self, index: int) -> None: # pylint: disable=arguments-differ
self.beginRemoveRows(QModelIndex(), index, index)
del self._list[index]
del self._data[index]
self.endRemoveRows()
self.changed.emit()
@ -195,6 +197,6 @@ class ListModel(QAbstractListModel):
def clear(self) -> None:
# Reimplemented for performance reasons (begin/endRemoveRows)
self.beginRemoveRows(QModelIndex(), 0, self.rowCount())
self._list.clear()
self._data.clear()
self.endRemoveRows()
self.changed.emit()

View File

@ -1,4 +1,4 @@
from typing import Any, DefaultDict
from typing import Any, Callable, DefaultDict, MutableSequence
from PyQt5.QtCore import QObject, pyqtSlot
@ -6,12 +6,14 @@ from .list_model import ListModel
class ListModelMap(QObject):
def __init__(self) -> None:
def __init__(self, models_container: Callable[..., MutableSequence] = list
) -> None:
super().__init__()
# Set the parent to prevent item garbage-collection on the C++ side
self.dict: DefaultDict[Any, ListModel] = \
DefaultDict(lambda: ListModel(parent=self))
DefaultDict(lambda: ListModel(parent = self,
container = models_container))
@pyqtSlot(str, result="QVariant")

View File

@ -1,6 +1,8 @@
# Copyright 2019 miruka
# This file is part of harmonyqml, licensed under GPLv3.
from typing import Deque
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal
from .list_model import ListModel
@ -15,7 +17,7 @@ class QMLModels(QObject):
super().__init__()
self._accounts: ListModel = ListModel()
self._rooms: ListModelMap = ListModelMap()
self._room_events: ListModelMap = ListModelMap()
self._room_events: ListModelMap = ListModelMap(models_container=Deque)
@pyqtProperty(ListModel, constant=True)

View File

@ -7,7 +7,6 @@ Column {
id: "rootCol"
function mins_between(date1, date2) {
console.log(Math.round((((date2 - date1) % 86400000) % 3600000) / 60000))
return Math.round((((date2 - date1) % 86400000) % 3600000) / 60000)
}
@ -59,8 +58,6 @@ Column {
combine ? standardSpacing / 4 :
standardSpacing
//Text { text: rootCol.topPadding }
Daybreak { visible: dayBreak }
MessageContent { visible: isMessage }