Commit 871d0366 authored by Matias Guijarro's avatar Matias Guijarro
Browse files

Merge branch 'issue-100' into 'master'

Centralize custom members implementation (fixes #100)

Closes #100

See merge request !433
parents 584c975c 6e7d7e38
......@@ -33,7 +33,7 @@ from bliss.common.task_utils import *
from bliss.common.motor_config import StaticConfig
from bliss.common.motor_settings import AxisSettings
from bliss.common import event
from bliss.common.utils import Null
from bliss.common.utils import Null, with_custom_members
from bliss.config.static import get_config
from bliss.common.encoder import Encoder
import gevent
......@@ -94,6 +94,7 @@ class Motion(object):
return self.__axis
@with_custom_members
class Axis(object):
"""
Bliss motor axis
......@@ -116,8 +117,6 @@ class Axis(object):
self.__settings = AxisSettings(self)
self.__move_done = gevent.event.Event()
self.__move_done.set()
self.__custom_methods_list = list()
self.__custom_attributes_dict = dict()
self.__move_task = None
self.__stopped = False
self._in_group_move = False
......@@ -204,29 +203,6 @@ class Axis(object):
else:
return get_encoder(encoder_name)
@property
def custom_methods_list(self):
"""
List of custom methods defined for this axis.
Internal usage only
"""
# Returns a *copy* of the custom methods list.
return self.__custom_methods_list[:]
@property
def custom_attributes_list(self):
"""
List of custom attributes defined for this axis.
Internal usage only
"""
ad = self.__custom_attributes_dict
# Converts dict into list...
_attr_list = [(a_name, ad[a_name][0], ad[a_name][1]) for i, a_name in enumerate(ad)]
# Returns a *copy* of the custom attributes list.
return _attr_list[:]
def set_setting(self, *args):
"""Sets the given settings"""
self.settings.set(*args)
......@@ -252,10 +228,6 @@ class Axis(object):
return True
return False
def _add_custom_method(self, method, name, types_info=(None, None)):
setattr(self, name, method)
self.__custom_methods_list.append((name, types_info))
@lazy_init
def on(self):
"""Turns the axis on"""
......
......@@ -15,6 +15,7 @@ import gevent.event
import math
from bliss.common import log
from bliss.common.measurement import CounterBase
from bliss.common.utils import with_custom_members
class TempControllerCounter(CounterBase):
......@@ -29,6 +30,7 @@ class TempControllerCounter(CounterBase):
data = self.parent.read()
return data
@with_custom_members
class Input(object):
""" Implements the access to temperature sensors
"""
......@@ -41,10 +43,6 @@ class Input(object):
self.__name = config["name"]
self.__config = config
# lists of custom attr and commands
self.__custom_methods_list = list()
self.__custom_attributes_dict = dict()
# useful attribute for a temperature controller writer
self._attr_dict = {}
......@@ -63,22 +61,6 @@ class Input(object):
""" returns the sensor config """
return self.__config
@property
def custom_methods_list(self):
""" Returns a *copy* of the custom methods list."""
return self.__custom_methods_list[:]
@property
def custom_attributes_list(self):
""" Returns a *copy* of the custom attributes list """
ad = self.__custom_attributes_dict
# Converts dict into list...
_attr_list = [(a_name, ad[a_name][0], ad[a_name][1]) for i, a_name in enumerate(ad)]
# Returns a *copy* of the custom attributes list.
return _attr_list[:]
@property
def counter(self):
""" returns the counter object """
......@@ -94,11 +76,8 @@ class Input(object):
log.debug("On Input:state")
return self.controller.state_input(self)
def _add_custom_method(self, method, name, types_info=(None, None)):
""" necessary to add custom methods to a class """
setattr(self, name, method)
self.__custom_methods_list.append((name, types_info))
@with_custom_members
class Output(object):
""" Implements the access to temperature heaters """
def __init__(self, controller, config):
......@@ -126,11 +105,6 @@ class Output(object):
# if defined as self.__deadband, not available.
# in that case, use of decorator property offers it (read only) to world
# lists of custom attr and commands
self.__custom_methods_list = list()
self.__custom_attributes_dict = dict()
# useful attribute for a temperature controller writer
self._attr_dict = {}
......@@ -162,22 +136,6 @@ class Output(object):
While the setpoint is not reached, a wait will block on it."""
return self.__deadband
@property
def custom_methods_list(self):
""" Returns a *copy* of the custom methods """
return self.__custom_methods_list[:]
@property
def custom_attributes_list(self):
""" returns the list of attributes """
ad = self.__custom_attributes_dict
# Converts dict into list...
_attr_list = [(a_name, ad[a_name][0], ad[a_name][1]) for i, a_name in enumerate(ad)]
# Returns a *copy* of the custom attributes list.
return _attr_list[:]
@property
def counter(self):
""" returns the counter object """
......@@ -418,6 +376,7 @@ class Output(object):
self.__custom_methods_list.append((name, types_info))
@with_custom_members
class Loop(object):
""" Implements the access to temperature regulation loop """
def __init__(self, controller, config):
......@@ -432,10 +391,6 @@ class Loop(object):
self._Ival = None
self._Dval = None
# lists of custom attr and commands
self.__custom_methods_list = list()
self.__custom_attributes_dict = dict()
# useful attribute for a temperature controller writer
self._attr_dict = {}
......@@ -464,21 +419,6 @@ class Loop(object):
""" returns the loop output object """
return self.__output
@property
def custom_methods_list(self):
# Returns a *copy* of the custom methods list.
return self.__custom_methods_list[:]
@property
def custom_attributes_list(self):
ad = self.__custom_attributes_dict
# Converts dict into list...
_attr_list = [(a_name, ad[a_name][0], ad[a_name][1]) for i, a_name in enumerate(ad)]
# Returns a *copy* of the custom attributes list.
return _attr_list[:]
def set(self, new_setpoint=None, wait=False,**kwargs):
""" same as a call to the the method set on its output object """
log.debug(("On Loop: set %s") % new_setpoint)
......@@ -544,10 +484,4 @@ class Loop(object):
return self.controller.read_kd(self)
def _add_custom_method(self, method, name, types_info=(None, None)):
""" necessary to add custom methods to this class """
setattr(self, name, method)
self.__custom_methods_list.append((name, types_info))
......@@ -84,27 +84,7 @@ def object_method_type(method=None, name=None, args=[], types_info=(None, None),
def add_object_attribute(obj, name=None, fget=None, fset=None, args=[], type_info=None, filter=None):
cust_attr_dict = dict()
for aname, a1, a2 in obj.custom_attributes_list:
cust_attr_dict[aname] = (a1, a2)
if cust_attr_dict.get(name):
access_mode = cust_attr_dict[name][1]
if fget and not 'r' in access_mode:
access_mode = "rw"
if fset and not 'w' in access_mode:
access_mode = "rw"
cust_attr_dict[name] = (type_info, access_mode)
else:
if fget:
cust_attr_dict[name] = (type_info, "r")
elif fset:
cust_attr_dict[name] = (type_info, "w")
else:
raise RuntimeError("impossible case: must have fget or fset...")
obj._add_custom_attribute(name, fget, fset, type_info)
"""
decorators for set/get methods to access to custom attributes
......@@ -183,6 +163,69 @@ def set_custom_members(src_obj, target_obj, pre_call=None):
pass
def with_custom_members(klass):
"""A class decorator to enable custom attributes and custom methods"""
def _get_custom_methods(self):
try:
return self.__custom_methods_list
except AttributeError:
self.__custom_methods_list = []
return self.__custom_methods_list
def custom_methods_list(self):
""" Returns a *copy* of the custom methods """
return self._get_custom_methods()[:]
def _add_custom_method(self, method, name, types_info=(None, None)):
setattr(self, name, method)
self._get_custom_methods().append((name, types_info))
def _get_custom_attributes(self):
try:
return self.__custom_attributes_dict
except AttributeError:
self.__custom_attributes_dict = {}
return self.__custom_attributes_dict
def custom_attributes_list(self):
"""
List of custom attributes defined for this axis.
Internal usage only
"""
ad = self._get_custom_attributes()
# Converts dict into list...
return [(a_name, ad[a_name][0], ad[a_name][1]) for a_name in ad]
def _add_custom_attribute(self, name, fget=None, fset=None, type_info=None):
custom_attrs = self._get_custom_attributes()
attr_info = custom_attrs.get(name)
if attr_info:
orig_type_info, access_mode = attr_info
if fget and not 'r' in access_mode:
access_mode = 'rw'
if fset and not 'w' in access_mode:
access_mode = 'rw'
assert type_info == orig_type_info, '%s get/set types mismatch' % name
else:
access_mode = 'r' if fget else ''
access_mode += 'w' if fset else ''
if fget is None and fset is None:
raise RuntimeError("impossible case: must have fget or fset...")
custom_attrs[name] = type_info, access_mode
klass._get_custom_methods = _get_custom_methods
klass.custom_methods_list = property(custom_methods_list)
klass._add_custom_method = _add_custom_method
klass._get_custom_attributes = _get_custom_attributes
klass.custom_attributes_list = property(custom_attributes_list)
klass._add_custom_attribute = _add_custom_attribute
return klass
class Null(object):
__slots__ = []
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment