commit c8e405496221d6bd7e72b937a14614ee6b675aa4
parent 3bc2f9160c10aab793422b139790aaf27da268f5
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Fri, 13 Sep 2024 10:21:38 -0700
Fix backend and editor state mismatch
When reconstructTo was called on the backend, it's state was
reconstructed to what it looked like at diff position D. Afterwords
the editor might—or in the case of this program, would—step through
history much like the backend applying differences in order to
reconstruct it's state to where it needed to be. The issue came
when it needed to reference some data that wasn't in the diff, for
example points a pointmap refers to, and there was a mismatch between
what the data should've looked like at that point for the editor
and what it actually was in the backend.
One way of solving this would be to have the editor store it's own
state of things and push and pull differences to and from the
backend, but then what's the point of the backend? So now you can
provide the backend with a callback function for applying differences.
This actually simplifies quite a few things that depend on the
backend aswell.
Now the state of the editor is always the same as the state of the
backend.
Diffstat:
3 files changed, 12 insertions(+), 44 deletions(-)
diff --git a/files/floorplans/floorplan/backend.js b/files/floorplans/floorplan/backend.js
@@ -128,7 +128,7 @@ class BackendHistory {
diff.id = this.diffs.push(diff) - 1
this.place = diff.id
console.debug("Backend.History.addDiff", diff.id, diff)
- return diff.id
+ return diff
}
diffMark(diff) {
@@ -414,7 +414,7 @@ export class FloorplanBackend {
console.debug("Backend.addData", id, value)
let t = idTable(id)
if (!options.nodiff) {
- this.history.addDiff("add", idPath(id), value, options)
+ this.cb("patch", this.history.addDiff("add", idPath(id), value, options))
}
this.cache[t][id] = value
@@ -435,7 +435,7 @@ export class FloorplanBackend {
}
if (!options.nodiff) {
- this.history.addDiff("remove", idPath(id), null, options)
+ this.cb("patch", this.history.addDiff("remove", idPath(id), null, options))
}
delete this.cache[t][id]
}
@@ -621,6 +621,7 @@ export class FloorplanBackend {
cb(name, arg) {
if (this.callbacks[name]) {
+ console.debug("Backend.cb", name, arg)
this.callbacks[name](arg)
}
}
@@ -716,6 +717,7 @@ export class FloorplanBackend {
} else {
this.addData(id, diff[i].value, options)
}
+ this.cb("patch", diff[i])
}
if (!options.nodiff) {
this.history.mark()
diff --git a/files/floorplans/floorplan/editor.js b/files/floorplans/floorplan/editor.js
@@ -247,6 +247,8 @@ export class FloorplanEditor {
options = {}
}
+ let editor = this
+
this.draw = svg
this.mode
this.modes = {}
@@ -265,14 +267,10 @@ export class FloorplanEditor {
if (!options.backend.callbacks) {
options.backend.callbacks = {}
}
-
- let editor = this
+ options.backend.callbacks["patch"] = function(diff) { editor.applyOp(diff) }
this.backend = new backend.FloorplanBackend(floorplan, options.backend)
- // The diff which reflects the state of the displayed objects
- this.diff = -1
-
this.grids = {}
for (let system in this.units.systems) {
this.grids[system] = gridSystem(this, system)
@@ -451,12 +449,10 @@ export class FloorplanEditor {
undo() {
this.backend.undo()
- this.updateDisplay()
}
redo() {
this.backend.redo()
- this.updateDisplay()
}
addPoint(point, force) {
@@ -466,9 +462,7 @@ export class FloorplanEditor {
return already
}
}
- let p = this.backend.addPoint(point)
- this.updateDisplay()
- return p
+ return this.backend.addPoint(point)
}
remove(...elements) {
@@ -496,7 +490,6 @@ export class FloorplanEditor {
}
this.backend.removeOrphans()
- this.updateDisplay()
}
movePoint(point, coordinate) {
@@ -533,9 +526,7 @@ export class FloorplanEditor {
}
mapPoints(type, p1, p2) {
- let id = this.backend.mapPoints(type, getID(p1, "points"), getID(p2, "points"))
- this.updateDisplay()
- return id
+ return this.backend.mapPoints(type, getID(p1, "points"), getID(p2, "points"))
}
addFurniture(params, id) {
@@ -543,15 +534,11 @@ export class FloorplanEditor {
}
mapFurniture(params, id) {
- id = this.backend.mapFurniture(params, id)
- this.updateDisplay()
- return id
+ return this.backend.mapFurniture(params, id)
}
addMappedFurniture(params, id) {
- id = this.backend.addMappedFurniture(params, id)
- this.updateDisplay()
- return id
+ return this.backend.addMappedFurniture(params, id)
}
selectedPoints() {
@@ -569,21 +556,8 @@ export class FloorplanEditor {
return this.draw.findOneMax("#points > .last_selected")
}
- updateDisplay() {
- let diffs = this.backend.history.between(this.diff, this.backend.history.place)
- if (diffs.length > 0) {
- this.applyDiffs(diffs)
- this.diff = diffs.at(-1).id
- if (this.diff > this.backend.history.place) {
- this.diff -= 1
- }
- console.debug("Editor.updateDisplay", "Updated display to diff id", this.diff)
- }
- }
-
applyDiffs(diffs) {
for (let op in diffs) {
- // TODO: Catch errors and update this.diff accordingly
this.applyOp(diffs[op])
}
}
diff --git a/files/floorplans/floorplan/main.js b/files/floorplans/floorplan/main.js
@@ -46,7 +46,6 @@ function init() {
{ backend: {
callbacks: {
pull: function() {
- editor.updateDisplay()
suffix.data = ""
},
push: function() {
@@ -165,7 +164,6 @@ function selectHandler(event, editor, state) {
const changeTypes = function(newvalue) {
for (let i in maps) {
editor.mapPoints(newvalue, maps[i].a, maps[i].b)
- editor.updateDisplay()
}
}
c.appendChild(
@@ -452,7 +450,6 @@ function precisePointHandler(event, editor, state) {
if (state.snapmap == null) {
editor.movePoint(state.to, p)
- editor.updateDisplay()
}
let points = editor.thingsAt(p, "#points")
@@ -484,7 +481,6 @@ function precisePointHandler(event, editor, state) {
state.snapmap = null
state.to = editor.addPoint(p, true)
editor.mapPoints("wall", state.from, state.to)
- editor.updateDisplay()
state.to = editor.findObj(state.to)
}
@@ -562,7 +558,6 @@ function precisePointHandler(event, editor, state) {
state.origin.distanceTo(cursor) > 200) {
state.to = editor.addPoint(cursor, true)
editor.mapPoints("wall", state.from, state.to)
- editor.updateDisplay()
state.to = editor.findObj(state.to)
init()
}
@@ -617,7 +612,6 @@ function precisePointMapHandler(event, editor) {
return
}
- // Shouldn't really use backend as it's only correct when updateDisplay is called
let data = editor.backend.obj(lib.getID(map))
if (data.type != "wall") {
throw new Error("Changing direction of doors not yet supported")
@@ -634,7 +628,6 @@ function precisePointMapHandler(event, editor) {
editor.mapPoints("wall", data.a, sub)
editor.mapPoints("wall", sub, data.b)
editor.remove(map)
- editor.updateDisplay()
}
}
@@ -993,7 +986,6 @@ function addWallHandler(click, editor) {
}
editor.addPoint(editor.draw.point(click.clientX, click.clientY))
- editor.updateDisplay()
if (editor.draw.findOne("#points").children().length >= 2) {
editor.mapSelected("wall")
}