Model items can now have multiple parent models

This commit is contained in:
miruka 2020-04-28 16:25:28 -04:00
parent 34f98b48d1
commit 393a56a50a
2 changed files with 19 additions and 21 deletions

View File

@ -79,7 +79,7 @@ class Model(MutableMapping):
# Set parent model on new item
if self.sync_id:
new.parent_model = self
new.parent_models[self.sync_id] = self
# Insert into sorted data
@ -106,8 +106,11 @@ class Model(MutableMapping):
def __delitem__(self, key) -> None:
with self._write_lock:
item = self._data[key]
item.parent_model = None
item = self._data[key]
if self.sync_id:
del item.parent_models[self.sync_id]
del self._data[key]
index = self._sorted_data.index(item)

View File

@ -1,9 +1,10 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
from typing import TYPE_CHECKING, Any, Dict, Optional
from typing import TYPE_CHECKING, Any, Dict
from ..pyotherside_events import ModelItemSet
from ..utils import serialize_value_for_qml
from . import SyncId
if TYPE_CHECKING:
from .model import Model
@ -21,37 +22,31 @@ class ModelItem:
"""
def __new__(cls, *_args, **_kwargs) -> "ModelItem":
cls.parent_model: Optional[Model] = None
cls.parent_models: Dict[SyncId, Model] = {}
return super().__new__(cls)
def __setattr__(self, name: str, value) -> None:
"""If this item is in a `Model`, alert it of attribute changes."""
if name == "parent_model" or self.parent_model is None:
if name == "parent_model" or not self.parent_models:
super().__setattr__(name, value)
return
if getattr(self, name) == value:
return
with self.parent_model._write_lock:
super().__setattr__(name, value)
super().__setattr__(name, value)
if self.parent_model.sync_id:
index_then = self.parent_model._sorted_data.index(self)
for sync_id, model in self.parent_models.items():
with model._write_lock:
index_then = model._sorted_data.index(self)
model._sorted_data.sort()
index_now = model._sorted_data.index(self)
self.parent_model._sorted_data.sort()
fields = {name: self.serialize_field(name)}
if self.parent_model.sync_id:
index_now = self.parent_model._sorted_data.index(self)
ModelItemSet(
self.parent_model.sync_id,
index_then,
index_now,
{name: self.serialize_field(name)},
)
ModelItemSet(sync_id, index_then, index_now, fields)
def __delattr__(self, name: str) -> None:
@ -72,6 +67,6 @@ class ModelItem:
return {
name: self.serialize_field(name) for name in dir(self)
if not (
name.startswith("_") or name in ("parent_model", "serialized")
name.startswith("_") or name in ("parent_models", "serialized")
)
}