refactor levels.

only compute strip/bus comp tuples if ldirty.

add comp generator function to util.

added some docstrings

patch bump
This commit is contained in:
onyx-and-iris 2022-07-09 11:06:48 +01:00
parent 210c75ed5f
commit e979595a09
5 changed files with 67 additions and 28 deletions

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "voicemeeter-api"
version = "0.2.2"
version = "0.2.3"
description = "A Python wrapper for the Voiceemeter API"
authors = ["onyx-and-iris <code@onyxandiris.online>"]
license = "MIT"

View File

@ -9,7 +9,7 @@ from .cbindings import CBindings
from .error import VMError
from .kinds import KindId
from .subject import Subject
from .util import polling, script
from .util import comp, polling, script
class Remote(CBindings):
@ -44,7 +44,13 @@ class Remote(CBindings):
t.start()
def _updates(self):
"""Continously update observers of dirty states."""
"""
Continously update observers of dirty states.
Generate _strip_comp, _bus_comp and update level cache if ldirty.
Runs updates at a rate of self.ratelimit.
"""
self.cache["strip_level"], self.cache["bus_level"] = self._get_levels()
while self.running:
@ -53,6 +59,12 @@ class Remote(CBindings):
if self.mdirty:
self.subject.notify("mdirty")
if self.ldirty:
self._strip_comp, self._bus_comp = (
tuple(
not x for x in comp(self.cache["strip_level"], self._strip_buf)
),
tuple(not x for x in comp(self.cache["bus_level"], self._bus_buf)),
)
self.cache["strip_level"] = self._strip_buf
self.cache["bus_level"] = self._bus_buf
self.subject.notify("ldirty")
@ -110,16 +122,10 @@ class Remote(CBindings):
def ldirty(self) -> bool:
"""True iff levels have been updated."""
self._strip_buf, self._bus_buf = self._get_levels()
self._strip_comp, self._bus_comp = (
tuple(
not a == b
for a, b in zip(self.cache.get("strip_level"), self._strip_buf)
),
tuple(
not a == b for a, b in zip(self.cache.get("bus_level"), self._bus_buf)
),
return not (
self.cache.get("strip_level") == self._strip_buf
and self.cache.get("bus_level") == self._bus_buf
)
return any(any(l) for l in (self._strip_comp, self._bus_comp))
def clear_dirty(self):
while self.pdirty or self.mdirty:

View File

@ -116,16 +116,21 @@ class BusLevel(IRemote):
self.range = self.level_map[self.index]
def getter(self, mode):
"""Returns a tuple of level values for the channel."""
"""
Returns a tuple of level values for the channel.
If observables thread running fetch values from cache otherwise call CAPI func.
"""
def fget(i):
if self._remote.running and "bus_level" in self._remote.cache:
res = self._remote.cache["bus_level"][i]
else:
res = self._remote.get_level(mode, i)
return round(20 * log(res, 10), 1) if res > 0 else -200.0
return round(20 * log(i, 10), 1) if i > 0 else -200.0
return tuple(fget(i) for i in range(*self.range))
if self._remote.running and "bus_level" in self._remote.cache:
vals = self._remote.cache["bus_level"][self.range[0] : self.range[-1]]
else:
vals = [self._remote.get_level(mode, i) for i in range(*self.range)]
return tuple(fget(i) for i in vals)
@property
def identifier(self) -> str:
@ -137,6 +142,12 @@ class BusLevel(IRemote):
@property
def is_updated(self) -> bool:
"""
Returns dirty status for this specific channel.
Expected to be used in a callback only.
"""
if self._remote.running:
return any(self._remote._bus_comp[self.range[0] : self.range[-1]])

View File

@ -189,16 +189,21 @@ class StripLevel(IRemote):
self.range = self.level_map[self.index]
def getter(self, mode):
"""Returns a tuple of level values for the channel."""
"""
Returns a tuple of level values for the channel.
If observables thread running fetch values from cache otherwise call CAPI func.
"""
def fget(i):
if self._remote.running and "strip_level" in self._remote.cache:
res = self._remote.cache["strip_level"][i]
else:
res = self._remote.get_level(mode, i)
return round(20 * log(res, 10), 1) if res > 0 else -200.0
return round(20 * log(i, 10), 1) if i > 0 else -200.0
return tuple(fget(i) for i in range(*self.range))
if self._remote.running and "strip_level" in self._remote.cache:
vals = self._remote.cache["strip_level"][self.range[0] : self.range[-1]]
else:
vals = [self._remote.get_level(mode, i) for i in range(*self.range)]
return tuple(fget(i) for i in vals)
@property
def identifier(self) -> str:
@ -221,6 +226,12 @@ class StripLevel(IRemote):
@property
def is_updated(self) -> bool:
"""
Returns dirty status for this specific channel.
Expected to be used in a callback only.
"""
if self._remote.running:
return any(self._remote._strip_comp[self.range[0] : self.range[-1]])

View File

@ -1,4 +1,5 @@
import functools
from typing import Iterator
def polling(func):
@ -50,3 +51,13 @@ def script(func):
return func(remote, script)
return wrapper
def comp(t0: tuple, t1: tuple) -> Iterator[bool]:
"""
Generator function, accepts two tuples.
Evaluates equality of each member in both tuples.
"""
for a, b in zip(t0, t1):
yield a == b