def build_call(i, ex, args, meta_args): func = create_func(meta_args.declaration) spec = signature(func) for name, parameter in spec.parameters.items(): if parameter.annotation is parameter.empty: raise ValueError("Expected annotation for parameter '{}'".format(name)) attr = hive.attribute(parameter.annotation) pull_in = hive.pull_in(attr) antenna = hive.antenna(pull_in) setattr(i, name, attr) setattr(i, "pull_{}".format(name), pull_in) setattr(ex, name, antenna) wrapped_func = create_wrapper_func(meta_args.declaration, spec.parameters) i.modifier = hive.modifier(wrapped_func) return_type = spec.return_annotation if return_type is spec.empty: raise ValueError("Expected annotation for return parameter") i.result = hive.attribute(return_type) i.pull_result = hive.pull_out(i.result) ex.result = hive.output(i.pull_result) hive.trigger(i.pull_result, i.modifier, pretrigger=True)
def build_operator(i, ex, args, meta_args): """HIVE interface to python mathematical operators""" assert meta_args.operator in operators op = operators[meta_args.operator] i.a = hive.attribute(meta_args.data_type) i.b = hive.attribute(meta_args.data_type) i.pull_a = hive.pull_in(i.a) ex.a = hive.antenna(i.pull_a) i.pull_b = hive.pull_in(i.b) ex.b = hive.antenna(i.pull_b) hive.trigger(i.pull_a, i.pull_b) i.result = hive.attribute(meta_args.data_type) i.pull_result = hive.pull_out(i.result) ex.result = hive.output(i.pull_result) def calc(self): self._result = op(self._a, self._b) i.run_operator = hive.modifier(calc) hive.trigger(i.pull_a, i.run_operator) hive.trigger(i.pull_result, i.pull_a, pretrigger=True)
def build_foreach(i, ex, args, meta_args): """Iterate over iterable object""" # Set iterable i.iterable = hive.attribute() i.pull_iterable = hive.pull_in(i.iterable) ex.iterable = hive.antenna(i.pull_iterable) i.do_trig = hive.triggerfunc() i.trig_in = hive.triggerable(i.do_trig) ex.start = hive.entry(i.trig_in) i.break_ = hive.attribute('bool', False) i.item = hive.attribute(meta_args.data_type) i.push_item = hive.push_out(i.item) ex.item = hive.output(i.push_item) i.index = hive.attribute('int', 0) i.pull_index = hive.pull_out(i.index) ex.index = hive.output(i.pull_index) i.finished = hive.triggerfunc() i.do_break = hive.modifier(do_break) ex.break_ = hive.entry(i.do_break) ex.finished = hive.hook(i.finished) i.iter = hive.modifier(do_iter) hive.trigger(i.do_trig, i.pull_iterable) hive.trigger(i.do_trig, i.iter)
def build_decompose(i, ex, args): """Decompose complex number into real and imaginary components""" i.value = hive.attribute('complex') i.real = hive.attribute('float') i.imag = hive.attribute('float') i.pull_imag = hive.pull_out(i.imag) i.pull_real = hive.pull_out(i.real) ex.real = hive.output(i.pull_real) ex.imag = hive.output(i.pull_imag) i.pull_value = hive.pull_in(i.value) ex.value = hive.antenna(i.pull_value) def build_value(self): value = self._value self._real = value.real self._imag = value.imag i.build_value = hive.modifier(build_value) hive.trigger(i.pull_imag, i.pull_value, pretrigger=True) hive.trigger(i.pull_real, i.pull_value, pretrigger=True) hive.trigger(i.pull_value, i.build_value)
def build_expression(i, ex, args, meta_args): """Execute bound expression for provided inputs and output result""" ast_node = ast.parse(meta_args.expression, mode='eval') visitor = NodeVisitor() visitor.visit(ast_node) visited_nodes = visitor.visited_nodes variable_names = [x.id for x in visited_nodes if isinstance(x, ast.Name)] i.result = hive.attribute(meta_args.result_type) i.pull_result = hive.pull_out(i.result) ex.result = hive.output(i.pull_result) for name in variable_names: attribute = hive.attribute() setattr(i, name, attribute) pull_in = hive.pull_in(attribute) setattr(ex, name, hive.antenna(pull_in)) hive.trigger(i.pull_result, pull_in, pretrigger=True) func = create_func(meta_args.expression, variable_names) i.modifier = hive.modifier(func) hive.trigger(i.pull_result, i.modifier, pretrigger=True)
def build_attr(i, ex, args, meta_args): """Set/get attribute on object""" i.name = hive.attribute("str") i.value = hive.attribute(meta_args.attribute_type) i.object_ = hive.attribute(meta_args.object_type) i.pull_name = hive.pull_in(i.name) i.pull_object = hive.pull_in(i.object_) ex.object_ = hive.antenna(i.pull_object) ex.name = hive.antenna(i.pull_name) if meta_args.mode == "set": i.push_value = hive.push_in(i.value) ex.value = hive.antenna(i.push_value) i.do_set_attr = hive.modifier(do_setattr) hive.trigger(i.push_value, i.pull_object) hive.trigger(i.pull_object, i.pull_name) hive.trigger(i.pull_name, i.do_set_attr) else: i.pull_value = hive.pull_out(i.value) ex.value = hive.output(i.pull_value) i.do_get_attr = hive.modifier(do_getattr) hive.trigger(i.pull_value, i.pull_object, pretrigger=True) hive.trigger(i.pull_object, i.pull_name) hive.trigger(i.pull_name, i.do_get_attr)
def build_set(i, ex, args): """Perform set operation on two sets""" i.a = hive.attribute('set') i.pull_a = hive.pull_in(i.a) ex.a = hive.antenna(i.pull_a) i.b = hive.attribute('set') i.pull_b = hive.pull_in(i.b) ex.b = hive.antenna(i.pull_b) i.result = hive.attribute('set') for op_name, op in SET_SET_OPERATIONS.items(): pull_op = hive.pull_out(i.result) setattr(i, "pull_{}".format(op_name), pull_op) setattr(ex, op_name, hive.output(pull_op)) def do_operation(self): self._result = op(self._a, self._b) mod = hive.modifier(do_operation) setattr(i, "do_{}".format(op_name), mod) hive.trigger(pull_op, i.pull_a, pretrigger=True) hive.trigger(pull_op, mod, pretrigger=True) hive.trigger(i.pull_a, i.pull_b)
def build_and(i, ex, args): ex.a_value = hive.attribute(("bool", ), False) ex.b_value = hive.attribute(("bool", ), False) i.a = hive.pull_in(ex.a_value) i.b = hive.pull_in(ex.b_value) ex.a = hive.antenna(i.a) ex.b = hive.antenna(i.b) def on_and(h): h._pull_inputs() if h.a_value and h.b_value: h.trig_out() i.trig_out = hive.triggerfunc() i.trig_in = hive.modifier(on_and) # Update attributes before calling modifier i.pull_inputs = hive.triggerfunc() hive.trigger(i.pull_inputs, i.a, pretrigger=True) hive.trigger(i.pull_inputs, i.b, pretrigger=True) ex.trig_out = hive.hook(i.trig_out) ex.trig_in = hive.entry(i.trig_in)
def build_item(i, ex, args, meta_args): """Set/get item in object""" i.name = hive.attribute(meta_args.index_type) i.value = hive.attribute(meta_args.item_type) i.container_ = hive.attribute(meta_args.container_type) i.pull_name = hive.pull_in(i.name) i.pull_container = hive.pull_in(i.container_) ex.container_ = hive.antenna(i.pull_container) ex.name = hive.antenna(i.pull_name) if meta_args.mode == "set": i.push_value = hive.push_in(i.value) ex.value = hive.antenna(i.push_value) i.do_set_attr = hive.modifier(do_setitem) hive.trigger(i.push_value, i.pull_container) hive.trigger(i.pull_container, i.pull_name) hive.trigger(i.pull_name, i.do_set_attr) else: i.pull_value = hive.pull_out(i.value) ex.value = hive.output(i.pull_value) i.do_get_attr = hive.modifier(do_getitem) hive.trigger(i.pull_value, i.pull_container, pretrigger=True) hive.trigger(i.pull_container, i.pull_name) hive.trigger(i.pull_name, i.do_get_attr)
def build_unpack_tuple(i, ex, args, meta_args): """Unpack a tuple from individual inputs""" i.tuple_ = hive.attribute('tuple') i.push_tuple = hive.push_in(i.tuple_) ex.tuple_ = hive.antenna(i.push_tuple) for index, data_type in enumerate(meta_args.types): attr = hive.attribute(data_type) setattr(i, "attr_{}".format(index), attr) pull_out = hive.pull_out(attr) setattr(i, "pull_out_{}".format(index), pull_out) setattr(ex, "item_{}".format(index), hive.output(pull_out)) def do_unpack_tuple(self): tuple_ = self._tuple_ data_types = meta_args.types assert len(tuple_) == len(data_types) for index, item in enumerate(tuple_): setattr(self, "_attr_{}".format(index), item) i.do_unpack_tuple = hive.modifier(do_unpack_tuple) hive.trigger(i.push_tuple, i.do_unpack_tuple)
def build_range(i, ex, args): """A range iterator hive""" i.min_value = hive.attribute("int") i.max_value = hive.attribute("int") i.step = hive.attribute("int") i.pull_min_value = hive.pull_in(i.min_value) i.pull_max_value = hive.pull_in(i.max_value) i.pull_step = hive.pull_in(i.step) ex.min_value = hive.antenna(i.pull_min_value) ex.max_value = hive.antenna(i.pull_max_value) ex.step = hive.antenna(i.pull_step) i.iterator = hive.attribute("int") def get_range(self): self._iterator = range(self._min_value, self._max_value, self._step) i.get_range = hive.modifier(get_range) i.pull_iterator = hive.pull_out(i.iterator, "iterator") ex.iterator = hive.output(i.pull_iterator) hive.trigger(i.pull_iterator, i.pull_min_value, pretrigger=True) hive.trigger(i.pull_iterator, i.pull_max_value, pretrigger=True) hive.trigger(i.pull_iterator, i.pull_step, pretrigger=True) hive.trigger(i.pull_iterator, i.get_range, pretrigger=True)
def build_determinant(i, ex, args): """Calculate the determinant (length) of a vector""" i.vector = hive.attribute("vector") i.pull_vector = hive.pull_in(i.vector) ex.vector = hive.antenna(i.pull_vector) i.result = hive.attribute("float") i.pull_result = hive.pull_out(i.result) ex.result = hive.output(i.pull_result) i.calculate = hive.modifier(length_modifier) hive.trigger(i.pull_result, i.calculate, pretrigger=True)
def build_normalise(i, ex, args): """Find the unit vector for a given vector""" i.vector = hive.attribute("vector") i.pull_vector = hive.pull_in(i.vector) ex.vector = hive.antenna(i.pull_vector) i.result = hive.attribute("vector") i.pull_result = hive.pull_out(i.result) ex.result = hive.output(i.pull_result) i.calculate = hive.modifier(normalise_modifier) hive.trigger(i.pull_result, i.calculate, pretrigger=True)
def build_generator(i, ex, args): """Define and instantiate a new generator when pulled""" args.generator_body = hive.parameter(("str", "code")) ex.generator = hive.attribute() ex.generator_body = hive.attribute(("str", "code"), args.generator_body) i.create_generator = hive.modifier(on_new_generator) i.generator_out = hive.pull_out(ex.generator) ex.generator_out = hive.output(i.generator_out) hive.trigger(i.generator_out, i.create_generator, pretrigger=True)
def build_apply(i, ex, args, meta_args): """Call callable object with provided inputs and output result""" i.callable = hive.attribute(("object", "callable")) i.pull_callable = hive.pull_in(i.callable) ex.callable = hive.antenna(i.pull_callable) i.modifier = hive.modifier(modifier) i.result = hive.attribute(meta_args.result_type) i.pull_result = hive.pull_out(i.result) ex.result = hive.output(i.pull_result) hive.trigger(i.pull_result, i.pull_callable, pretrigger=True) hive.trigger(i.pull_result, i.modifier, pretrigger=True)
def build_format(i, ex, args, meta_args): """Interface to Python string value formatting""" formatter = string.Formatter() format_string = meta_args.format_string fields = list(formatter.parse(format_string)) kwarg_fields = [] indexed_fields = [] i.result = hive.attribute('str') i.result_out = hive.pull_out(i.result) for index, field in enumerate(fields): literal_text = field[1] if literal_text is None: continue if not literal_text.isidentifier(): field_name = "field_{}".format(index) indexed_fields.append(field_name) else: field_name = literal_text kwarg_fields.append(field_name) # Create IO attr = hive.attribute() setattr(i, field_name, attr) in_attr = hive.pull_in(attr) setattr(i, "{}_in".format(field_name), in_attr) setattr(ex, field_name, hive.antenna(in_attr)) hive.trigger(i.result_out, in_attr, pretrigger=True) ex.result = hive.output(i.result_out) def do_format(self): args = [ getattr(self, "_{}".format(attr_name)) for attr_name in indexed_fields ] kwargs = { attr_name: getattr(self, "_{}".format(attr_name)) for attr_name in kwarg_fields } self._result = formatter.format(format_string, *args, **kwargs) i.func = hive.modifier(do_format) hive.trigger(i.result_out, i.func, pretrigger=True)
def build_keyboard(cls, i, ex, args): ex.on_event = hive.socket(cls.add_single_listener, identifier="event.add_handler") i.on_tick = hive.triggerfunc() ex.name = hive.attribute(("str", ), "<Sensor>") ex.key = hive.property(cls, "key", "str") ex.is_positive = hive.attribute(("bool", ), False) i.positive = hive.pull_out(ex.is_positive) ex.positive = hive.output(i.positive) i.trig_out = hive.triggerfunc() ex.trig_out = hive.hook(i.trig_out)
def build_import(i, ex, args): """Interface to python import mechanism""" i.do_import = hive.modifier(do_import_from_path) i.import_path = hive.attribute("str") i.pull_import_path = hive.pull_in(i.import_path) ex.import_path = hive.antenna(i.pull_import_path) i.module = hive.attribute("module") i.pull_module = hive.pull_out(i.module) ex.module = hive.output(i.pull_module) hive.trigger(i.pull_module, i.pull_import_path, pretrigger=True) hive.trigger(i.pull_module, i.do_import, pretrigger=True)
def build_len(i, ex, args): """Determine length of object""" i.object = hive.attribute() i.pull_object = hive.pull_in(i.object) ex.object = hive.antenna(i.pull_object) i.length = hive.attribute('int') i.pull_length = hive.pull_out(i.length) ex.length = hive.output(i.pull_object) i.do_length = hive.modifier(do_len) hive.trigger(i.pull_length, i.pull_object, pretrigger=True) hive.trigger(i.pull_object, i.do_length)
def build_iter(i, ex, args, meta_args): """Create iterator for object""" i.iterable = hive.attribute() i.pull_iterable = hive.pull_in(i.iterable) ex.iterable = hive.antenna(i.pull_iterable) i.iterator = hive.attribute("iterator") i.pull_iterator = hive.pull_out(i.iterator) ex.iterator = hive.output(i.pull_iterator) i.do_iter = hive.modifier(do_iter) hive.trigger(i.pull_iterator, i.pull_iterable, pretrigger=True) hive.trigger(i.pull_iterable, i.do_iter)
def build_always(i, ex, args): ex.name = hive.attribute(("str", ), "<Sensor>") ex.is_positive = hive.attribute(("bool", ), True) i.positive = hive.pull_out(ex.is_positive) ex.positive = hive.output(i.positive) def trigger(h): h.trig_out() i.trig_in = hive.modifier(trigger) ex.trig_in = hive.entry(i.trig_in) i.trig_out = hive.triggerfunc() ex.trig_out = hive.hook(i.trig_out)
def build_set(i, ex, args, meta_args): """Perform set operation on single sets""" i.set_ = hive.attribute('set', set()) i.pull_set_ = hive.pull_out(i.set_) ex.set_out = hive.output(i.pull_set_) i.push_set_ = hive.push_in(i.set_) ex.set_ = hive.antenna(i.push_set_) # Pop item i.popped_item = hive.attribute(meta_args.data_type) i.pull_pop = hive.pull_out(i.popped_item) ex.pop = hive.output(i.pull_pop) def do_pop(self): self._popped_item = self._set_.pop() i.do_pop = hive.modifier(do_pop) hive.trigger(i.pull_pop, i.do_pop, pretrigger=True) # Add item i.to_add = hive.attribute(meta_args.data_type) i.push_to_add = hive.push_in(i.to_add) ex.add = hive.antenna(i.push_to_add) def to_add(self): self._set_.add(self._to_add) i.do_add = hive.modifier(to_add) hive.trigger(i.push_to_add, i.do_add) # Remove item i.to_remove = hive.attribute(meta_args.data_type) i.push_to_remove = hive.push_in(i.to_remove) ex.remove = hive.antenna(i.push_to_remove) def do_remove(self): self._set_.remove(self._to_remove) i.do_remove = hive.modifier(do_remove) hive.trigger(i.push_to_remove, i.do_remove) def do_clear(self): self._set_.clear() i.do_clear = hive.modifier(do_clear) ex.clear = hive.entry(i.do_clear)
def build_decompose(i, ex, args): """Decompose a vector into its x, y and z components""" i.refresh = hive.modifier(decompose_modifier) for name in ['x', 'y', 'z']: attr = hive.attribute("float") setattr(i, name, attr) pull_out = hive.pull_out(attr) setattr(ex, name, hive.output(pull_out)) hive.trigger(pull_out, i.refresh, pretrigger=True) i.vector = hive.attribute("vector") i.pull_vector = hive.pull_in(i.vector) ex.vector = hive.antenna(i.pull_vector)
def build_next(i, ex, args, meta_args): """Iterate over generator object, output new value when pulled""" i.iterator = hive.attribute("iterator") i.iterator_in = hive.pull_in(i.iterator) ex.iterator = hive.antenna(i.iterator_in) i.pull_iterator = hive.triggerfunc() hive.trigger(i.pull_iterator, i.iterator_in) i.result = hive.attribute(meta_args.data_type) i.pull_value = hive.pull_out(i.result) ex.value = hive.output(i.pull_value) i.do_next = hive.modifier(next_modifier) hive.trigger(i.pull_value, i.do_next, pretrigger=True)
def build_buffer(i, ex, args, meta_args): """Store the input value and output saved value. In pull mode, the trigger is used to update the internal value. In push mode, the trigger is used to output the internal value. Can be used to cache changing values """ args.start_value = hive.parameter(meta_args.data_type, None) i.cached_value = hive.attribute(meta_args.data_type, args.start_value) if meta_args.mode == "push": i.push_value = hive.push_in(i.cached_value) ex.value = hive.antenna(i.push_value) i.push_cached_value = hive.push_out(i.cached_value) ex.cached_value = hive.output(i.push_cached_value) ex.output = hive.entry(i.push_cached_value) elif meta_args.mode == "pull": i.pull_value = hive.pull_in(i.cached_value) ex.value = hive.antenna(i.pull_value) i.pull_cached_value = hive.pull_out(i.cached_value) ex.cached_value = hive.output(i.pull_cached_value) ex.update_cache = hive.entry(i.pull_value)
def build_debug(i, ex, args): def on_call(h): print(h.message) ex.message = hive.attribute(("str", ), "Triggered!") i.trig_in = hive.modifier(on_call) ex.trig_in = hive.entry(i.trig_in)
def build_cross(i, ex, args): """Calculate the cross product between two vectors""" i.a = hive.attribute("vector") i.b = hive.attribute("vector") pull_a = hive.pull_in(i.a) pull_b = hive.pull_in(i.b) ex.a = hive.antenna(pull_a) ex.b = hive.antenna(pull_b) i.result = hive.attribute("vector") i.pull_result = hive.pull_out(i.result) ex.result = hive.output(i.pull_result) calculate = hive.modifier(cross_modifier) hive.trigger(i.pull_result, calculate, pretrigger=True)
def build_input(i, ex, args): """Get input from Python stdin""" args.message = hive.parameter("str", "") ex.message = hive.attribute("str", args.message) i.message_in = hive.push_in(ex.message) ex.message_in = hive.antenna(i.message_in) ex.value = hive.attribute("str") i.value_out = hive.pull_out(ex.value) ex.value_out = hive.output(i.value_out) def get_input(self): self.value = input(self.message) i.get_input = hive.modifier(get_input) hive.trigger(i.value_out, i.get_input, pretrigger=True)
def build_loads(i, ex, args): """Interface to JSON loads function""" def do_loads(self): self._result = loads(self._object_) i.result = hive.attribute('str') i.object_ = hive.attribute() i.pull_result = hive.pull_out(i.result) ex.result = hive.output(i.pull_result) i.pull_object = hive.pull_in(i.object_) ex.object_ = hive.antenna(i.pull_object) i.do_loads = hive.modifier(do_loads) hive.trigger(i.pull_result, i.pull_object, pretrigger=True) hive.trigger(i.pull_object, i.do_loads)
def build_compose(i, ex, args): """Compose a euler from its x, y and z components""" i.compose_vector = hive.modifier(compose_modifier) i.result = hive.attribute("euler") i.pull_result = hive.pull_out(i.result) for name in ('x', 'y', 'z'): attr = hive.attribute("float") setattr(i, name, attr) pull_in = hive.pull_in(attr) setattr(ex, "{}".format(name), hive.antenna(pull_in)) hive.trigger(i.pull_result, pull_in, pretrigger=True) hive.trigger(i.pull_result, i.compose_vector, pretrigger=True) ex.result = hive.output(i.pull_result)