def __publish_attr_changes(self, attr_changes): # Format: {fit: {item: {attr_ids}}} fit_changes_regular = {} # Format: {fit: {item: {attr_ids}}} fit_changes_masked = {} for item, attr_ids in attr_changes.items(): item_fit = item._fit item_attr_overrides = item.attrs._override_callbacks item_changes_regular = attr_ids.difference(item_attr_overrides) item_changes_masked = attr_ids.intersection(item_attr_overrides) if item_changes_regular: fit_changes_regular.setdefault(item_fit, {})[item] = item_changes_regular if item_changes_masked: fit_changes_masked.setdefault(item_fit, {})[item] = item_changes_masked # Format: {fit, [messages]} fits_msgs = {} for fit, attr_changes in fit_changes_regular.items(): msg = AttrsValueChanged(attr_changes) fits_msgs.setdefault(fit, []).append(msg) for fit, attr_changes in fit_changes_masked.items(): msg = AttrsValueChangedMasked(attr_changes) fits_msgs.setdefault(fit, []).append(msg) for fit, msgs in fits_msgs.items(): fit._publish_bulk(msgs)
def _override_value_may_change(self, attr_id): """Notify everyone that callback value may change. When originator of callback knows that callback return value may (or will) change for an attribute, it should invoke this method. """ self.__publish(AttrsValueChanged({self.__item: {attr_id}}))
def _set_override_callback(self, attr_id, callback): """Set override for the attribute in the form of callback.""" if self.__override_callbacks is None: self.__override_callbacks = {} # If the same callback is set, do nothing if self.__override_callbacks.get(attr_id) == callback: return self.__override_callbacks[attr_id] = callback # Exposed attribute value may change after setting/resetting override self.__publish(AttrsValueChanged({self.__item: {attr_id}}))
def _del_override_callback(self, attr_id): """Remove override callback from attribute.""" overrides = self.__override_callbacks or {} if attr_id not in overrides: return del overrides[attr_id] # Set overrides map to None if there're none left to save some memory if not overrides: self.__override_callbacks = None # Exposed attribute value may change after removing override self.__publish(AttrsValueChanged({self.__item: {attr_id}}))