From 3cbe41e2be7b4ca8dabcf98094caad15a321ddc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 20 May 2021 12:00:37 +0200 Subject: [PATCH] If a measurement is being skipped because of the ruler's rate limiting, schedule the measurement for later to ensure the ruler sticks to the token --- CHANGELOG.md | 5 +++++ src/foundry_imports.js | 24 +++++++++++++++++++++--- src/main.js | 1 - 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e218e87..cf72ad5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## In development +### Bugfixes +- Fixed a bug that could cause the ruler to not end up at the token's center (especially if the token is being moved very quickly and then stopped abruptly) + + ## 1.7.1 ### Bugfixes - Fixed a bug that prevented players from moving their tokens ([#74](https://github.com/manuelVo/foundryvtt-drag-ruler/issues/74)) diff --git a/src/foundry_imports.js b/src/foundry_imports.js index bf8c477..0bfcf27 100644 --- a/src/foundry_imports.js +++ b/src/foundry_imports.js @@ -16,6 +16,9 @@ export async function moveEntities(draggedEntity, selectedEntities) { if (!this.visible || !this.destination) return false; if (!draggedEntity) return; + // Wait until all scheduled measurements are done + await this.deferredMeasurementPromise; + // Get the movement rays and check collision along each Ray // These rays are center-to-center for the purposes of collision checking const rays = this.constructor.dragRulerGetRaysFromWaypoints(this.waypoints, this.destination); @@ -103,8 +106,6 @@ export function onMouseMove(event) { if (this._state === Ruler.STATES.MOVING) return; // Extract event data - const mt = event._measureTime || 0; - const originalEvent = event.data.originalEvent; const destination = {x: event.data.destination.x + this.rulerOffset.x, y: event.data.destination.y + this.rulerOffset.y} // Hide any existing Token HUD @@ -112,10 +113,27 @@ export function onMouseMove(event) { delete event.data.hudState; // Draw measurement updates - if (Date.now() - mt > 50) { + scheduleMeasurement.call(this, destination, event); +} + +function scheduleMeasurement(destination, event) { + const measurementInterval = 50; + const mt = event._measureTime || 0; + const originalEvent = event.data.originalEvent; + if (Date.now() - mt > measurementInterval) { this.measure(destination, {snap: !originalEvent.shiftKey}); event._measureTime = Date.now(); this._state = Ruler.STATES.MEASURING; + window.clearTimeout(this.deferredMeasurementTimeout); + this.deferredMeasurementTimeout = undefined; + this.deferredMeasurementResolve?.(); + } + else { + this.deferredMeasurementData = {destination, event}; + if (!this.deferredMeasurementTimeout) { + this.deferredMeasurementPromise = new Promise((resolve, reject) => this.deferredMeasurementResolve = resolve); + this.deferredMeasurementTimeout = window.setTimeout(() => scheduleMeasurement.call(this, this.deferredMeasurementData.destination, this.deferredMeasurementData.event), measurementInterval); + } } } diff --git a/src/main.js b/src/main.js index 11036c9..8f2da66 100644 --- a/src/main.js +++ b/src/main.js @@ -154,7 +154,6 @@ function onEntityDragLeftDrop(event) { const ruler = canvas.controls.ruler if (!ruler.isDragRuler) return false - onMouseMove.call(ruler, event); // When we're dragging a measured template no token will ever be selected, // resulting in only the dragged template to be moved as would be expected const selectedTokens = canvas.tokens.controlled