From 3562824db7dc078853bf6da6023d06f68956358e Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Tue, 31 Dec 2019 20:06:26 -0800 Subject: [PATCH] clean up picking code --- modules/core/src/lib/deck-picker.js | 11 ++++---- modules/core/src/lib/deck.js | 24 +++++++++++------ modules/core/src/lib/picking/pick-info.js | 32 ----------------------- 3 files changed, 21 insertions(+), 46 deletions(-) diff --git a/modules/core/src/lib/deck-picker.js b/modules/core/src/lib/deck-picker.js index 95835c2a81d..7d483094f84 100644 --- a/modules/core/src/lib/deck-picker.js +++ b/modules/core/src/lib/deck-picker.js @@ -30,7 +30,7 @@ import GL from '@luma.gl/constants'; import assert from '../utils/assert'; import PickLayersPass from '../passes/pick-layers-pass'; import {getClosestObject, getUniqueObjects} from './picking/query-object'; -import {processPickInfo, callLayerPickingCallbacks, getLayerPickingInfo} from './picking/pick-info'; +import {processPickInfo, getLayerPickingInfo} from './picking/pick-info'; export default class DeckPicker { constructor(gl) { @@ -125,7 +125,6 @@ export default class DeckPicker { radius = 0, depth = 1, mode = 'query', - event, unproject3D, onViewportActive }) { @@ -213,10 +212,10 @@ export default class DeckPicker { pixelRatio }); - const processedPickInfos = callLayerPickingCallbacks(infos, mode, event); - - if (processedPickInfos) { - processedPickInfos.forEach(info => result.push(info)); + for (const info of infos.values()) { + if (info.layer) { + result.push(info); + } } // If no object is picked stop. diff --git a/modules/core/src/lib/deck.js b/modules/core/src/lib/deck.js index 6a989543d83..e6c99be32ba 100644 --- a/modules/core/src/lib/deck.js +++ b/modules/core/src/lib/deck.js @@ -532,7 +532,6 @@ export default class Deck { this.layerManager.context.mousePosition = {x: _pickRequest.x, y: _pickRequest.y}; } - _pickRequest.callback = this.props.onHover; _pickRequest.event = event; _pickRequest.mode = 'hover'; } @@ -541,19 +540,28 @@ export default class Deck { _pickAndCallback() { const {_pickRequest} = this; - if (_pickRequest.mode) { - // perform picking + if (_pickRequest.event) { + // Perform picking const {result, emptyInfo} = this._pick('pickObject', 'pickObject Time', _pickRequest); - const shouldGenerateInfo = _pickRequest.callback || this.props.getTooltip; - const pickedInfo = shouldGenerateInfo && (result.find(info => info.index >= 0) || emptyInfo); + const pickedInfo = result[0] || emptyInfo; + + // Update tooltip if (this.props.getTooltip) { const displayInfo = this.props.getTooltip(pickedInfo); this.tooltip.setTooltip(displayInfo, pickedInfo.x, pickedInfo.y); } - if (_pickRequest.callback && !pickedInfo.handled) { - _pickRequest.callback(pickedInfo, _pickRequest.event); + + // Execute callbacks + let handled = false; + if (pickedInfo.layer) { + handled = pickedInfo.layer.onHover(pickedInfo, _pickRequest.event); + } + if (!handled && this.props.onHover) { + this.props.onHover(pickedInfo, _pickRequest.event); } - _pickRequest.mode = null; + + // Clear pending pickRequest + _pickRequest.event = null; } } diff --git a/modules/core/src/lib/picking/pick-info.js b/modules/core/src/lib/picking/pick-info.js index 4b9a7368d6e..60e86f1a8f5 100644 --- a/modules/core/src/lib/picking/pick-info.js +++ b/modules/core/src/lib/picking/pick-info.js @@ -149,35 +149,3 @@ function getViewportFromCoordinates({viewports}) { const viewport = viewports[0]; return viewport; } - -// Per-layer event handlers (e.g. onClick, onHover) are provided by the -// user and out of deck.gl's control. It's very much possible that -// the user calls React lifecycle methods in these function, such as -// ReactComponent.setState(). React lifecycle methods sometimes induce -// a re-render and re-generation of props of deck.gl and its layers, -// which invalidates all layers currently passed to this very function. - -// Therefore, per-layer event handlers must be invoked at the end -// of the picking operation. NO operation that relies on the states of current -// layers should be called after this code. -export function callLayerPickingCallbacks(infos, mode, event) { - const unhandledPickInfos = []; - - infos.forEach(info => { - if (!info.layer) { - return; - } - - switch (mode) { - case 'hover': - info.handled = info.layer.onHover(info, event); - break; - case 'query': - default: - } - - unhandledPickInfos.push(info); - }); - - return unhandledPickInfos; -}