Skip to content

Commit

Permalink
Improve view types (#8763)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress committed Apr 6, 2024
1 parent 2f1c39d commit 68a354a
Show file tree
Hide file tree
Showing 16 changed files with 96 additions and 73 deletions.
3 changes: 0 additions & 3 deletions modules/arcgis/src/commons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ async function createDeckInstance(gl: WebGL2RenderingContext): Promise<{
}> {
return new Promise(resolve => {
const deckInstance = new Deck({
// The view state will be set dynamically to track the MapView current extent.
viewState: {},

// Input is handled by the ArcGIS API for JavaScript.
controller: false,

Expand Down
4 changes: 2 additions & 2 deletions modules/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ export type {OrbitViewState, OrbitViewProps} from './views/orbit-view';
export type {OrthographicViewState, OrthographicViewProps} from './views/orthographic-view';
export type {GlobeViewState, GlobeViewProps} from './views/globe-view';
export type {ChangeFlags} from './lib/layer-state';
export type {LayersList} from './lib/layer-manager';
export type {LayerContext} from './lib/layer-manager';
export type {LayersList, LayerContext} from './lib/layer-manager';
export type {ViewStateMap} from './lib/view-manager';
export type {UpdateParameters} from './lib/layer';
export type {DeckProps} from './lib/deck';
export type {
Expand Down
14 changes: 7 additions & 7 deletions modules/core/src/lib/deck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import type {PickingInfo} from './picking/pick-info';
import type {PickByPointOptions, PickByRectOptions} from './deck-picker';
import type {LayersList} from './layer-manager';
import type {TooltipContent} from './tooltip';
import type {ViewStateMap, AnyViewStateOf, ViewOrViews} from './view-manager';
import type {ViewStateMap, AnyViewStateOf, ViewOrViews, ViewStateObject} from './view-manager';

/* global document */

Expand Down Expand Up @@ -90,7 +90,7 @@ type CursorState = {
isDragging: boolean;
};

export type DeckProps<ViewsT extends ViewOrViews = ViewOrViews> = {
export type DeckProps<ViewsT extends ViewOrViews = null> = {
/** Id of this Deck instance */
id?: string;
/** Width of the canvas, a number in pixels or a valid CSS string.
Expand Down Expand Up @@ -288,7 +288,7 @@ const defaultProps = {
};

/* eslint-disable max-statements */
export default class Deck<ViewsT extends ViewOrViews = ViewOrViews> {
export default class Deck<ViewsT extends ViewOrViews = null> {
static defaultProps = defaultProps;
// This is used to defeat tree shaking of init.js
// https://github.com/visgl/deck.gl/issues/3213
Expand All @@ -314,7 +314,7 @@ export default class Deck<ViewsT extends ViewOrViews = ViewOrViews> {
protected animationLoop: AnimationLoop | null = null;

/** Internal view state if no callback is supplied */
protected viewState: ViewStateMap<ViewsT> | null;
protected viewState: ViewStateObject<ViewsT> | null;
protected cursorState: CursorState = {
isHovering: false,
isDragging: false
Expand Down Expand Up @@ -473,7 +473,7 @@ export default class Deck<ViewsT extends ViewOrViews = ViewOrViews> {
width: number;
height: number;
views: View[];
viewState: ViewStateMap<ViewsT>;
viewState: ViewStateObject<ViewsT> | null;
} = Object.create(this.props);
Object.assign(resolvedProps, {
views: this._getViews(),
Expand Down Expand Up @@ -826,8 +826,8 @@ export default class Deck<ViewsT extends ViewOrViews = ViewOrViews> {

// Get the most relevant view state: props.viewState, if supplied, shadows internal viewState
// TODO: For backwards compatibility ensure numeric width and height is added to the viewState
private _getViewState(): ViewStateMap<ViewsT> {
return this.props.viewState || this.viewState || {};
private _getViewState(): ViewStateObject<ViewsT> | null {
return this.props.viewState || this.viewState;
}

// Get the view descriptor list
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/lib/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export type PostRenderOptions = LayersPassRenderOptions & {
swapBuffer: Framebuffer;
};
export type EffectContext = {
deck: Deck;
deck: Deck<any>;
device: Device;
};

Expand Down
4 changes: 2 additions & 2 deletions modules/core/src/lib/layer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const TRACE_ACTIVATE_VIEWPORT = 'layerManager.activateViewport';
export type LayerContext = {
layerManager: LayerManager;
resourceManager: ResourceManager;
deck?: Deck;
deck?: Deck<any>;
device: Device;
shaderAssembler: ShaderAssembler;
defaultShaderModules: ShaderModule[];
Expand All @@ -59,7 +59,7 @@ export type LayerContext = {
export type LayersList = (Layer | undefined | false | null | LayersList)[];

export type LayerManagerProps = {
deck?: Deck;
deck?: Deck<any>;
stats?: Stats;
viewport?: Viewport;
timeline?: Timeline;
Expand Down
4 changes: 2 additions & 2 deletions modules/core/src/lib/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ export default class Tooltip implements Widget {
placement: WidgetPlacement = 'fill';
props = {};
isVisible: boolean = false;
deck?: Deck;
deck?: Deck<any>;
element?: HTMLDivElement;
lastViewport?: Viewport;

onAdd({deck}: {deck: Deck}): HTMLDivElement {
onAdd({deck}: {deck: Deck<any>}): HTMLDivElement {
const el = document.createElement('div');
el.className = 'deck-tooltip';
Object.assign(el.style, defaultStyle);
Expand Down
32 changes: 21 additions & 11 deletions modules/core/src/lib/view-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,34 @@ import type View from '../views/view';
import type {Timeline} from '@luma.gl/engine';
import type {EventManager} from 'mjolnir.js';
import type {ConstructorOf} from '../types/types';
import type MapView from '../views/map-view';
import type {default as MapView, MapViewState} from '../views/map-view';

export type ViewOrViews = View | View[] | null;
type ViewStatOf<ViewT extends View> = ReturnType<ViewT['filterViewState']>;
type ViewStateOf<ViewT> = ViewT extends View<infer ViewStateT> ? ViewStateT : never;
type OneOfViews<ViewsT extends ViewOrViews> = ViewsT extends null
? MapView
: ViewsT extends readonly (infer ViewT)[]
? ViewT
: ViewsT extends View[]
? ViewsT[number]
: ViewsT;
export type AnyViewStateOf<ViewsT extends ViewOrViews> = ViewStatOf<OneOfViews<ViewsT>>;
export type ViewStateMap<ViewsT extends ViewOrViews> =
export type AnyViewStateOf<ViewsT extends ViewOrViews> = ViewStateOf<OneOfViews<ViewsT>>;
export type ViewStateMap<ViewsT extends ViewOrViews> = ViewsT extends null
? MapViewState
: ViewsT extends View
? ViewStateOf<ViewsT>
: {[viewId: string]: AnyViewStateOf<ViewsT>};

/** This is a very lose type of all "acceptable" viewState
* It's not good for type hinting but matches what may exist internally
*/
export type ViewStateObject<ViewsT extends ViewOrViews> =
| ViewStateMap<ViewsT>
| AnyViewStateOf<ViewsT>
| {[viewId: string]: AnyViewStateOf<ViewsT>};

/** ViewManager props directly supplied by the user */
type ViewManagerProps<ViewsT extends ViewOrViews> = {
views: ViewsT;
viewState: ViewStateMap<ViewsT>;
viewState: ViewStateObject<ViewsT> | null;
onViewStateChange?: (params: ViewStateChangeParameters<AnyViewStateOf<ViewsT>>) => void;
onInteractionStateChange?: (state: InteractionState) => void;
width?: number;
Expand All @@ -57,7 +67,7 @@ export default class ViewManager<ViewsT extends View[]> {
width: number;
height: number;
views: View[];
viewState: ViewStateMap<ViewsT>;
viewState: ViewStateObject<ViewsT>;
controllers: {[viewId: string]: Controller<any> | null};
timeline: Timeline;

Expand All @@ -83,7 +93,7 @@ export default class ViewManager<ViewsT extends View[]> {
this.views = [];
this.width = 100;
this.height = 100;
this.viewState = {};
this.viewState = {} as any;
this.controllers = {};
this.timeline = props.timeline;

Expand Down Expand Up @@ -282,7 +292,7 @@ export default class ViewManager<ViewsT extends View[]> {
this.views = views;
}

private _setViewState(viewState: ViewStateMap<ViewsT>): void {
private _setViewState(viewState: ViewStateObject<ViewsT>): void {
if (viewState) {
// depth = 3 when comparing viewStates: viewId.position.0
const viewStateChanged = !deepEqual(viewState, this.viewState, 3);
Expand Down Expand Up @@ -322,7 +332,7 @@ export default class ViewManager<ViewsT extends View[]> {

private _updateController(
view: View,
viewState: ViewStateMap<ViewsT>,
viewState: AnyViewStateOf<ViewsT>,
viewport: Viewport | null,
controller?: Controller<any> | null
): Controller<any> | null {
Expand Down
6 changes: 3 additions & 3 deletions modules/core/src/lib/widget-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface Widget<PropsT = any> {
* @returns an optional UI element that should be appended to the Deck container */
onAdd: (params: {
/** The Deck instance that the widget is attached to */
deck: Deck;
deck: Deck<any>;
/** The id of the view that the widget is attached to */
viewId: string | null;
}) => HTMLDivElement | null;
Expand Down Expand Up @@ -68,7 +68,7 @@ export type WidgetPlacement = keyof typeof PLACEMENTS;
const ROOT_CONTAINER_ID = '__root';

export class WidgetManager {
deck: Deck;
deck: Deck<any>;
parentElement?: HTMLElement | null;

/** Widgets added via the imperative API */
Expand All @@ -83,7 +83,7 @@ export class WidgetManager {
/** Viewport provided to widget on redraw */
private lastViewports: {[id: string]: Viewport} = {};

constructor({deck, parentElement}: {deck: Deck; parentElement?: HTMLElement | null}) {
constructor({deck, parentElement}: {deck: Deck<any>; parentElement?: HTMLElement | null}) {
this.deck = deck;
this.parentElement = parentElement;
}
Expand Down
14 changes: 13 additions & 1 deletion modules/google-maps/src/google-maps-overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,19 @@ const defaultProps = {
interleaved: true
};

export type GoogleMapsOverlayProps = DeckProps & {
export type GoogleMapsOverlayProps = Omit<
DeckProps,
| 'width'
| 'height'
| 'gl'
| 'glOptions'
| 'parent'
| 'canvas'
| '_customRender'
| 'viewState'
| 'initialViewState'
| 'controller'
> & {
interleaved?: boolean;
};

Expand Down
1 change: 1 addition & 0 deletions modules/mapbox/src/deck-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export function getInterleavedProps(currProps: DeckProps) {
blendEquation: GL.FUNC_ADD,
...currProps.parameters
} as any,
// @ts-ignore views prop is hidden by the types because it is not expected to work the same way as in standalone Deck, see documentation
views: currProps.views || [new MapView({id: 'mapbox'})]
};

Expand Down

0 comments on commit 68a354a

Please sign in to comment.