more layer replacement
This commit is contained in:
parent
14634af83c
commit
236f3d2058
@ -92,7 +92,6 @@ class PropertyLayer(PropertyManager):
|
|||||||
def __setitem__(self, name, value):
|
def __setitem__(self, name, value):
|
||||||
if name in self.properties and self.properties[name] == value:
|
if name in self.properties and self.properties[name] == value:
|
||||||
return
|
return
|
||||||
logger.debug("property change: %s => %s", name, value)
|
|
||||||
self.properties[name] = value
|
self.properties[name] = value
|
||||||
self._fireCallbacks(name, value)
|
self._fireCallbacks(name, value)
|
||||||
|
|
||||||
@ -146,33 +145,61 @@ class PropertyStack(PropertyManager):
|
|||||||
"""
|
"""
|
||||||
highest priority = 0
|
highest priority = 0
|
||||||
"""
|
"""
|
||||||
|
self._fireChanges(self._addLayer(priority, pm))
|
||||||
|
|
||||||
|
def _addLayer(self, priority: int, pm: PropertyManager):
|
||||||
|
changes = {}
|
||||||
for key in pm.keys():
|
for key in pm.keys():
|
||||||
if key not in self or self[key] != pm[key]:
|
if key not in self or self[key] != pm[key]:
|
||||||
self._fireCallbacks(key, pm[key])
|
changes[key] = pm[key]
|
||||||
|
|
||||||
self.layers.append({"priority": priority, "props": pm})
|
|
||||||
|
|
||||||
def eventClosure(name, value):
|
def eventClosure(name, value):
|
||||||
self.receiveEvent(pm, name, value)
|
self.receiveEvent(pm, name, value)
|
||||||
|
|
||||||
pm.wire(eventClosure)
|
sub = pm.wire(eventClosure)
|
||||||
|
|
||||||
|
self.layers.append({"priority": priority, "props": pm, "sub": sub})
|
||||||
|
|
||||||
|
return changes
|
||||||
|
|
||||||
|
def removeLayer(self, pm: PropertyManager):
|
||||||
|
for layer in self.layers:
|
||||||
|
if layer["props"] == pm:
|
||||||
|
self._fireChanges(self._removeLayer(layer))
|
||||||
|
|
||||||
|
def _removeLayer(self, layer):
|
||||||
|
layer["sub"].cancel()
|
||||||
|
self.layers.remove(layer)
|
||||||
|
changes = {}
|
||||||
|
pm = layer["props"]
|
||||||
|
for key in pm.keys():
|
||||||
|
if key in self:
|
||||||
|
if self[key] != pm[key]:
|
||||||
|
changes[key] = self[key]
|
||||||
|
else:
|
||||||
|
changes[key] = None
|
||||||
|
return changes
|
||||||
|
|
||||||
|
def replaceLayer(self, priority: int, pm: PropertyManager):
|
||||||
|
layers = [x for x in self.layers if x["priority"] == priority]
|
||||||
|
changes = {}
|
||||||
|
if layers:
|
||||||
|
changes = self._removeLayer(layers[0])
|
||||||
|
|
||||||
|
for k, v in self._addLayer(priority, pm).items():
|
||||||
|
changes[k] = v
|
||||||
|
|
||||||
|
self._fireChanges(changes)
|
||||||
|
|
||||||
|
def _fireChanges(self, changes):
|
||||||
|
for k, v in changes.items():
|
||||||
|
self._fireCallbacks(k, v)
|
||||||
|
|
||||||
def receiveEvent(self, layer, name, value):
|
def receiveEvent(self, layer, name, value):
|
||||||
if layer != self._getTopLayer(name):
|
if layer != self._getTopLayer(name):
|
||||||
return
|
return
|
||||||
self._fireCallbacks(name, value)
|
self._fireCallbacks(name, value)
|
||||||
|
|
||||||
def removeLayer(self, pm: PropertyManager):
|
|
||||||
for layer in self.layers:
|
|
||||||
if layer["props"] == pm:
|
|
||||||
self.layers.remove(layer)
|
|
||||||
for key in pm.keys():
|
|
||||||
if key in self:
|
|
||||||
if self[key] != pm[key]:
|
|
||||||
self._fireCallbacks(key, self[key])
|
|
||||||
else:
|
|
||||||
self._fireCallbacks(key, None)
|
|
||||||
|
|
||||||
def _getTopLayer(self, item):
|
def _getTopLayer(self, item):
|
||||||
layers = [la["props"] for la in sorted(self.layers, key=lambda l: l["priority"])]
|
layers = [la["props"] for la in sorted(self.layers, key=lambda l: l["priority"])]
|
||||||
for m in layers:
|
for m in layers:
|
||||||
|
@ -136,3 +136,34 @@ class PropertyStackTest(TestCase):
|
|||||||
mock.reset_mock()
|
mock.reset_mock()
|
||||||
stack.removeLayer(high_layer)
|
stack.removeLayer(high_layer)
|
||||||
mock.method.assert_called_once_with(None)
|
mock.method.assert_called_once_with(None)
|
||||||
|
|
||||||
|
def testReplaceLayer(self):
|
||||||
|
first_layer = PropertyLayer()
|
||||||
|
first_layer["testkey"] = "old value"
|
||||||
|
second_layer = PropertyLayer()
|
||||||
|
second_layer["testkey"] = "new value"
|
||||||
|
|
||||||
|
stack = PropertyStack()
|
||||||
|
stack.addLayer(0, first_layer)
|
||||||
|
|
||||||
|
mock = Mock()
|
||||||
|
stack.wireProperty("testkey", mock.method)
|
||||||
|
mock.method.assert_called_once_with("old value")
|
||||||
|
mock.reset_mock()
|
||||||
|
|
||||||
|
stack.replaceLayer(0, second_layer)
|
||||||
|
mock.method.assert_called_once_with("new value")
|
||||||
|
|
||||||
|
def testUnwiresEventsOnRemoval(self):
|
||||||
|
layer = PropertyLayer()
|
||||||
|
layer["testkey"] = "before"
|
||||||
|
stack = PropertyStack()
|
||||||
|
stack.addLayer(0, layer)
|
||||||
|
mock = Mock()
|
||||||
|
stack.wire(mock.method)
|
||||||
|
stack.removeLayer(layer)
|
||||||
|
mock.method.assert_called_once_with("testkey", None)
|
||||||
|
mock.reset_mock()
|
||||||
|
|
||||||
|
layer["testkey"] = "after"
|
||||||
|
mock.method.assert_not_called()
|
||||||
|
Loading…
Reference in New Issue
Block a user