Working python proxy/filter for room list
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
from typing import TYPE_CHECKING, Collection, Dict, Optional, Tuple
|
||||
from typing import TYPE_CHECKING, Any, Collection, Dict, Optional, Tuple
|
||||
|
||||
from . import SyncId
|
||||
from .model import Model
|
||||
@@ -20,10 +20,20 @@ class ModelFilter(ModelProxy):
|
||||
return True
|
||||
|
||||
|
||||
def source_item_set(self, source: Model, key, value: "ModelItem") -> None:
|
||||
def source_item_set(
|
||||
self,
|
||||
source: Model,
|
||||
key,
|
||||
value: "ModelItem",
|
||||
_changed_fields: Optional[Dict[str, Any]] = None,
|
||||
) -> None:
|
||||
if self.accept_source(source):
|
||||
dct = self if self.accept_item(value) else self.filtered_out
|
||||
dct[source.sync_id, key] = value
|
||||
if self.accept_item(value):
|
||||
self.__setitem__((source.sync_id, key), value, _changed_fields)
|
||||
self.filtered_out.pop((source.sync_id, key), None)
|
||||
else:
|
||||
self.filtered_out[source.sync_id, key] = value
|
||||
self.pop((source.sync_id, key), None)
|
||||
|
||||
|
||||
def source_item_deleted(self, source: Model, key) -> None:
|
||||
@@ -64,11 +74,11 @@ class ModelFilter(ModelProxy):
|
||||
|
||||
|
||||
class FieldSubstringFilter(ModelFilter):
|
||||
def __init__(self, fields: Collection[str], *args, **kwargs) -> None:
|
||||
def __init__(self, sync_id: SyncId, fields: Collection[str]) -> None:
|
||||
self.fields: Collection[str] = fields
|
||||
self._filter: str = ""
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
super().__init__(sync_id)
|
||||
|
||||
|
||||
@property
|
||||
|
@@ -40,6 +40,11 @@ class Model(MutableMapping):
|
||||
self._sorted_data: List["ModelItem"] = blist()
|
||||
self._write_lock: RLock = RLock()
|
||||
|
||||
self.take_items_ownership: bool = True
|
||||
|
||||
if self.sync_id:
|
||||
self.instances[self.sync_id] = self
|
||||
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Provide a full representation of the model and its content."""
|
||||
@@ -63,27 +68,34 @@ class Model(MutableMapping):
|
||||
return self._data[key]
|
||||
|
||||
|
||||
def __setitem__(self, key, value: "ModelItem") -> None:
|
||||
def __setitem__(
|
||||
self,
|
||||
key,
|
||||
value: "ModelItem",
|
||||
_changed_fields: Optional[Dict[str, Any]] = None,
|
||||
) -> None:
|
||||
with self._write_lock:
|
||||
existing = self._data.get(key)
|
||||
new = value
|
||||
|
||||
# Collect changed fields
|
||||
|
||||
changed_fields = {}
|
||||
changed_fields = _changed_fields or {}
|
||||
|
||||
for field in new.__dataclass_fields__: # type: ignore
|
||||
changed = True
|
||||
if not changed_fields:
|
||||
for field in new.__dataclass_fields__: # type: ignore
|
||||
changed = True
|
||||
|
||||
if existing:
|
||||
changed = getattr(new, field) != getattr(existing, field)
|
||||
if existing:
|
||||
changed = \
|
||||
getattr(new, field) != getattr(existing, field)
|
||||
|
||||
if changed:
|
||||
changed_fields[field] = new.serialize_field(field)
|
||||
if changed:
|
||||
changed_fields[field] = new.serialize_field(field)
|
||||
|
||||
# Set parent model on new item
|
||||
|
||||
if self.sync_id:
|
||||
if self.sync_id and self.take_items_ownership:
|
||||
new.parent_model = self
|
||||
|
||||
# Insert into sorted data
|
||||
@@ -101,6 +113,12 @@ class Model(MutableMapping):
|
||||
|
||||
self._data[key] = new
|
||||
|
||||
# Callbacks
|
||||
|
||||
for sync_id, proxy in self.proxies.items():
|
||||
if sync_id != self.sync_id:
|
||||
proxy.source_item_set(self, key, value)
|
||||
|
||||
# Emit PyOtherSide event
|
||||
|
||||
if self.sync_id and (index_then != index_now or changed_fields):
|
||||
@@ -121,6 +139,10 @@ class Model(MutableMapping):
|
||||
index = self._sorted_data.index(item)
|
||||
del self._sorted_data[index]
|
||||
|
||||
for sync_id, proxy in self.proxies.items():
|
||||
if sync_id != self.sync_id:
|
||||
proxy.source_item_deleted(self, key)
|
||||
|
||||
if self.sync_id:
|
||||
ModelItemDeleted(self.sync_id, index)
|
||||
|
||||
|
@@ -42,19 +42,23 @@ class ModelItem:
|
||||
|
||||
super().__setattr__(name, value)
|
||||
|
||||
model = self.parent_model
|
||||
parent = self.parent_model
|
||||
|
||||
if not model.sync_id:
|
||||
if not parent.sync_id:
|
||||
return
|
||||
|
||||
with model._write_lock:
|
||||
index_then = model._sorted_data.index(self)
|
||||
model._sorted_data.sort()
|
||||
index_now = model._sorted_data.index(self)
|
||||
fields = {name: self.serialize_field(name)}
|
||||
|
||||
fields = {name: self.serialize_field(name)}
|
||||
with parent._write_lock:
|
||||
index_then = parent._sorted_data.index(self)
|
||||
parent._sorted_data.sort()
|
||||
index_now = parent._sorted_data.index(self)
|
||||
|
||||
ModelItemSet(model.sync_id, index_then, index_now, fields)
|
||||
ModelItemSet(parent.sync_id, index_then, index_now, fields)
|
||||
|
||||
for sync_id, proxy in parent.proxies.items():
|
||||
if sync_id != parent.sync_id:
|
||||
proxy.source_item_set(parent, self.id, self, fields)
|
||||
|
||||
|
||||
def __delattr__(self, name: str) -> None:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||
|
||||
from . import SyncId
|
||||
from .model import Model
|
||||
@@ -12,14 +12,12 @@ if TYPE_CHECKING:
|
||||
class ModelProxy(Model):
|
||||
def __init__(self, sync_id: SyncId) -> None:
|
||||
super().__init__(sync_id)
|
||||
self.take_items_ownership = False
|
||||
Model.proxies[sync_id] = self
|
||||
|
||||
for sync_id, model in Model.instances.items():
|
||||
if sync_id != self.sync_id and self.accept_source(model):
|
||||
for key, item in model.items():
|
||||
# if isinstance(model, ModelProxy):
|
||||
# key = key[1]
|
||||
|
||||
self.source_item_set(model, key, item)
|
||||
|
||||
|
||||
@@ -27,9 +25,15 @@ class ModelProxy(Model):
|
||||
return True
|
||||
|
||||
|
||||
def source_item_set(self, source: Model, key, value: "ModelItem") -> None:
|
||||
def source_item_set(
|
||||
self,
|
||||
source: Model,
|
||||
key,
|
||||
value: "ModelItem",
|
||||
_changed_fields: Optional[Dict[str, Any]] = None,
|
||||
) -> None:
|
||||
if self.accept_source(source):
|
||||
self[source.sync_id, key] = value
|
||||
self.__setitem__((source.sync_id, key), value, _changed_fields)
|
||||
|
||||
|
||||
def source_item_deleted(self, source: Model, key) -> None:
|
||||
|
Reference in New Issue
Block a user