diff --git a/light9/live/Effect.ts b/light9/live/Effect.ts --- a/light9/live/Effect.ts +++ b/light9/live/Effect.ts @@ -93,7 +93,7 @@ export class Effect { newSettings.push({ device, deviceAttr, setting, value }); } this.settings = newSettings; - log(`rebuild to ${this.settings.length}`); + log(`settings is rebuilt to length ${this.settings.length}`); this.settingsChanged.emit(); // maybe one emitter per dev+attr? // this.onValuesChanged(); } diff --git a/light9/live/Light9AttrControl.ts b/light9/live/Light9AttrControl.ts --- a/light9/live/Light9AttrControl.ts +++ b/light9/live/Light9AttrControl.ts @@ -93,17 +93,31 @@ export class Light9AttrControl extends L private onValueProperty() { if (this.deviceAttrRow === null) throw new Error(); - if (this.effect !== null && this.graph !== undefined) { - const p = this.effect.edit(this.deviceAttrRow.device, this.deviceAttrRow.uri, this.value); - if (p.adds.length || p.dels.length) { - log("Effect told us to graph.patch", p, "to", this.graph); + if (!this.graph) { + log('ignoring value change- no graph yet') + return; + } + if (this.effect === null) { + this.value = null; + } else { + const p = this.effect.edit( + // + this.deviceAttrRow.device, + this.deviceAttrRow.uri, + this.value + ); + if (!p.isEmpty()) { + log("Effect told us to graph.patch this:\n", p.dump()); this.graph.applyAndSendPatch(p); } } } private onEffectProperty() { - if (this.effect === null) throw new Error(); + if (this.effect === null) { + log('no effect obj yet') + return; + } // effect will read graph changes on its own, but emit an event when it does this.effect.settingsChanged.subscribe(() => { this.effectSettingsChanged(); diff --git a/light9/web/SyncedGraph.ts b/light9/web/SyncedGraph.ts --- a/light9/web/SyncedGraph.ts +++ b/light9/web/SyncedGraph.ts @@ -153,9 +153,11 @@ export class SyncedGraph { log("not connected-- dropping patch"); return; } + if (patch.isEmpty()) throw 'should not get to this point with empty patch' this._applyPatch(patch); if (this.client) { + log("sending patch:\n", patch.dump()) this.client.sendPatch(patch); } console.timeEnd("applyAndSendPatch"); @@ -165,7 +167,7 @@ export class SyncedGraph { // In most cases you want applyAndSendPatch. // // This is the only method that writes to this.graph! - log("patch from server [1]"); + log("_applyPatch [1]\n", patch.dump()); this.cachedFloatValues.clear(); this.cachedUriValues.clear(); patch.applyToGraph(this.graph); diff --git a/light9/web/patch.ts b/light9/web/patch.ts --- a/light9/web/patch.ts +++ b/light9/web/patch.ts @@ -52,6 +52,7 @@ export class Patch { } isEmpty() { + // sometimes returns bogus false- waiting for port to Immutable return !this.dels.length && !this.adds.length; } @@ -76,17 +77,20 @@ export class Patch { dump(): string { const lines: string[] = []; const s = (term: N3.Term): string => { - if (term.termType=='Literal') return term.value; - if (term.termType=='NamedNode') return term.value - .replace("http://light9.bigasterisk.com/effect/","effect:") - .replace("http://light9.bigasterisk.com/",":") - .replace("http://www.w3.org/2000/01/rdf-schema#","rdfs:") - .replace("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdf:") - if (term.termType=='BlankNode') return '_:'+term.value; + if (term.termType == "Literal") return term.value; + if (term.termType == "NamedNode") + return term.value + .replace("http://light9.bigasterisk.com/effect/", "effect:") + .replace("http://light9.bigasterisk.com/", ":") + .replace("http://www.w3.org/2000/01/rdf-schema#", "rdfs:") + .replace("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdf:"); + if (term.termType == "BlankNode") return "_:" + term.value; return term.id; }; - this.dels.forEach((d) => lines.push("- " + s(d.subject) + " " + s(d.predicate) + " " + s(d.object))); - this.adds.forEach((d) => lines.push("+ " + s(d.subject) + " " + s(d.predicate) + " " + s(d.object))); + const delPrefix = "- ", + addPrefix = "\u200B+ "; // dels to sort before adds + this.dels.forEach((d) => lines.push(delPrefix + s(d.subject) + " " + s(d.predicate) + " " + s(d.object))); + this.adds.forEach((d) => lines.push(addPrefix + s(d.subject) + " " + s(d.predicate) + " " + s(d.object))); lines.sort(); return lines.join("\n"); }