diff --git a/light9/live/GraphToControls.ts b/light9/live/GraphToControls.ts --- a/light9/live/GraphToControls.ts +++ b/light9/live/GraphToControls.ts @@ -4,16 +4,39 @@ import { SyncedGraph } from "../web/Sync import { ControlValue, Effect } from "./Effect"; const log = debug("g2c"); +// Callback for GraphToControls to set a ControlValue on a +// Light9LiveControl (widget for a Device+Attr) type NewValueCb = (newValue: ControlValue | null) => void; // More efficient bridge between liveControl widgets and graph edits (inside Effect), // as opposed to letting each widget scan the graph and push lots of // tiny patches to it. +// +// When you create a Light9LiveControl, it registers with GraphToControls (and does not +// watch value updates from the graph). export class GraphToControls { // rename to PageControls? - effect: Effect | null = null; // this uri should sync to the editchoice - registeredWidgets: Map> = new Map(); - constructor(public graph: SyncedGraph) {} + private effect: Effect | null = null; // this uri should sync to the editchoice + + // This will fill with every device+attr in the show. Currently there's no unregister to forget a device or attr. + private registeredWidgets: Map< + NamedNode /*Device*/, + Map< + NamedNode /*DeviceAttr*/, // + NewValueCb + > + > = new Map(); + constructor(public graph: SyncedGraph) { + + } + + debugDump() { + log("dump: effect", this.effect); + log("registered widgets"); + for (let e of this.registeredWidgets.entries()) { + log(" rw:", e[0], e[1]); + } + } setEffect(effect: NamedNode | null) { log(`setEffect ${effect?.value}`); @@ -31,7 +54,11 @@ export class GraphToControls { return this.effect.uri; } - onValuesChanged() { + emptyEffect() { + throw new Error("not implemented"); + } + + private onValuesChanged() { log(`i learned values changed for ${this.effect?.uri.value} `); this.registeredWidgets.forEach((d1: Map, device: NamedNode) => { d1.forEach((cb: NewValueCb, deviceAttr: NamedNode) => { diff --git a/light9/live/Light9LiveControls.ts b/light9/live/Light9LiveControls.ts --- a/light9/live/Light9LiveControls.ts +++ b/light9/live/Light9LiveControls.ts @@ -43,15 +43,16 @@ export class Light9LiveControls extends return html` -

device control

+

effect deviceattrs

- +
+
${this.devices.map( (device: NamedNode) => html` @@ -76,11 +77,13 @@ export class Light9LiveControls extends this.graph = g; this.graph.runHandler(this.findDevices.bind(this), "findDevices"); this.graphToControls = new GraphToControls(this.graph); - // this.graph.runHandler(this.xupdate.bind(this), "Light9LiveControls update"); + // this.graph.runHandler(this.update.bind(this), "Light9LiveControls update"); this.setEffectFromUrl(); }); } - + onEffectChoice2(ev: CustomEvent) { + this.effectChoice = ev.detail.newValue as NamedNode; + } updated(changedProperties: PropertyValues) { if (changedProperties.has("effectChoice")) { log(`effectChoice to ${this.effectChoice?.value}`); @@ -88,11 +91,13 @@ export class Light9LiveControls extends } } + // Note that this doesn't fetch setting values, so it only should get rerun + // upon (rarer) changes to the devices etc. findDevices(patch?: Patch) { const U = this.graph.U(); - if (patch && !patchContainsPreds(patch, [U("rdf:type")])) { - return; - } + // if (patch && !patchContainsPreds(patch, [U("rdf:type")])) { + // return; + // } this.devices = []; let classes = this.graph.subjects(U("rdf:type"), U(":DeviceClass")); @@ -158,38 +163,38 @@ export class Light9LiveControls extends return this.graphToControls.emptyEffect(); } - configureFromGraph() { - const U = (x: string) => this.graph.Uri(x); + // configureFromGraph() { + // const U = (x: string) => this.graph.Uri(x); - const newDevs: NamedNode[] = []; - for (let dc of Array.from(this.graph.sortedUris(this.graph.subjects(U("rdf:type"), U(":DeviceClass"))))) { - for (let dev of Array.from(this.graph.sortedUris(this.graph.subjects(U("rdf:type"), dc)))) { - if (this.graph.contains(dev, U(":hideInLiveUi"), null)) { - continue; - } - if (newDevs.length == 0) newDevs.push(dev); - } - } - log("is this called?"); - log(`controls update now has ${newDevs.length} devices`); - this.devices = newDevs; - this.requestUpdate(); + // const newDevs: NamedNode[] = []; + // for (let dc of Array.from(this.graph.sortedUris(this.graph.subjects(U("rdf:type"), U(":DeviceClass"))))) { + // for (let dev of Array.from(this.graph.sortedUris(this.graph.subjects(U("rdf:type"), dc)))) { + // if (this.graph.contains(dev, U(":hideInLiveUi"), null)) { + // continue; + // } + // if (newDevs.length == 0) newDevs.push(dev); + // } + // } + // log("is this called?"); + // log(`controls update now has ${newDevs.length} devices`); + // this.devices = newDevs; + // this.requestUpdate(); - return; + // return; - // Tried css columns- big slowdown from relayout as I'm scrolling. - // Tried isotope- seems to only scroll to the right. - // Tried columnize- fails in jquery maybe from weird elements. + // // Tried css columns- big slowdown from relayout as I'm scrolling. + // // Tried isotope- seems to only scroll to the right. + // // Tried columnize- fails in jquery maybe from weird elements. - // not sure how to get this run after the children are created - return setTimeout( - () => - $("#deviceControls").isotope({ - // fitColumns would be nice, but it doesn't scroll vertically - layoutMode: "masonry", - containerStyle: null, - }), - 2000 - ); - } + // // not sure how to get this run after the children are created + // return setTimeout( + // () => + // $("#deviceControls").isotope({ + // // fitColumns would be nice, but it doesn't scroll vertically + // layoutMode: "masonry", + // containerStyle: null, + // }), + // 2000 + // ); + // } }