Source code for wield.declarative.callbacks.relay

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: © 2021 Massachusetts Institute of Technology.
# SPDX-FileCopyrightText: © 2021 Lee McCuller <mcculler@caltech.edu>
# NOTICE: authors should document their contributions in concisely in NOTICE
# with details inline in source files, comments, and docstrings.
"""
"""
from ..utilities.representations import ReprMixin
from ..properties import mproperty
import numpy as np

_UNIQUE = ("UNIQUE",)


[docs] class RelayValueRejected(Exception): pass
[docs] class RelayValueCoerced(RelayValueRejected): def __init__(self, preferred): self.preferred = preferred
[docs] class RelayValue(ReprMixin): """ """ __slots__ = ("callbacks", "_value") __repr_slots__ = ("_value",)
[docs] @staticmethod def validator(val): return val
[docs] def __init__(self, initial_value, validator=None, **kwargs): """ """ super(RelayValue, self).__init__(**kwargs) self.callbacks = {} if validator is not None: self.validator = validator initial_value = self.validator(initial_value) self._value = initial_value return
[docs] def register( self, key=None, callback=None, assumed_value=_UNIQUE, call_immediate=False, remove=False, ): """ """ if key is None: key = callback if key is None: raise RuntimeError("Key or Callback must be specified") if not remove: self.callbacks[key] = callback if assumed_value is not _UNIQUE: if self._value != assumed_value: callback(self._value) elif call_immediate: callback(self._value) else: if assumed_value is not _UNIQUE: if self._value != assumed_value: callback(assumed_value) del self.callbacks[key] return
[docs] def validator_assign(self, validator, remove=False): if not remove: if self.validator is not self.__class__.validator: raise RuntimeError("Can not set multiple validators") self.validator = validator else: del self.validator return
[docs] def put(self, val): if np.any(val != self._value): val = self.validator(val) self._value = val for cb in list(self.callbacks.values()): cb(val) return
[docs] def put_exclude_cb(self, val, key): if val != self._value: val = self.validator(val) self._value = val for cb_key, cb in list(self.callbacks.items()): if cb_key is not key: cb(val) return
[docs] def put_coerce(self, val): if np.any(val != self._value): try: val = self.validator(val) retval = True except RelayValueCoerced as E: val = E.preferred retval = False self._value = val for cb in list(self.callbacks.values()): cb(val) return retval return True
[docs] def put_coerce_exclude_cb(self, val, key): if val != self._value: try: val = self.validator(val) retval = True except RelayValueCoerced as E: val = E.preferred retval = False self._value = val for cb_key, cb in list(self.callbacks.items()): if cb_key is not key: cb(val) return retval return True
[docs] def put_valid(self, val): if val != self._value: self._value = val for cb in list(self.callbacks.values()): cb(val) return
[docs] def put_valid_exclude_cb(self, val, key): if val != self._value: self._value = val for cb_key, cb in list(self.callbacks.items()): if cb_key is not key: cb(val) return
@property def value(self): return self._value @value.setter def value(self, val): if np.any(val != self._value): val = self.validator(val) self._value = val for cb in list(self.callbacks.values()): cb(val) return @mproperty def shadow(self): return self.__class__(self.value, validator=self.validator)
[docs] def shadow_from(self): self.put_valid(self.shadow._value) return
[docs] def shadow_to(self): self.shadow.put_valid(self._value) return