diff --git a/sardine_core/handlers/osc.py b/sardine_core/handlers/osc.py index 76eada8c..ece649ec 100644 --- a/sardine_core/handlers/osc.py +++ b/sardine_core/handlers/osc.py @@ -133,3 +133,62 @@ def send( else: serialized = list(chain(*message.items())) self.call_timed_with_nudge(deadline, self._send, f"/{address}", serialized) + + @alias_param(name="iterator", alias="i") + @alias_param(name="divisor", alias="d") + @alias_param(name="rate", alias="r") + @alias_param(name="sorted", alias="s") + def send_pure( + self, + address: Optional[StringElement] | Callable[[], StringElement], + iterator: Number | Callable[[], Number] = 0, + divisor: NumericElement | Callable[[], NumericElement] = 1, + rate: NumericElement | Callable[[], NumericElement] = 1, + sort: bool | Callable[[], bool] = True, + **rest_of_pattern: dict, + ) -> None: + + def _util_flatten(value): + if isinstance(value, (list, tuple)): + return list(value) + else: + return [value] + + if address is None: + return + + if self.apply_conditional_mask_to_bars( + pattern=rest_of_pattern, + ): + return + + pattern = {"address": _resolve_if_callable(address)} + + # Evaluate all potential callables + for key, value in rest_of_pattern.items(): + pattern[key] = _resolve_if_callable(value) + + deadline = self.env.clock.shifted_time + for message in self.pattern_reduce( + pattern, + _resolve_if_callable(iterator), + _resolve_if_callable(divisor), + _resolve_if_callable(rate), + ): + if message["address"] is None: + continue + address = message.pop("address") + if sort: + serialized = list( + chain( + *[ + _util_flatten(value) + for key, value in sorted(message.items()) + ] + ) + ) + else: + serialized = list( + chain(*[_util_flatten(value) for value in message.values()]) + ) + self.call_timed_with_nudge(deadline, self._send, f"/{address}", serialized)