Changeset - d665acb12046
[Not reviewed]
default
0 2 0
drewp@bigasterisk.com - 20 months ago 2023-05-23 20:58:26
drewp@bigasterisk.com
cleanup
2 files changed with 12 insertions and 18 deletions:
0 comments (0 inline, 0 general)
light9/fade/web/Light9FadeUi.ts
Show inline comments
 
@@ -64,98 +64,95 @@ export class Light9FadeUi extends LitEle
 

	
 
@customElement("light9-fader")
 
export class Light9Fader extends LitElement {
 
  static styles = [
 
    css`
 
      :host {
 
        display: inline-block;
 
        border: 2px gray outset;
 
        background: #272727;
 
      }
 
      fast-slider {
 
        height: 256px;
 
      }
 
      fast-slider > .track {
 
        background: #e3bbc0;
 
        box-shadow: 0 0 8px;
 
      }
 
      fast-slider {
 
        --accent-foreground-rest: #0a0a0c;
 
      }
 
    `,
 
  ];
 
  render() {
 
    return html`
 
      <fast-slider orientation="vertical" .value=${this.value} step=${1 / 255} min="1" max="0" @change=${this.onSliderInput}>
 
        <fast-slider-label label="0"></fast-slider-label>
 
        <fast-slider-label label="1.0"></fast-slider-label>
 
      </fast-slider>
 
      <div>${this.value.toPrecision(3)}</div>
 
      <div>eff: <edit-choice .uri=${this.effect} @edited=${this.onEffectChange}></edit-choice></div>
 
      <div>attr: <edit-choice .uri=${this.effectAttr}></edit-choice></div>
 
      <div>&lt;=&gt; Slider ${this.column}</div>
 
    `;
 
  }
 

	
 
  graph!: SyncedGraph;
 
  ctx: NamedNode = new NamedNode(showRoot + "/fade");
 
  @property() uri!: NamedNode;
 
  @property() column!: string;
 
  @property() effect: NamedNode | null = null;
 
  @property() effectAttr: NamedNode | null = null;
 

	
 
  @property() value: number = 0.111;
 

	
 
  constructor() {
 
    super();
 
    getTopGraph().then((g) => {
 
      this.graph = g;
 
      this.graph.runHandler(this.configure.bind(this), `config ${this.uri.value}`);
 
      this.graph.runHandler(this.valueSync.bind(this), `valueSync ${this.uri.value}`);
 
      this.graph.runHandler(this.compile.bind(this), `config ${this.uri.value}`);
 
      this.graph.runHandler(this.compileValue.bind(this), `valueSync ${this.uri.value}`);
 
    });
 
  }
 

	
 
  configure() {
 
    //   console.time(`fader configure ${this.uri.value}`)
 
  private compile() {
 
    const U = this.graph.U();
 
    if (!this.graph.contains(this.uri, U("rdf:type"), U(":Fader"))) {
 
      // not loaded yet
 
      //   console.timeEnd(`fader configure ${this.uri.value}`)
 

	
 
      // not loaded yet, perhaps
 
      this.column = "unset";
 
      this.effect = null;
 
      this.effectAttr = null;
 
      return;
 
    }
 
    this.column = this.graph.stringValue(this.uri, U(":column"));
 
    this.effect = this.graph.uriValue(this.uri, U(":effectClass"));
 
    this.effectAttr = this.graph.uriValue(this.uri, U(":effectAttr"));
 
    // console.timeEnd(`fader configure ${this.uri.value}`)
 
    this.effect = this.graph.uriValue(this.uri, U(":effect"));
 
    const s = this.graph.uriValue(this.uri, U(":setting"));
 
    this.effectAttr = this.graph.uriValue(s, U(":effectAttr"));
 
  }
 

	
 
  valueSync() {
 
    // console.time(`valueSync ${this.uri.value}`)
 
  private compileValue() {
 
    const U = this.graph.U();
 
    if (!this.graph.contains(this.uri, U("rdf:type"), U(":Fader"))) {
 
      // not loaded yet
 
      // console.timeEnd(`valueSync ${this.uri.value}`)
 
      return;
 
    }
 

	
 
    this.value = this.graph.floatValue(this.uri, this.graph.Uri(":value"));
 
    // console.timeEnd(`valueSync ${this.uri.value}`)
 
  }
 

	
 
  onSliderInput(ev: CustomEvent) {
 
    const prev = this.value;
 
    const v: number = (ev.target as any).valueAsNumber;
 
    this.value = parseFloat(v.toPrecision(3)); // rewrite pls
 
    if (this.value == prev) {
 
      return;
 
    }
 
    log(`new value ${this.value}`);
 
    meter.tick();
 
    this.graph.patchObject(this.uri, this.graph.Uri(":value"), this.graph.LiteralRoundedFloat(this.value), this.ctx);
 
  }
 

	
 
  onEffectChange(ev: CustomEvent) {
 
    const { newValue } = ev.detail;
 
    this.graph.patchObject(this.uri, this.graph.Uri(":effectClass"), newValue, this.ctx);
 
    this.graph.patchObject(this.uri, this.graph.Uri(":effect"), newValue, this.ctx);
 
  }
 
}
light9/typedgraph.py
Show inline comments
 
from typing import List, Type, TypeVar, cast, get_args
 

	
 
from rdfdb.syncedgraph.syncedgraph import SyncedGraph
 
from rdflib import XSD, BNode, Graph, Literal, URIRef
 
from rdflib.term import Node
 

	
 
# todo: this ought to just require a suitable graph.value method
 
EitherGraph = Graph | SyncedGraph
 

	
 
_ObjType = TypeVar('_ObjType')
 

	
 

	
 
class ConversionError(ValueError):
 
    """graph had a value, but it does not safely convert to any of the requested types"""
 

	
 

	
 
def _expandUnion(t: Type) -> List[Type]:
 
    if hasattr(t, '__args__'):
 
        return list(get_args(t))
 
    return [t]
 

	
 

	
 
def _typeIncludes(t1: Type, t2: Type) -> bool:
 
    """same as issubclass but t1 can be a NewType"""
 
    if t2 is None:
 
        t2 = type(None)
 
    if t1 == t2:
 
        return True
 

	
 
    if getattr(t1, '__supertype__', None) == t2:
 
        return True
 

	
 
    ts = _expandUnion(t1)
 
    if len(ts) > 1:
 
        return any(_typeIncludes(t, t2) for t in ts)
 
    # if t1 is float:
 
    #     return float in get_args(t2)
 
    print(f'down to {t1} {t2}')
 

	
 
    return False
 

	
 

	
 
def _convLiteral(objType: Type[_ObjType], x: Literal) -> _ObjType:
 
    if _typeIncludes(objType, Literal):
 
        return cast(objType, x)
 

	
 
    for outType, dtypes in [
 
        (float, (XSD['integer'], XSD['double'], XSD['decimal'])),
 
        (int, (XSD['integer'],)),
 
        (str, ()),
 
    ]:
 
        for t in _expandUnion(objType):
 
            if _typeIncludes(t, outType) and (not dtypes or x.datatype in dtypes):
 
                # e.g. user wants float and we have xsd:double
 
                return cast(objType, outType(x.toPython()))
 
    raise ConversionError
 

	
 

	
 
def typedValue(objType: Type[_ObjType], graph: EitherGraph, subj: Node, pred: URIRef) -> _ObjType:
 
    """graph.value(subj, pred) with a given return type.
 
    If objType is not an rdflib.Node, we toPython() the value.
 

	
 
    Allow objType to include None if you want a None return for not-found.
 
    """
 
    if objType is None:
 
        raise TypeError('must allow non-None result type')
 
    obj = graph.value(subj, pred)
 
    if obj is None:
 
        if _typeIncludes(objType, None):
 
            return cast(objType, None)
 
        raise ValueError(f'No obj for {subj=} {pred=}')
 

	
 
    ConvFrom: Type[Node] = type(obj)
 
    ConvTo = objType
 
    try:
 
        if ConvFrom == URIRef and _typeIncludes(ConvTo, URIRef):
 
            conv = obj
 
        elif ConvFrom == BNode and issubclass(BNode, ConvTo):
 
            conv = obj
 
        elif ConvFrom == Literal:
 
            conv = _convLiteral(objType, cast(Literal, obj))
 
        else:
 
            raise ConversionError
 
    except ConversionError:
 
        raise ConversionError(f'graph contains {type(obj)}, caller requesting {objType}')
 
    # if objType is float and isinstance(conv, decimal.Decimal):
0 comments (0 inline, 0 general)