Files @ 623836db99af
Branch filter:

Location: light9/light9/effect/effect_function_library.py

drewp@bigasterisk.com
fix ts warning
"""repo of the EffectFunctions in the graph. Includes URI->realPythonFunction"""
import logging
from dataclasses import dataclass, field
from typing import Callable, List, Optional, cast

from rdfdb.syncedgraph.syncedgraph import SyncedGraph
from rdflib import RDF, RDFS, Literal

from light9.namespaces import FUNC, L9
from light9.newtypes import EffectAttr, EffectFunction, VTUnion
from light9.typedgraph import typedValue

from . import effect_functions

log = logging.getLogger('effectfuncs')


@dataclass
class _EffectFunctionInput:
    effectAttr: EffectAttr
    defaultValue: Optional[VTUnion]


@dataclass
class _RdfEffectFunction:
    uri: EffectFunction
    label: Optional[Literal]
    inputs: List[_EffectFunctionInput]


@dataclass
class EffectFunctionLibrary:
    """parses :EffectFunction structures"""
    graph: SyncedGraph

    funcs: List[_RdfEffectFunction] = field(default_factory=list)

    def __post_init__(self):
        self.graph.addHandler(self._compile)

    def _compile(self):
        self.funcs = []
        for subj in self.graph.subjects(RDF.type, L9['EffectFunction']):
            label = typedValue(Literal | None, self.graph, subj, RDFS.label)
            inputs = []
            for inp in self.graph.objects(subj, L9['input']):
                inputs.append(
                    _EffectFunctionInput(  #
                        typedValue(EffectAttr, self.graph, inp, L9['effectAttr']),  #
                        typedValue(VTUnion | None, self.graph, inp, L9['defaultValue'])))

            self.funcs.append(_RdfEffectFunction(cast(EffectFunction, subj), label, inputs))

    def getFunc(self, uri: EffectFunction) -> Callable:
        return {
            FUNC['scale']: effect_functions.effect_scale,
            FUNC['strobe']: effect_functions.effect_strobe,
        }[uri]

    def getDefaultValue(self, uri: EffectFunction, attr: EffectAttr) -> VTUnion:
        for f in self.funcs:
            if f.uri == uri:
                for i in f.inputs:
                    if i.effectAttr == attr:
                        if i.defaultValue is not None:
                            return i.defaultValue
        raise ValueError(f'no default for {uri} {attr}')