annotate light9/web/live/Effect.ts @ 2091:9324fc8285ad

Effect repairs duplicate :settings edges when it finds them
author drewp@bigasterisk.com
date Mon, 30 May 2022 23:21:50 -0700
parents bbd6816d9e9e
children 9c2e1b5c16e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
1 import debug from "debug";
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
2 import { Literal, NamedNode, Quad_Object, Quad_Predicate, Quad_Subject, Term } from "n3";
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
3 import { some } from "underscore";
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
4 import { Patch, patchContainsPreds, patchUpdate } from "../patch";
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
5 import { SyncedGraph } from "../SyncedGraph";
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
6
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
7 type Color = string;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
8 export type ControlValue = number | Color | NamedNode;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
9
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
10 const log = debug("effect");
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
11
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
12 function isUri(x: Term | number | string): x is NamedNode {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
13 return typeof x == "object" && x.termType == "NamedNode";
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
14 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
15
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
16 function valuePred(graph: SyncedGraph, attr: NamedNode): NamedNode {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
17 const U = graph.U();
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
18 const scaledAttributeTypes = [U(":color"), U(":brightness"), U(":uv")];
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
19 if (some(scaledAttributeTypes, (x: NamedNode) => attr.equals(x))) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
20 return U(":scaledValue");
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
21 } else {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
22 return U(":value");
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
23 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
24 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
25
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
26 // effect settings data; r/w sync with the graph
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
27 export class Effect {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
28 private settings: Array<{ device: NamedNode; deviceAttr: NamedNode; setting: NamedNode; value: ControlValue }> = [];
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
29
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
30 constructor(
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
31 public graph: SyncedGraph,
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
32 public uri: NamedNode,
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
33 // called if the graph changes our values and not when the caller uses edit()
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
34 private onValuesChanged: (values: void) => void
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
35 ) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
36 graph.runHandler(this.rebuildSettingsFromGraph.bind(this), `effect sync ${uri.value}`);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
37 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
38
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
39 private ctxForEffect(): NamedNode {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
40 return this.graph.Uri(this.uri.value.replace("light9.bigasterisk.com/effect", "light9.bigasterisk.com/show/dance2019/effect"));
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
41 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
42
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
43 addNewEffectToGraph() {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
44 const U = this.graph.U();
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
45 const ctx = this.ctxForEffect();
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
46 const quad = (s: Quad_Subject, p: Quad_Predicate, o: Quad_Object) => this.graph.Quad(s, p, o, ctx);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
47
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
48 const addQuads = [
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
49 quad(this.uri, U("rdf:type"), U(":Effect")),
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
50 quad(this.uri, U("rdfs:label"), this.graph.Literal(this.uri.value.replace(/.*\//, ""))),
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
51 quad(this.uri, U(":publishAttr"), U(":strength")),
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
52 ];
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
53 const patch = { adds: addQuads, dels: [] } as Patch;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
54 log("init new effect", patch);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
55 this.settings = [];
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
56 this.graph.applyAndSendPatch(patch);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
57 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
58
2089
bbd6816d9e9e big optimization on effect editing. 50% time still in rebuildSettingsFromGraph though, and the rest is in setLabel
drewp@bigasterisk.com
parents: 2087
diff changeset
59 rebuildSettingsFromGraph(patch?: Patch) {
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
60 const U = this.graph.U();
2089
bbd6816d9e9e big optimization on effect editing. 50% time still in rebuildSettingsFromGraph though, and the rest is in setLabel
drewp@bigasterisk.com
parents: 2087
diff changeset
61 if (patch && !patchContainsPreds(patch, [U(":setting"), U(":device"), U(":deviceAttr")])) {
bbd6816d9e9e big optimization on effect editing. 50% time still in rebuildSettingsFromGraph though, and the rest is in setLabel
drewp@bigasterisk.com
parents: 2087
diff changeset
62 // that's an approx list of preds , but it just means we'll miss some pathological settings edits
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
63 // return;
2089
bbd6816d9e9e big optimization on effect editing. 50% time still in rebuildSettingsFromGraph though, and the rest is in setLabel
drewp@bigasterisk.com
parents: 2087
diff changeset
64 }
bbd6816d9e9e big optimization on effect editing. 50% time still in rebuildSettingsFromGraph though, and the rest is in setLabel
drewp@bigasterisk.com
parents: 2087
diff changeset
65
bbd6816d9e9e big optimization on effect editing. 50% time still in rebuildSettingsFromGraph though, and the rest is in setLabel
drewp@bigasterisk.com
parents: 2087
diff changeset
66 // log("syncFromGraph", this.uri);
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
67
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
68 // 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
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
69 const newSettings = [];
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
70
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
71 const seenDevAttrPairs: Set<string> = new Set();
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
72
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
73 for (let setting of Array.from(this.graph.objects(this.uri, U(":setting")))) {
2089
bbd6816d9e9e big optimization on effect editing. 50% time still in rebuildSettingsFromGraph though, and the rest is in setLabel
drewp@bigasterisk.com
parents: 2087
diff changeset
74 // log(` setting ${setting.value}`);
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
75 if (!isUri(setting)) throw new Error();
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
76 let value: ControlValue;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
77 const device = this.graph.uriValue(setting, U(":device"));
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
78 const deviceAttr = this.graph.uriValue(setting, U(":deviceAttr"));
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
79
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
80 const pred = valuePred(this.graph, deviceAttr);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
81 try {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
82 value = this.graph.uriValue(setting, pred);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
83 if (!(value as NamedNode).id.match(/^http/)) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
84 throw new Error("not uri");
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
85 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
86 } catch (error) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
87 try {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
88 value = this.graph.floatValue(setting, pred);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
89 } catch (error1) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
90 value = this.graph.stringValue(setting, pred); // this may find multi values and throw
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
91 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
92 }
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
93 // log(`change: graph contains ${deviceAttr.value} ${value}`);
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
94
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
95 newSettings.push({ device, deviceAttr, setting, value });
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
96 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
97 this.settings = newSettings;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
98 log(`rebuild to ${this.settings.length}`);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
99 this.onValuesChanged();
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
100 }
2089
bbd6816d9e9e big optimization on effect editing. 50% time still in rebuildSettingsFromGraph though, and the rest is in setLabel
drewp@bigasterisk.com
parents: 2087
diff changeset
101
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
102 currentValue(device: NamedNode, deviceAttr: NamedNode): ControlValue | null {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
103 for (let s of this.settings) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
104 if (device.equals(s.device) && deviceAttr.equals(s.deviceAttr)) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
105 return s.value;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
106 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
107 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
108 return null;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
109 }
2089
bbd6816d9e9e big optimization on effect editing. 50% time still in rebuildSettingsFromGraph though, and the rest is in setLabel
drewp@bigasterisk.com
parents: 2087
diff changeset
110
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
111 // change this object now, but return the patch to be applied to the graph so it can be coalesced.
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
112 edit(device: NamedNode, deviceAttr: NamedNode, newValue: ControlValue | null): Patch {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
113 log(`edit: value=${newValue}`);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
114 let existingSetting: NamedNode | null = null;
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
115 let result = { adds: [], dels: [] };
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
116 for (let s of this.settings) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
117 if (device.equals(s.device) && deviceAttr.equals(s.deviceAttr)) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
118 if (existingSetting !== null) {
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
119 // this is corrupt. There was only supposed to be one setting per (dev,attr) pair. But we can fix it because we're going to update existingSetting to the user's requested value.
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
120 log(`${this.uri.value} had two settings for ${device.value} - ${deviceAttr.value} - deleting ${s.setting}`);
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
121 patchUpdate(result, this._removeEffectSetting(s.setting));
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
122 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
123 existingSetting = s.setting;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
124 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
125 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
126
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
127 if (newValue !== null && this.shouldBeStored(deviceAttr, newValue)) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
128 if (existingSetting === null) {
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
129 patchUpdate(result, this._addEffectSetting(device, deviceAttr, newValue));
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
130 } else {
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
131 patchUpdate(result, this._patchExistingEffectSetting(existingSetting, deviceAttr, newValue));
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
132 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
133 } else {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
134 if (existingSetting !== null) {
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
135 patchUpdate(result, this._removeEffectSetting(existingSetting));
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
136 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
137 }
2091
9324fc8285ad Effect repairs duplicate :settings edges when it finds them
drewp@bigasterisk.com
parents: 2089
diff changeset
138 return result;
2087
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
139 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
140
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
141 shouldBeStored(deviceAttr: NamedNode, value: ControlValue | null): boolean {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
142 // this is a bug for zoom=0, since collector will default it to
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
143 // stick at the last setting if we don't explicitly send the
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
144 // 0. rx/ry similar though not the exact same deal because of
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
145 // their remap.
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
146 return value != null && value !== 0 && value !== "#000000";
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
147 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
148
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
149 _addEffectSetting(device: NamedNode, deviceAttr: NamedNode, value: ControlValue): Patch {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
150 log(" _addEffectSetting", deviceAttr.value, value);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
151 const U = (x: string) => this.graph.Uri(x);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
152 const ctx = this.ctxForEffect();
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
153 const quad = (s: Quad_Subject, p: Quad_Predicate, o: Quad_Object) => this.graph.Quad(s, p, o, ctx);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
154 if (!this.uri) throw new Error("effect unset");
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
155 const setting = this.graph.nextNumberedResource(this.uri.value + "_set");
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
156
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
157 const addQuads = [
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
158 quad(this.uri, U(":setting"), setting),
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
159 quad(setting, U(":device"), device),
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
160 quad(setting, U(":deviceAttr"), deviceAttr),
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
161 quad(setting, valuePred(this.graph, deviceAttr), this._nodeForValue(value)),
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
162 ];
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
163 const patch = { adds: addQuads, dels: [] } as Patch;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
164 log(" save", patch);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
165 this.settings.push({ device, deviceAttr, setting, value });
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
166 return patch;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
167 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
168
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
169 _patchExistingEffectSetting(effectSetting: NamedNode, deviceAttr: NamedNode, value: ControlValue): Patch {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
170 log(" patch existing", effectSetting.value);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
171 return this.graph.getObjectPatch(
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
172 effectSetting, //
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
173 valuePred(this.graph, deviceAttr),
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
174 this._nodeForValue(value),
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
175 this.ctxForEffect()
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
176 );
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
177 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
178
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
179 _removeEffectSetting(effectSetting: NamedNode): Patch {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
180 const U = (x: string) => this.graph.Uri(x);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
181 log(" _removeEffectSetting", effectSetting.value);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
182 const toDel = [this.graph.Quad(this.uri, U(":setting"), effectSetting, this.ctxForEffect())];
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
183 for (let q of this.graph.subjectStatements(effectSetting)) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
184 toDel.push(q);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
185 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
186 return { dels: toDel, adds: [] };
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
187 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
188
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
189 _nodeForValue(value: ControlValue): NamedNode | Literal {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
190 if (value === null) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
191 throw new Error("no value");
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
192 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
193 if (isUri(value)) {
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
194 return value;
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
195 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
196 return this.graph.prettyLiteral(value);
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
197 }
1b6e7016e3de rewrite state mgmt in live/
drewp@bigasterisk.com
parents:
diff changeset
198 }