Files @ 8c82f13a3298
Branch filter:

Location: light9/light9/effect/sequencer/eval_faders.py

drewp@bigasterisk.com
rm or repair dead code (notes could come back)
import logging
import time
from dataclasses import dataclass
from typing import List, Optional, cast

from prometheus_client import Summary

from rdfdb import SyncedGraph
from rdflib import URIRef
from rdflib.term import Node

from light9.effect import effecteval
from light9.effect.settings import DeviceSettings, EffectSettings
from light9.metrics import metrics
from light9.namespaces import L9, RDF
from light9.newtypes import EffectAttr, EffectUri, UnixTime
from light9.typedgraph import typedValue

log = logging.getLogger('seq.fader')

COMPILE=Summary('compile_graph_fader', '')

@dataclass
class Fader:
    graph: SyncedGraph
    uri: URIRef
    effect: EffectUri
    setEffectAttr: EffectAttr

    value: Optional[float]=None # mutable

    def __post_init__(self):
        self.ee = effecteval.EffectEval2(self.graph, self.effect)

class FaderEval:
    """peer to Sequencer, but this one takes the current :Fader settings -> sendToCollector

    """
    def __init__(self,
                 graph: SyncedGraph,
                 ):
        self.graph = graph
        self.faders: List[Fader] = []

        log.info('fader adds handler')
        self.graph.addHandler(self._compile)
        self.lastLoopSucceeded = False

    def onCodeChange(self):
        log.debug('seq.onCodeChange')
        self.graph.addHandler(self._compile)

    @COMPILE.time()
    def _compile(self) -> None:
        """rebuild our data from the graph"""
        self.faders = []
        for fader in self.graph.subjects(RDF.type, L9['Fader']):
            effect = typedValue(EffectUri, self.graph, fader, L9['effect'])
            setting = typedValue(Node, self.graph, fader, L9['setting'])
            setAttr = typedValue(EffectAttr,  self.graph, setting, L9['effectAttr'])
            self.faders.append(Fader(self.graph, cast(URIRef, fader), effect, setAttr))

        # this could go in a second, smaller addHandler call to avoid rebuilding Fader objs constantly
        for f in self.faders:
            setting = typedValue(Node, self.graph, f.uri, L9['setting'])            
            f.value = typedValue(float, self.graph, setting, L9['value'])

    def computeOutput(self) -> DeviceSettings:
        faderEffectOutputs: List[DeviceSettings] = []
        now = UnixTime(time.time())
        for f in self.faders:
            if f.value is None:
                raise TypeError('f.value should be set by now')
            effectSettings = EffectSettings(self.graph, [(f.effect, f.setEffectAttr, f.value)])

            if f.value < .001:
                continue

            faderEffectOutputs.append(f.ee.compute(effectSettings))

            # ee = effecteval.EffectEval(self.graph, f.effectClass, self.simpleOutputs)
            # deviceSettings, report = ee.outputFromEffect(
            #     effectSettings,
            #     songTime=now, # probably wrong
            #     noteTime=now, # wrong
            #     )
            # log.info(f'  𝅘𝅥𝅮  {uriTail(f.uri)}: {effectSettings=} -> {deviceSettings=}')
            # if deviceSettings:
            #     notesSettings.append(deviceSettings)
        return DeviceSettings.merge(self.graph, faderEffectOutputs)