Last active
August 29, 2015 14:10
-
-
Save Halicea/4946ba5a271073db4c5b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import print_function | |
from atom.catom import DefaultValue | |
from atom.api import (Atom, Signal, Instance, ForwardInstance, Bool, Value, | |
List, Str, set_default) | |
from .core import X4CDefinition, X4CObject, ROOT_DEFINITION | |
from .types import Type | |
class Formula(Atom): | |
_exp = Str(default='') | |
interpreter = Value() | |
eval_method = Value() | |
@property | |
def exp(self): | |
return self._exp | |
@exp.setter | |
def exp(self, value): | |
self._exp = value | |
self.eval_method = lambda context: self.interpreter.eval( | |
value, | |
context=context) | |
def eval(self, context): | |
return self.eval_method(context) | |
class Property(X4CObject): | |
_value = Value() | |
_formula = Instance(Formula) | |
@property | |
def IsFormula(self): | |
return self._value.startswith('=') # self._formula is not None | |
definition = ForwardInstance(lambda: PropertyDefinition) | |
def __init__(self, definition): | |
super(Property, self).__init__(definition) | |
m_value = self.get_member('_value') | |
m_value.set_default_value_mode(DefaultValue.CallObject, | |
lambda: self.definition.default) | |
def __getstate__(self): | |
state = super(Property, self).__getstate__() | |
if 'changed' in state: | |
del state['changed'] | |
if '_value' in state: | |
del state['_value'] | |
state['value'] = self.definition.type.format(self._value, 'getstate') | |
return state | |
def __setstate__(self, state, repo): | |
for name, member in self.members().items(): | |
if isinstance(member, Signal) or name.startswith("_"): | |
continue | |
try: | |
if name in state: | |
setattr(self, name, state[name]) | |
except TypeError: | |
pass | |
if 'value' in state: | |
self.value = state['value'] | |
def __getattr__(self, name): | |
if name in self.definition.type.actions: | |
return getattr(self.definition.type, name) | |
else: | |
raise AttributeError("Action not found") | |
@property | |
def actions(self): | |
return self.definition.type.actions | |
@property | |
def value(self): | |
raw_value = self._value | |
if self._value is None: | |
raw_value = self.definition.default | |
if self.IsFormula: | |
raw_value = self._formula.eval(self.context) | |
else: | |
raw_value = self._value | |
return self.definition.type.format(raw_value) | |
@value.setter | |
def value(self, value): | |
# if value.startswith('='): | |
# _formula.build(value) | |
if self.validate(value): | |
# FIXME: use formulas too | |
self._value = self.definition.type.setter(value) | |
self.changed(self, value) | |
else: | |
raise ValueError("Invalid value '{}'".format(value)) | |
def __repr__(self): | |
return '$pr{}:{}'.format(self.definition.name, self.value) | |
def __str__(self): | |
return self.__repr__() | |
class PropertyDefinition(X4CDefinition): | |
# FIXME: support value & unit | |
parent = set_default(ROOT_DEFINITION) | |
defines_class = set_default(Property) | |
default = Value() | |
is_formula = Bool(False) | |
type = Instance(Type) | |
constraints = List() | |
def __init__(self, name, x4c_type=Type, *args, **kwargs): | |
super(PropertyDefinition, self).__init__(name, **kwargs) | |
m_default = self.get_member('default') | |
m_default.set_default_value_mode(DefaultValue.CallObject, | |
lambda: self.type.default) | |
try: | |
if callable(x4c_type): | |
self.type = x4c_type() | |
else: | |
self.type = x4c_type | |
except Exception: | |
raise ValueError("Invalid x4c_type") | |
def __setstate__(self, slots, repo): | |
super(PropertyDefinition, self).__setstate__(slots, repo) | |
self.default = slots['default'] | |
self.is_formula = slots['is_formula'] | |
self.type = repo.get(slots['type']) | |
self.constraints = repo.get_all(slots['constraints']) | |
def clone(self, name): | |
return PropertyDefinition(name=name, x4c_type=self.type, parent=self) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment