commit 703b2b6fd2e69e997647fe358a36308d653f42c0
parent 36f939973f6c38d4476da30448abef2f73cbcd37
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Thu, 10 Oct 2024 11:42:02 -0700
Update backend mapPoints method
It now takes a parameters argument along with the ID of the map to
update like furniture maps. It uses a new method updatedObject to
validate parameters and build to new object. In the future I want
all these functions function the same way using this updatedObject
method.
While it should have been a separate commit, the precisePointHandler
function was also updated so fix some issues with the snapmap stuff,
which led to the changes described above.
Diffstat:
3 files changed, 110 insertions(+), 81 deletions(-)
diff --git a/files/floorplans/floorplan/backend.js b/files/floorplans/floorplan/backend.js
@@ -489,31 +489,40 @@ export class FloorplanBackend {
}
}
- // Returns map id
- mapPoints(type, a, b, options) {
- options = options ?? {}
- if (type != "wall" && type != "door") {
- throw new Error("Only walls and doors allowed in pointmap so far")
- }
- if (!this.cache.points[a] || !this.cache.points[b]) {
- throw new Error(`${a}, ${b}: Pointmap must reference existing points`)
+ mapPoints(params, id) {
+ const backend = this
+ const validPoint = function(id) {
+ return idType(id) === "pnt" && backend.obj(id)
}
- let d = {
- type: type,
- a: a,
- b: b
- }
- if (options.door_swing != null) {
- switch (options.door_swing) {
- case "a+": case "a-": case "b+": case "b-":
- break;
- default:
- throw new Error(options.door_swing + ": Invalid door swing")
+ const m = this.updatedObject(params, id, {
+ type: {
+ required: true,
+ validate: function(type) {
+ return type === "wall" || type === "door"
+ }
+ },
+ a: {
+ required: true,
+ validate: validPoint
+ },
+ b: {
+ required: true,
+ validate: validPoint
+ },
+ door_swing: {
+ validate: function(swing) {
+ switch (swing) {
+ case "a+": case "a-": case "b+": case "b-":
+ return true
+ default:
+ return false
+ }
+ }
}
- d.door_swing = options.door_swing
- }
- return this.addData(this.whichPointMap(a, b) ?? "pointmaps", d, options)
+ })
+
+ this.addData(this.whichPointMap(m.a, m.b) ?? "pointmaps", m)
}
unmapPoints(id, options) {
@@ -639,6 +648,38 @@ export class FloorplanBackend {
return this.mapFurniture(params, id)
}
+ updatedObject(params, id, vd) {
+ let obj = id ? structuredClone(this.reqObj(id)) : {}
+
+ for (let k in vd) {
+ let vdk = vd[k]
+ if (vdk.required && params[k] === null) {
+ throw new Error(`Cannot delete required parameter ("${k}")`)
+ }
+ if (params[k] === undefined) {
+ continue
+ }
+ if (typeof vdk.parse === "function") {
+ obj[k] = vdk.parse(params[k])
+ } else if (typeof vdk.validate === "function") {
+ if (!vdk.validate(params[k])) {
+ throw new Error(`Invalid value for "${k}" parameter ("${params[k]}")`)
+ }
+ obj[k] = params[k]
+ } else {
+ throw new Error(`"${k}" parameter missing validate or parse function`)
+ }
+ }
+
+ for (let k in vd) {
+ if (vd[k].required && obj[k] == null) {
+ throw new Error(`Cannot omit required parameter ("${k}")`)
+ }
+ }
+
+ return obj
+ }
+
reqObj(id) {
let obj = this.obj(id)
if (obj == null) {
diff --git a/files/floorplans/floorplan/editor.js b/files/floorplans/floorplan/editor.js
@@ -585,11 +585,17 @@ export class FloorplanEditor {
mapSelected(type) {
let points = this.selectedPoints()
- return this.mapPoints(type, points.a, points.b)
+ return this.mapPoints({ type, a: points.a, b: points.b })
}
- mapPoints(type, p1, p2) {
- return this.backend.mapPoints(type, getID(p1, "points"), getID(p2, "points"))
+ mapPoints(params, id) {
+ if (params.a) {
+ params.a = getID(params.a, "points")
+ }
+ if (params.b) {
+ params.b = getID(params.b, "points")
+ }
+ return this.backend.mapPoints(params, id)
}
addFurniture(params, id) {
diff --git a/files/floorplans/floorplan/main.js b/files/floorplans/floorplan/main.js
@@ -275,29 +275,30 @@ function selectHandler(event, editor, state) {
userLength(editor, editor.pointmapLength(groups.pntmap[0]))))
}
- let maps = []
if (groups.pntmap !== undefined) {
+ let maps = {}
for (let i = 0; i < groups.pntmap.length; ++i) {
- maps.push(editor.backend.cache.pointmaps[groups.pntmap[i]])
+ maps[groups.pntmap[i]] = editor.backend.cache.pointmaps[groups.pntmap[i]]
}
- }
-
- if (maps.length > 0) {
- const changeTypes = function(newvalue) {
- for (let i in maps) {
- editor.mapPoints(newvalue, maps[i].a, maps[i].b)
+ if (groups.pntmap.length > 0) {
+ const changeTypes = function(newvalue) {
+ for (let id in maps) {
+ editor.mapPoints({ type: newvalue }, id)
+ }
}
- }
- let current = maps[0].type
- for (let i = 0; i < maps.length; ++i) {
- if (current !== maps[i].type) {
- current = null
- break;
+ let current
+ for (let id in maps) {
+ if (current === undefined) {
+ current = maps[id].type
+ } else if (current !== maps[i].type) {
+ current = null
+ break;
+ }
}
+ c.appendChild(
+ selector({ wall: true, door: true }, changeTypes, { current, text: "Type:" })
+ )
}
- c.appendChild(
- selector({ wall: true, door: true }, changeTypes, { current, text: "Type:" })
- )
}
let fmaps = ids.filter(function(item) { return backend.idType(item) === "furmap" })
@@ -537,6 +538,7 @@ function precisePointHandler(event, editor, state) {
}
})
}
+
const cleanup = function() {
if (state.moveTimeout != null) {
clearTimeout(state.moveTimeout)
@@ -548,58 +550,30 @@ function precisePointHandler(event, editor, state) {
delete state[i]
}
}
+
const updatePoint = function(p, options) {
options = options ?? {}
- if (state.snapmap == null) {
- editor.movePoint(state.to, p)
- }
-
let points = editor.thingsAt(p, "#points")
let fid = lib.getID(state.from)
- let tid
- if (state.snapmap == null) {
- tid = lib.getID(state.to)
- }
- let instead
+ let tid = lib.getID(state.to)
+ delete state.onPoint
for (let i in points) {
let id = lib.getID(points[i])
if (id !== tid && id !== fid) {
- instead = id
+ state.onPoint = id
+ p = editor.backend.obj(id)
}
}
- if (instead != undefined) {
- if (instead !== state.to) {
- if (state.snapmap == null) {
- editor.remove(state.to)
- } else {
- editor.remove(state.snapmap)
- }
- state.to = editor.findObj(instead)
- if (state.removeSnapmap == undefined) {
- state.removeSnapmap = editor.backend.whichPointMap(
- lib.getID(state.from), lib.getID(state.to)
- ) == null
- }
- state.snapmap = editor.mapPoints("wall", state.from, state.to)
- }
- } else if (state.snapmap != null) {
- if (state.removeSnapmap) {
- editor.remove(state.snapmap)
- delete state.removeSnapmap
- }
- state.snapmap = null
- state.to = editor.addPoint(p, true)
- editor.mapPoints("wall", state.from, state.to)
- state.to = editor.findObj(state.to)
- }
+ editor.movePoint(state.to, p)
if (!options.leave_input) {
unitInput(editor, state.len,
editor.units.snapTo(state.origin.distanceTo(p), editor.unit))
}
}
+
const doMove = function() {
const ad = function(a, b) {
return Math.abs(a - b)
@@ -639,6 +613,7 @@ function precisePointHandler(event, editor, state) {
}
updatePoint(snapped)
}
+
const revert = function() {
/*
* NOTE: WARNING: If allowing asyncronous edits this would be bad
@@ -651,7 +626,14 @@ function precisePointHandler(event, editor, state) {
editor.undo()
cleanup()
}
+
const commit = function() {
+ if (state.onPoint) {
+ for (let oth in editor.backend.mappedPoints[state.to]) {
+ editor.mapPoints({ a: state.onPoint, b: oth }, editor.backend.mappedPoints[state.to][oth])
+ }
+ editor.remove(state.to)
+ }
editor.finishAction()
cleanup()
}
@@ -705,7 +687,7 @@ function precisePointHandler(event, editor, state) {
} else if (event.type === "pointermove" && state.origin != undefined &&
state.origin.distanceTo(cursor) > 200) {
state.to = editor.addPoint(cursor, true)
- editor.mapPoints("wall", state.from, state.to)
+ editor.mapPoints({ type: "wall", a: state.from, b: state.to})
state.to = editor.findObj(state.to)
init()
} else {
@@ -782,7 +764,7 @@ function precisePointMapHandler(event, editor, state) {
}
let s = (o > 0 ? "+" : "-")
- editor.backend.mapPoints(state.door.type, state.door.a, state.door.b, { door_swing: state.hinge + s })
+ editor.backend.mapPoints({ door_swing: state.hinge + s }, state.doorID)
editor.finishAction()
cleanup()
return
@@ -807,8 +789,8 @@ function precisePointMapHandler(event, editor, state) {
}
sub = editor.addPoint(sub)
- editor.mapPoints("wall", data.a, sub)
- editor.mapPoints("wall", sub, data.b)
+ editor.mapPoints({ type: "wall", a: data.a, b: sub })
+ editor.mapPoints({ type: "wall", a: sub, b: data.b })
editor.remove(map)
return
}