Changeset - e9239995eb57
[Not reviewed]
default
0 2 0
drewp@bigasterisk.com - 20 months ago 2023-05-30 06:08:15
drewp@bigasterisk.com
fix effect new/clear commands
2 files changed with 40 insertions and 20 deletions:
0 comments (0 inline, 0 general)
light9/live/Effect.ts
Show inline comments
 
@@ -19,52 +19,63 @@ function isUri(x: Term | number | string
 
// todo: eliminate this. address the scaling when we actually scale
 
// stuff, instead of making a mess of every setting
 
function valuePred(graph: SyncedGraph, attr: NamedNode): NamedNode {
 
  const U = graph.U();
 
  const scaledAttributeTypes = [U(":color"), U(":brightness"), U(":uv")];
 
  if (some(scaledAttributeTypes, (x: NamedNode) => attr.equals(x))) {
 
    return U(":value");
 
  } else {
 
    return U(":value");
 
  }
 
}
 

	
 
function effContext(graph: SyncedGraph, uri: NamedNode): NamedNode {
 
  return graph.Uri(uri.value.replace("light9.bigasterisk.com/effect", `light9.bigasterisk.com/show/${shortShow}/effect`));
 
}
 

	
 
export function newEffect(graph: SyncedGraph): NamedNode {
 
  // wrong- this should be our editor's scratch effect, promoted to a
 
  // real one when you name it.
 
  const uri = graph.nextNumberedResource(graph.Uri("http://light9.bigasterisk.com/effect/effect"));
 

	
 
  const effect = new Effect(graph, uri);
 
  const U = graph.U();
 
  const ctx = effContext(graph, uri);
 
  const quad = (s: Quad_Subject, p: Quad_Predicate, o: Quad_Object) => graph.Quad(s, p, o, ctx);
 

	
 
  const addQuads = [
 
    quad(uri, U("rdf:type"), U(":Effect")),
 
    quad(uri, U("rdfs:label"), graph.Literal(uri.value.replace(/.*\//, ""))),
 
    quad(uri, U(":publishAttr"), U(":strength")),
 
  ];
 
  const patch = new Patch([], addQuads);
 
  log("init new effect", patch);
 
  graph.applyAndSendPatch(patch);
 

	
 
  return effect.uri;
 
}
 

	
 
// effect settings data; r/w sync with the graph
 
export class Effect {
 
  private settings: Array<{ device: NamedNode; deviceAttr: NamedNode; setting: NamedNode; value: ControlValue }> = [];
 
  private ctxForEffect: NamedNode;
 
  settingsChanged: SubEvent<void> = new SubEvent();
 
  constructor(
 
    public graph: SyncedGraph,
 
    public uri: NamedNode // called if the graph changes our values and not when the caller uses edit()
 
  ) {
 
    this.ctxForEffect = this.graph.Uri(this.uri.value.replace("light9.bigasterisk.com/effect", `light9.bigasterisk.com/show/${shortShow}/effect`));
 
    this.ctxForEffect = effContext(this.graph, this.uri);
 
    graph.runHandler(this.rebuildSettingsFromGraph.bind(this), `effect sync ${uri.value}`);
 
  }
 

	
 
  addNewEffectToGraph() {
 
    const U = this.graph.U();
 
    const quad = (s: Quad_Subject, p: Quad_Predicate, o: Quad_Object) => this.graph.Quad(s, p, o, this.ctxForEffect);
 

	
 
    const addQuads = [
 
      quad(this.uri, U("rdf:type"), U(":Effect")),
 
      quad(this.uri, U("rdfs:label"), this.graph.Literal(this.uri.value.replace(/.*\//, ""))),
 
      quad(this.uri, U(":publishAttr"), U(":strength")),
 
    ];
 
    const patch = new Patch([], addQuads);
 
    log("init new effect", patch);
 
    this.settings = [];
 
    this.graph.applyAndSendPatch(patch);
 
  }
 

	
 
  rebuildSettingsFromGraph(patch?: Patch) {
 
    const U = this.graph.U();
 
    if (patch && !patch.containsAnyPreds([U(":setting"), U(":device"), U(":deviceAttr")])) {
 
      // that's an approx list of preds , but it just means we'll miss some pathological settings edits
 
      //   return;
 
    }
 

	
 
    // log("syncFromGraph", this.uri);
 

	
 
    // this repeats work- it gathers all settings when really some values changed (and we might even know about them). maybe push the value-fetching into a secnod phase of the run, and have the 1st phase drop out early
 
    const newSettings = [];
 

	
 
@@ -177,22 +188,28 @@ export class Effect {
 
  }
 

	
 
  private removeEffectSetting(effectSetting: NamedNode): Patch {
 
    const U = (x: string) => this.graph.Uri(x);
 
    log("  _removeEffectSetting", effectSetting.value);
 
    const toDel = [this.graph.Quad(this.uri, U(":setting"), effectSetting, this.ctxForEffect)];
 
    for (let q of this.graph.subjectStatements(effectSetting)) {
 
      toDel.push(q);
 
    }
 
    return new Patch(toDel, []);
 
  }
 

	
 
clearAllSettings() {
 
  for (let s of this.settings) {
 
    this.graph.applyAndSendPatch(this.removeEffectSetting(s.setting))
 
  }
 
}
 

	
 
  private nodeForValue(value: ControlValue): NamedNode | Literal {
 
    if (value === null) {
 
      throw new Error("no value");
 
    }
 
    if (isUri(value)) {
 
      return value;
 
    }
 
    return this.graph.prettyLiteral(value);
 
  }
 
}
light9/live/Light9DeviceSettings.ts
Show inline comments
 
import debug from "debug";
 
import { css, html, LitElement, PropertyValues } from "lit";
 
import { customElement, property } from "lit/decorators.js";
 
import { NamedNode } from "n3";
 
import { sortBy, uniq } from "underscore";
 
import { Patch } from "../web/patch";
 
import { getTopGraph } from "../web/RdfdbSyncedGraph";
 
import { SyncedGraph } from "../web/SyncedGraph";
 
import { Effect } from "./Effect";
 
import { Effect, newEffect } from "./Effect";
 
export { EditChoice } from "../web/EditChoice";
 
export { Light9DeviceControl as Light9LiveDeviceControl } from "./Light9DeviceControl";
 
const log = debug("settings");
 

	
 
@customElement("light9-device-settings")
 
export class Light9DeviceSettings extends LitElement {
 
  graph!: SyncedGraph;
 

	
 
  static styles = [
 
    css`
 
      :host {
 
        display: flex;
 
@@ -71,26 +71,30 @@ export class Light9DeviceSettings extend
 
  constructor() {
 
    super();
 

	
 
    getTopGraph().then((g) => {
 
      this.graph = g;
 
      this.graph.runHandler(this.compile.bind(this), "findDevices");
 
      this.setEffectFromUrl();
 
    });
 
  }
 

	
 
  onEffectChoice2(ev: CustomEvent) {
 
    const uri = ev.detail.newValue as NamedNode;
 
    this.setCurrentEffect(uri);
 
  }
 
  setCurrentEffect(uri: NamedNode) {
 
    if (uri === null) {
 
      this.currentEffect = null;
 
      // todo: wipe the UI settings
 
    } else {
 
      this.currentEffect = new Effect(this.graph, uri);
 
    }
 
  }
 

	
 
  updated(changedProperties: PropertyValues<this>) {
 
    log("ctls udpated", changedProperties);
 
    if (changedProperties.has("currentEffect")) {
 
      log(`effectChoice to ${this.currentEffect?.uri?.value}`);
 
      this.writeToUrl(this.currentEffect?.uri);
 
    }
 
    // this.graphToControls?.debugDump();
 
@@ -131,20 +135,19 @@ export class Light9DeviceSettings extend
 
      return;
 
    }
 
    const u = new URL(window.location.href);
 
    if ((u.searchParams.get("effect") || "") === effectStr) {
 
      return;
 
    }
 
    u.searchParams.set("effect", effectStr); // this escapes : and / and i wish it didn't
 
    window.history.replaceState({}, "", u.href);
 
    log("wrote new url", u.href);
 
  }
 

	
 
  newEffect() {
 
    // this.effectChoice = this.graphToControls.newEffect();
 
    this.setCurrentEffect(newEffect(this.graph));
 
  }
 

	
 
  clearAll() {
 
    // clears the effect!
 
    return; //this.graphToControls.emptyEffect();
 
    this.currentEffect?.clearAllSettings()
 
  }
 
}
0 comments (0 inline, 0 general)