def _callback (self, params): args = [] list = List.from_pointer (ctypes.c_void_p (params)) for val in list: args.append (val.get()) # class method if self._self_object is not None: ret = self._callback_func (self._self_object(), *args) else: ret = self._callback_func (*args) if isinstance (ret, Value): _lib.myelin_value_ref (ret) return ret._ptr else: val = Value() if ret is not None: val.set (ret) _lib.myelin_value_ref (val) return val._ptr
def compute_average(self, where=None): """Similar to 'compute_integral', but - for each material region - divide the result of the integral by the volume of the material region thus obtaining the spatial average.""" integrals = self.compute_integral(where=where, as_value=False) if self.def_on_mat: v = Value() for subfield_name, value in integrals: v.set(subfield_name, value, self.unit / self.volumes[subfield_name]) return v else: assert len(integrals) == 1 subfield_name, value = integrals[0] return Value(value, self.unit / self.volumes[subfield_name])
def compute_integral(self, where=None, as_value=True): ocaml.lam_get_field(self.lam, self.master, self.get_lam_name()) dof_stem = "" if where != None: if type(where) == str: where = [where] dof_stem = ["%s_%s" % (self.name, mat_name) for mat_name in where] raw_result = nfem.integrate_field(self.master, dof_stem) if not as_value: return raw_result u = self.unit * self.volume_unit if self.def_on_mat: v = Value() for mat_name, data in raw_result: v.set(mat_name, data, u) return v else: assert len(raw_result) == 1 name, data = raw_result[0] return Value(data, u)
class Property: """A Property represents an individual state value of a thing.""" def __init__( self, thing, name, initial_value=None, writeproperty=None, readproperty=None, metadata=None, ): """ Initialize the object. thing -- the Thing this property belongs to name -- name of the property writeproperty -- Callable to pass value updates to readproperty -- Callable to obtain the property value metadata -- property metadata, i.e. type, description, unit, etc., as a dict """ self.value = Value( initial_value=initial_value, read_forwarder=readproperty, write_forwarder=writeproperty, ) self.thing = thing self.name = name self.href_prefix = "" self.href = "/properties/{}".format(self.name) self.metadata = metadata if metadata is not None else {} # Add the property change observer to notify the Thing about a property # change. self.value.on("update", lambda _: self.thing.property_notify(self)) def validate_value(self, value): """ Validate new property value before setting it. value -- New value """ if "type" in self.metadata: t = self.metadata["type"] if t == "null": if t is not None: raise PropertyError("Value must be null") elif t == "boolean": if type(value) is not bool: raise PropertyError("Value must be a boolean") elif t == "object": if type(value) is not dict: raise PropertyError("Value must be an object") elif t == "array": if type(value) is not list: raise PropertyError("Value must be an array") elif t == "number": if type(value) not in [float, int]: raise PropertyError("Value must be a number") elif t == "integer": if type(value) is not int: raise PropertyError("Value must be an integer") elif t == "string": if type(value) is not str: raise PropertyError("Value must be a string") if "readOnly" in self.metadata and self.metadata["readOnly"]: raise PropertyError("Read-only property") if "minimum" in self.metadata and value < self.metadata["minimum"]: raise PropertyError("Value less than minimum: {}".format( self.metadata["minimum"])) if "maximum" in self.metadata and value > self.metadata["maximum"]: raise PropertyError("Value greater than maximum: {}".format( self.metadata["maximum"])) if ("enum" in self.metadata and len(self.metadata["enum"]) > 0 and value not in self.metadata["enum"]): raise PropertyError("Invalid enum value") def as_property_description(self): """ Get the property description. Returns a dictionary describing the property. """ description = deepcopy(self.metadata) if "links" not in description: description["links"] = [] description["links"].append({ "rel": "property", "href": self.href_prefix + self.href, }) return description def set_href_prefix(self, prefix): """ Set the prefix of any hrefs associated with this property. prefix -- the prefix """ self.href_prefix = prefix def get_href(self): """ Get the href of this property. Returns the href. """ return self.href_prefix + self.href def get_value(self): """ Get the current property value. Returns the value. """ return self.value.get() def set_value(self, value): """ Set the current value of the property. value -- the value to set """ self.validate_value(value) self.value.set(value) def get_name(self): """ Get the name of this property. Returns the name. """ return self.name def get_thing(self): """Get the thing associated with this property.""" return self.thing def get_metadata(self): """Get the metadata associated with this property.""" return self.metadata
class Register(object): """ Defines a hardware register. """ def __init__(self, address=0, width=32, name=""): self.__address = Value(address) self.__token = Value("") self.__name = Value(name) self.__description = Value("") self.__width = Value(width) self.__nocode = Value(False) self.__dont_test = Value(False) self.__hide = Value(False) self.__bit_fields = {} self.__ram_size = Value(0) def find_first_unused_bit(self): """ Finds the first unused bit in a the register. """ bit = [0] * self.width for field in self.__bit_fields.values(): for val in range(field.start_position, field.stop_position + 1): bit[val] = 1 for pos in range(0, self.width): if bit[pos] == 0: return pos bit = set([]) for field in self.__bit_fields.values(): for val in range(field.start_position, field.stop_position + 1): bit.add(val) all_bits = set(range(0, self.width)) l = sorted(list(bit.difference(all_bits))) if l: return l[0] else: return 0 def find_next_unused_bit(self): """ Finds the first unused bit in a the register. """ bit = set([]) for field in self.__bit_fields.values(): for val in range(field.start_position, field.stop_position + 1): bit.add(val) lbits = sorted(list(bit)) if lbits: if lbits[-1] == self.width - 1: return self.find_first_unused_bit() else: return lbits[-1] + 1 else: return 0 def __set_dont_test(self, val): """ Sets the __dont_test flag. This cannot be accessed directly, but only via the propery 'do_not_test'. """ self.__dont_test.set(val) def __get_dont_test(self): """ Returns the value of the __dont_test flag. This cannot be accessed directly, but only via the property 'do_not_test' """ return self.__dont_test.get() def get_dont_test_obj(self): """ Returns the actual lower level __dont_test object. This is needed to set the modified flag and the last modified time stamp. """ return self.__dont_test do_not_test = property(__get_dont_test, __set_dont_test, None, "Indicates if the register should not be tested " "by automatic tests") def __set_ram_size(self, val): """ Sets __ram_size. This cannot be accessed directly, but only via the propery 'ram_size'. """ self.__ram_size.set(val) def __get_ram_size(self): """ Returns the value of __ram_size. This cannot be accessed directly, but only via the property 'ram_size' """ return self.__ram_size.get() def get_ram_size_obj(self): """ Returns the actual lower level __ram_size object. This is needed to set the modified flag and the last modified time stamp. """ return self.__ram_size ram_size = property(__get_ram_size, __set_ram_size, None, "Indicates if the register is a RAM, and what its" "length is") def __set_hide(self, val): """ Sets the __hide flag . This cannot be accessed directly, but only via the propery 'hide'. """ self.__hide.set(val) def __get_hide(self): """ Returns the value of the __hide flag. This cannot be accessed directly, but only via the property 'hide' """ return self.__hide.get() def get_hide_obj(self): """ Returns the actual lower level __hide object. This is needed to set the modified flag and the last modified time stamp. """ return self.__dont_test hide = property(__get_hide, __set_hide, None, "Indicates if the register should be hidden " "from documentation") def __set_no_code(self, val): """ Sets the __nocode flag. This cannot be accessed directly, but only via the propery 'do_not_generate_code' """ self.__nocode.set(bool(val)) def __get_no_code(self): """ Returns the value of the __nocode flag. This cannot be accessed directly, but only via the property 'do_not_generate_code' """ return self.__nocode.get() def get_no_code_obj(self): """ Returns the actual lower level __nocode object. This is needed to set the modified flag and the last modified time stamp. """ return self.__nocode do_not_generate_code = property(__get_no_code, __set_no_code, None, "Indicates if code generation should be " "suppressed") def __set_token(self, val): """ Sets the __token flag. This cannot be accessed directly, but only via the propery 'token' """ self.__token.set(val.strip().upper()) def __get_token(self): """ Returns the value of the __token flag. This cannot be accessed directly, but only via the property 'token' """ return self.__token.get() def get_token_obj(self): """ Returns the actual lower level __token object. This is needed to set the modified flag and the last modified time stamp. """ return self.__token token = property(__get_token, __set_token, None, "token name of the register") def __set_name(self, name): """ Sets the __name flag. This cannot be accessed directly, but only via the propery 'register_name' """ self.__name.set(name.strip()) def __get_name(self): """ Returns the value of the __name flag. This cannot be accessed directly, but only via the property 'register_name' """ return self.__name.get() def get_name_obj(self): """ Returns the actual lower level __name object. This is needed to set the modified flag and the last modified time stamp. """ return self.__name register_name = property(__get_name, __set_name, None, "Name of the register") def __set_address(self, addr): """ Sets the __address flag. This cannot be accessed directly, but only via the propery 'address' """ self.__address.set(addr) def __get_address(self): """ Returns the value of the __address flag. This cannot be accessed directly, but only via the property 'address' """ return self.__address.get() def get_address_obj(self): """ Returns the actual lower level __address object. This is needed to set the modified flag and the last modified time stamp. """ return self.__address address = property(__get_address, __set_address, None, "Address of the register") def __set_description(self, description): """ Sets the __description flag. This cannot be accessed directly, but only via the propery 'Description' """ self.__description.set(description) def __get_description(self): """ Returns the value of the __description flag. This cannot be accessed directly, but only via the property 'description' """ return self.__description.get() def get_description_obj(self): """ Returns the actual lower level __description object. This is needed to set the modified flag and the last modified time stamp. """ return self.__description description = property(__get_description, __set_description, None, "description of the register") def __set_width(self, width): """ Sets the __width flag. This cannot be accessed directly, but only via the propery 'width' """ self.__width.set(width) def __get_width(self): """ Returns the value of the __width flag. This cannot be accessed directly, but only via the property 'width' """ return self.__width.get() def get_width_obj(self): """ Returns the actual lower level __width object. This is needed to set the modified flag and the last modified time stamp. """ return self.__width width = property(__get_width, __set_width, None, "Width of the register") def get_bit_fields(self): """ Returns a dictionary of bit fields. The key is stop_position of the bit field. """ return self.__bit_fields.values() def get_bit_field(self, key): """ Returns the bit field associated with the specified key. """ return self.__bit_fields.get(key) def get_bit_field_keys(self): """ Returns the list of keys associated with the bit fields """ return sorted(self.__bit_fields.keys()) def add_bit_field(self, field): """ Adds a bit field to the set of bit fields. """ self.__bit_fields[field.stop_position] = field def delete_bit_field(self, field): """ Removes the specified bit field from the dictionary. We cannot use the stop_position, since it may have changed. """ for key in self.__bit_fields.keys(): if self.__bit_fields[key] == field: del self.__bit_fields[key]