Fix dict changing size problem in retry_decrypt_..

Also add a copy() method to models, and make them able
to not have a sync_id (in which case they won't send pyotherside
events).
This commit is contained in:
miruka 2020-03-15 16:18:32 -04:00
parent d00db2256d
commit adbe2d88ee
4 changed files with 28 additions and 16 deletions

View File

@ -981,7 +981,7 @@ class MatrixClient(nio.AsyncClient):
_, room_id, _ = sync_id _, room_id, _ = sync_id
for ev in model.values(): for ev in model.copy().values():
room = self.all_rooms[room_id] room = self.all_rooms[room_id]
if isinstance(ev.source, nio.MegolmEvent): if isinstance(ev.source, nio.MegolmEvent):

View File

@ -2,7 +2,9 @@
from bisect import bisect from bisect import bisect
from threading import RLock from threading import RLock
from typing import TYPE_CHECKING, Any, Dict, Iterator, List, MutableMapping from typing import (
TYPE_CHECKING, Any, Dict, Iterator, List, MutableMapping, Optional,
)
from blist import blist from blist import blist
@ -29,8 +31,8 @@ class Model(MutableMapping):
Items in the model are kept sorted using the `ModelItem` subclass `__lt__`. Items in the model are kept sorted using the `ModelItem` subclass `__lt__`.
""" """
def __init__(self, sync_id: SyncId) -> None: def __init__(self, sync_id: Optional[SyncId]) -> None:
self.sync_id: SyncId = sync_id self.sync_id: Optional[SyncId] = sync_id
self._data: Dict[Any, "ModelItem"] = {} self._data: Dict[Any, "ModelItem"] = {}
self._sorted_data: List["ModelItem"] = blist() self._sorted_data: List["ModelItem"] = blist()
self._write_lock: RLock = RLock() self._write_lock: RLock = RLock()
@ -86,7 +88,8 @@ class Model(MutableMapping):
index = bisect(self._sorted_data, new) index = bisect(self._sorted_data, new)
self._sorted_data.insert(index, new) self._sorted_data.insert(index, new)
ModelItemInserted(self.sync_id, index, new) if self.sync_id:
ModelItemInserted(self.sync_id, index, new)
def __delitem__(self, key) -> None: def __delitem__(self, key) -> None:
@ -98,7 +101,8 @@ class Model(MutableMapping):
index = self._sorted_data.index(item) index = self._sorted_data.index(item)
del self._sorted_data[index] del self._sorted_data[index]
ModelItemDeleted(self.sync_id, index) if self.sync_id:
ModelItemDeleted(self.sync_id, index)
def __iter__(self) -> Iterator: def __iter__(self) -> Iterator:
@ -116,4 +120,11 @@ class Model(MutableMapping):
def clear(self) -> None: def clear(self) -> None:
super().clear() super().clear()
ModelCleared(self.sync_id) if self.sync_id:
ModelCleared(self.sync_id)
def copy(self, sync_id: Optional[SyncId] = None) -> "Model":
new = type(self)(sync_id=sync_id)
new.update(self)
return new

View File

@ -42,13 +42,14 @@ class ModelItem:
self.parent_model._sorted_data.sort() self.parent_model._sorted_data.sort()
new_index = self.parent_model._sorted_data.index(self) new_index = self.parent_model._sorted_data.index(self)
ModelItemFieldChanged( if self.parent_model.sync_id:
self.parent_model.sync_id, ModelItemFieldChanged(
old_index, self.parent_model.sync_id,
new_index, old_index,
name, new_index,
self.serialize_field(name), name,
) self.serialize_field(name),
)
def __delattr__(self, name: str) -> None: def __delattr__(self, name: str) -> None:

View File

@ -60,13 +60,13 @@ QtObject {
function onModelItemInserted(syncId, index, item) { function onModelItemInserted(syncId, index, item) {
// print("insert", syncId, index, item) print("insert", syncId, index, item)
ModelStore.get(syncId).insert(index, item) ModelStore.get(syncId).insert(index, item)
} }
function onModelItemFieldChanged(syncId, oldIndex, newIndex, field, value){ function onModelItemFieldChanged(syncId, oldIndex, newIndex, field, value){
// print("change", syncId, oldIndex, newIndex, field, value) print("change", syncId, oldIndex, newIndex, field, value)
const model = ModelStore.get(syncId) const model = ModelStore.get(syncId)
model.setProperty(oldIndex, field, value) model.setProperty(oldIndex, field, value)