consistency; sdr and profile name updates working

This commit is contained in:
Jakob Ketterl 2023-05-09 19:42:43 +02:00
parent 8a588270f6
commit 6ad9ddbf19
2 changed files with 69 additions and 18 deletions

View file

@ -50,9 +50,6 @@ class ActiveListTransformation(ABC):
def transform(self, value):
pass
def __call__(self, *args, **kwargs):
return self.transform(*args, **kwargs)
def monitor(self, member, callback: callable):
pass
@ -60,26 +57,38 @@ class ActiveListTransformation(ABC):
pass
class BasicTransformation(ActiveListTransformation):
def __init__(self, transformation: callable):
self.transformation = transformation
def transform(self, value):
return self.transformation(value)
class ActiveListTransformationListener(ActiveListListener):
def __init__(self, transformation: callable, source: "ActiveList", target: "ActiveList"):
def __init__(self, transformation: ActiveListTransformation, source: "ActiveList", target: "ActiveList"):
self.transformation = transformation
self.source = source
self.target = target
if isinstance(transformation, ActiveListTransformation):
for idx, v in enumerate(self.source):
transformation.monitor(v, partial(self._onMonitor, idx))
for v in self.source:
transformation.monitor(v, partial(self._onMonitor, v))
def onListChange(self, source: "ActiveList", changes: list[ActiveListChange]):
for change in changes:
if isinstance(change, ActiveListIndexUpdated):
self.target[change.index] = self.transformation(change.newValue)
self.transformation.unmonitor(change.oldValue)
self.target[change.index] = self.transformation.transform(change.newValue)
self.transformation.monitor(change.newValue, partial(self._onMonitor, change.newValue))
elif isinstance(change, ActiveListIndexAdded):
self.target.insert(change.index, self.transformation(change.newValue))
self.target.insert(change.index, self.transformation.transform(change.newValue))
self.transformation.monitor(change.newValue, partial(self._onMonitor, change.newValue))
elif isinstance(change, ActiveListIndexDeleted):
del self.target[change.index]
self.transformation.unmonitor(change.oldValue)
def _onMonitor(self, idx):
self.target[idx] = self.transformation(self.source[idx])
def _onMonitor(self, value):
idx = self.source.index(value)
self.target[idx] = self.transformation.transform(self.source[idx])
class ActiveListFilterListener(ActiveListListener):
@ -133,12 +142,16 @@ class ActiveListFlattenListener(ActiveListListener):
idx = self.getOffsetForIndex(change.index)
for n, v in enumerate(change.newValue):
self.target.insert(idx + n, v)
change.newValue.addListener(self)
elif isinstance(change, ActiveListIndexUpdated):
change.oldValue.removeListener(self)
idx = self.getOffsetForIndex(change.index)
del self.target[idx, idx + len(change.oldValue)]
for n, v in enumerate(change.newValue):
self.target.insert(idx + n, v)
change.newValue.addListener(self)
elif isinstance(change, ActiveListIndexDeleted):
change.oldValue.removeListener(self)
idx = self.getOffsetForIndex(change.index)
del self.target[idx, idx + len(change.oldValue)]
else:
@ -186,9 +199,11 @@ class ActiveList:
def index(self, value):
return self.delegate.index(value)
def map(self, transform: Union[callable, ActiveListTransformation]):
res = ActiveList([transform(v) for v in self])
self.addListener(ActiveListTransformationListener(transform, self, res))
def map(self, transformation: Union[callable, ActiveListTransformation]):
if not isinstance(transformation, ActiveListTransformation):
transformation = BasicTransformation(transformation)
res = ActiveList([transformation.transform(v) for v in self])
self.addListener(ActiveListTransformationListener(transformation, self, res))
return res
def filter(self, filter: callable):

View file

@ -1,12 +1,51 @@
from owrx.config import Config
from owrx.source import SdrSource
from owrx.feature import FeatureDetector, UnknownFeatureException
from owrx.active.list import ActiveListTransformation
import logging
logger = logging.getLogger(__name__)
class ProfileNameMapper(ActiveListTransformation):
def __init__(self, source_id, source_name):
self.source_id = source_id
self.source_name = source_name
self.subscriptions = []
def transform(self, profile):
return {"id": "{}|{}".format(self.source_id, profile["id"]), "name": "{} {}".format(self.source_name, profile["name"])}
def monitor(self, profile, callback: callable):
self.subscriptions.append(profile.filter("name").wire(lambda _: callback()))
def unmonitor(self, member):
affected = [sub for sub in self.subscriptions if sub.subscriptee is member]
logger.debug("removing %i affected subs", len(affected))
for sub in affected:
sub.cancel()
self.subscriptions.remove(sub)
class ProfileMapper(ActiveListTransformation):
def __init__(self):
self.subscriptions = []
def transform(self, source):
return source.getProfiles().map(ProfileNameMapper(source.getId(), source.getName()))
def monitor(self, source, callback: callable):
self.subscriptions.append(source.getProps().filter("name").wire(lambda _: callback()))
def unmonitor(self, member):
affected = [sub for sub in self.subscriptions if sub.subscriptee is member]
logger.debug("removing %i affected subs", len(affected))
for sub in affected:
sub.cancel()
self.subscriptions.remove(sub)
class SdrService(object):
sources = None
activeSources = None
@ -84,11 +123,8 @@ class SdrService(object):
@staticmethod
def getAvailableProfiles():
def buildProfiles(source):
return source.getProfiles().map(lambda profile: {"id": "{}|{}".format(source.getId(), profile["id"]), "name": "{} {}".format(source.getName(), profile["name"])})
if SdrService.availableProfiles is None:
SdrService.availableProfiles = SdrService.getActiveSources().map(buildProfiles).flatten()
SdrService.availableProfiles = SdrService.getActiveSources().map(ProfileMapper()).flatten()
return SdrService.availableProfiles
@staticmethod