Synchronizing Python PCellDeclarationHelper between the two implementations (for standalone module + build-in for app)

This commit is contained in:
Matthias Koefferlein 2023-03-07 23:43:12 +01:00
parent 7d0964655d
commit 3e8f03ef5f
2 changed files with 288 additions and 277 deletions

View File

@ -459,7 +459,7 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
def produce(self, layout, layers, parameters, cell): def produce(self, layout, layers, parameters, cell):
""" """
coerce parameters (make consistent) produces the layout
""" """
self.init_values(parameters, layers) self.init_values(parameters, layers)
self.cell = cell self.cell = cell

View File

@ -9,13 +9,12 @@ class _PCellDeclarationHelperLayerDescriptor(object):
def __init__(self, param_index): def __init__(self, param_index):
self.param_index = param_index self.param_index = param_index
def __get__(self, obj, type=None): def __get__(self, obj, type = None):
return obj._layers[self.param_index] return obj._layers[self.param_index]
def __set__(self, obj, value): def __set__(self, obj, value):
raise AttributeError("can't change layer attribute") raise AttributeError("can't change layer attribute")
class _PCellDeclarationHelperParameterDescriptor(object): class _PCellDeclarationHelperParameterDescriptor(object):
""" """
A descriptor object which translates the PCell parameters into class attributes A descriptor object which translates the PCell parameters into class attributes
@ -25,13 +24,16 @@ class _PCellDeclarationHelperParameterDescriptor(object):
the descriptor acts as a value holder (self.value) the descriptor acts as a value holder (self.value)
""" """
def __init__(self, param_index): def __init__(self, param_index, param_name):
self.param_index = param_index self.param_index = param_index
self.param_name = param_name
self.value = None self.value = None
def __get__(self, obj, type=None): def __get__(self, obj, type = None):
if obj._param_values: if obj._param_values:
return obj._param_values[self.param_index] return obj._param_values[self.param_index]
elif obj._param_states:
return obj._param_states.parameter(self.param_name)
else: else:
return self.value return self.value
@ -41,7 +43,6 @@ class _PCellDeclarationHelperParameterDescriptor(object):
else: else:
self.value = value self.value = value
class _PCellDeclarationHelper(PCellDeclaration): class _PCellDeclarationHelper(PCellDeclaration):
""" """
A helper class that somewhat simplifies the implementation A helper class that somewhat simplifies the implementation
@ -55,6 +56,7 @@ class _PCellDeclarationHelper(PCellDeclaration):
# "private" attributes # "private" attributes
self._param_decls = [] self._param_decls = []
self._param_values = None self._param_values = None
self._param_states = None
self._layer_param_index = [] self._layer_param_index = []
self._layers = [] self._layers = []
# public attributes # public attributes
@ -63,17 +65,7 @@ class _PCellDeclarationHelper(PCellDeclaration):
self.layer = None self.layer = None
self.cell = None self.cell = None
def param( def param(self, name, value_type, description, hidden = False, readonly = False, unit = None, default = None, choices = None):
self,
name,
value_type,
description,
hidden=False,
readonly=False,
unit=None,
default=None,
choices=None,
):
""" """
Defines a parameter Defines a parameter
name -> the short name of the parameter name -> the short name of the parameter
@ -94,16 +86,10 @@ class _PCellDeclarationHelper(PCellDeclaration):
# create accessor methods for the parameters # create accessor methods for the parameters
param_index = len(self._param_decls) param_index = len(self._param_decls)
setattr( setattr(type(self), name, _PCellDeclarationHelperParameterDescriptor(param_index, name))
type(self), name, _PCellDeclarationHelperParameterDescriptor(param_index)
)
if value_type == type(self).TypeLayer: if value_type == type(self).TypeLayer:
setattr( setattr(type(self), name + "_layer", _PCellDeclarationHelperLayerDescriptor(len(self._layer_param_index)))
type(self),
name + "_layer",
_PCellDeclarationHelperLayerDescriptor(len(self._layer_param_index)),
)
self._layer_param_index.append(param_index) self._layer_param_index.append(param_index)
# store the parameter declarations # store the parameter declarations
@ -119,17 +105,11 @@ class _PCellDeclarationHelper(PCellDeclaration):
pdecl.unit = unit pdecl.unit = unit
if not (choices is None): if not (choices is None):
if not isinstance(choices, list) and not isinstance(choices, tuple): if not isinstance(choices, list) and not isinstance(choices, tuple):
raise Exception( raise "choices value must be an list/tuple of two-element arrays (description, value)"
"choices value must be an list/tuple of two-element arrays (description, value)"
)
for c in choices: for c in choices:
if ( if (not isinstance(choices, list) and not isinstance(choices, tuple)) or len(c) != 2:
not isinstance(choices, list) and not isinstance(choices, tuple) raise "choices value must be an list/tuple of two-element arrays (description, value)"
) or len(c) != 2: pdecl.add_choice(c[0],c[1])
raise Exception(
"choices value must be an list/tuple of two-element arrays (description, value)"
)
pdecl.add_choice(c[0], c[1])
# return the declaration object for further operations # return the declaration object for further operations
return pdecl return pdecl
@ -139,7 +119,9 @@ class _PCellDeclarationHelper(PCellDeclaration):
implementation of display_text implementation of display_text
""" """
self._param_values = parameters self._param_values = parameters
try:
text = self.display_text_impl() text = self.display_text_impl()
finally:
self._param_values = None self._param_values = None
return text return text
@ -157,7 +139,7 @@ class _PCellDeclarationHelper(PCellDeclaration):
self._param_values = None self._param_values = None
return v return v
def init_values(self, values=None, layers=None): def init_values(self, values = None, layers = None, states = None):
""" """
initializes the temporary parameter values initializes the temporary parameter values
"values" are the original values. If "None" is given, the "values" are the original values. If "None" is given, the
@ -165,7 +147,11 @@ class _PCellDeclarationHelper(PCellDeclaration):
"layers" are the layer indexes corresponding to the layer "layers" are the layer indexes corresponding to the layer
parameters. parameters.
""" """
if not values: self._param_values = None
self._param_states = None
if states:
self._param_states = states
elif not values:
self._param_values = [] self._param_values = []
for pd in self._param_decls: for pd in self._param_decls:
self._param_values.append(pd.default) self._param_values.append(pd.default)
@ -175,40 +161,59 @@ class _PCellDeclarationHelper(PCellDeclaration):
def finish(self): def finish(self):
""" """
Needs to be called at the end of produce() after init_values was used Needs to be called at the end of an implementation
""" """
self._param_values = None self._param_values = None
self._param_states = None
self._layers = None self._layers = None
self._cell = None
self._layout = None
self._layer = None
self._shape = None
def get_layers(self, parameters): def get_layers(self, parameters):
""" """
get the layer definitions gets the layer definitions
""" """
layers = [] layers = []
for i in self._layer_param_index: for i in self._layer_param_index:
layers.append(parameters[i]) layers.append(parameters[i])
return layers return layers
def callback(self, layout, name, states):
"""
callback (change state on parameter change)
"""
self.init_values(states = states)
self.layout = layout
try:
self.callback_impl(name)
finally:
self.finish()
def coerce_parameters(self, layout, parameters): def coerce_parameters(self, layout, parameters):
""" """
coerce parameters (make consistent) coerce parameters (make consistent)
""" """
self.init_values(parameters) self.init_values(parameters)
self.layout = layout self.layout = layout
try:
self.coerce_parameters_impl() self.coerce_parameters_impl()
self.layout = None parameters = self.get_values()
return self.get_values() finally:
self.finish()
return parameters
def produce(self, layout, layers, parameters, cell): def produce(self, layout, layers, parameters, cell):
""" """
coerce parameters (make consistent) produces the layout
""" """
self.init_values(parameters, layers) self.init_values(parameters, layers)
self.cell = cell self.cell = cell
self.layout = layout self.layout = layout
try:
self.produce_impl() self.produce_impl()
self.cell = None finally:
self.layout = None
self.finish() self.finish()
def can_create_from_shape(self, layout, shape, layer): def can_create_from_shape(self, layout, shape, layer):
@ -218,10 +223,10 @@ class _PCellDeclarationHelper(PCellDeclaration):
self.layout = layout self.layout = layout
self.shape = shape self.shape = shape
self.layer = layer self.layer = layer
try:
ret = self.can_create_from_shape_impl() ret = self.can_create_from_shape_impl()
self.layout = None finally:
self.shape = None self.finish()
self.layer = None
return ret return ret
def transformation_from_shape(self, layout, shape, layer): def transformation_from_shape(self, layout, shape, layer):
@ -231,10 +236,10 @@ class _PCellDeclarationHelper(PCellDeclaration):
self.layout = layout self.layout = layout
self.shape = shape self.shape = shape
self.layer = layer self.layer = layer
try:
t = self.transformation_from_shape_impl() t = self.transformation_from_shape_impl()
self.layout = None finally:
self.shape = None self.finish()
self.layer = None
return t return t
def parameters_from_shape(self, layout, shape, layer): def parameters_from_shape(self, layout, shape, layer):
@ -246,11 +251,11 @@ class _PCellDeclarationHelper(PCellDeclaration):
self.layout = layout self.layout = layout
self.shape = shape self.shape = shape
self.layer = layer self.layer = layer
try:
self.parameters_from_shape_impl() self.parameters_from_shape_impl()
param = self.get_values() param = self.get_values()
self.layout = None finally:
self.shape = None self.finish()
self.layer = None
return param return param
def display_text_impl(self): def display_text_impl(self):
@ -265,6 +270,12 @@ class _PCellDeclarationHelper(PCellDeclaration):
""" """
pass pass
def callback_impl(self, name):
"""
default implementation
"""
pass
def produce_impl(self): def produce_impl(self):
""" """
default implementation default implementation
@ -289,11 +300,11 @@ class _PCellDeclarationHelper(PCellDeclaration):
""" """
return Trans() return Trans()
# import the Type... constants from PCellParameterDeclaration # import the Type... constants from PCellParameterDeclaration
for k in dir(PCellParameterDeclaration): for k in dir(PCellParameterDeclaration):
if k.startswith("Type"): if k.startswith("Type"):
setattr(_PCellDeclarationHelper, k, getattr(PCellParameterDeclaration, k)) setattr(_PCellDeclarationHelper, k, getattr(PCellParameterDeclaration, k))
# Inject the PCellDeclarationHelper into pya module for consistency: # Inject the PCellDeclarationHelper into module for consistency:
PCellDeclarationHelper = _PCellDeclarationHelper PCellDeclarationHelper = _PCellDeclarationHelper