Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: loader option util improvements #833

Merged
merged 7 commits into from
Jul 1, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function normalize3DTilePositionAttribute(tile, positions, options) {
// https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/specification/TileFormats/Instanced3DModel/README.md#quantized-positions

// Optionally decodes quantized positions on GPU, for simpler renderers that don't accept normalized attributes
if (options.decodeQuantizedPositions) {
if (options['3d-tiles'] && options['3d-tiles'].decodeQuantizedPositions) {
tile.isQuantized = false;
return decodeQuantizedPositions(tile, positions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ export function parse3DTileGLTFViewSync(tile, arrayBuffer, byteOffset) {
}

export async function extractGLTF(tile, gltfFormat, options, context) {
const tile3DOptions = options['3d-tiles'] || {};

extractGLTFBufferOrURL(tile, gltfFormat, options);

if (options.loadGLTF) {
if (tile3DOptions.loadGLTF) {
const {parse, fetch} = context;
if (tile.gltfUrl) {
tile.gltfArrayBuffer = await fetch(tile.gltfUrl, options);
Expand Down
2 changes: 0 additions & 2 deletions modules/3d-tiles/src/lib/parsers/parse-3d-tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import {parseComposite3DTile} from './parse-3d-tile-composite';

// Extracts
export async function parse3DTile(arrayBuffer, byteOffset = 0, options, context, tile = {}) {
options = options['3d-tiles'] || {};

tile.byteOffset = byteOffset;
tile.type = getMagicString(arrayBuffer, byteOffset);

Expand Down
6 changes: 3 additions & 3 deletions modules/3d-tiles/src/tiles-3d-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ async function parseTileset(data, options, context) {

async function parse(data, options, context, loader) {
// auto detect file type
const loaderOptions = options['3d-tiles'] || {};
const tile3dOptions = options['3d-tiles'] || {};
let isTileset;
if ('isTileset' in loaderOptions) {
isTileset = loaderOptions.isTileset;
if ('isTileset' in tile3dOptions) {
isTileset = tile3dOptions.isTileset;
} else {
isTileset = context.url && context.url.indexOf('.json') !== -1;
}
Expand Down
10 changes: 6 additions & 4 deletions modules/core/docs/api-reference/parse.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ Note that additional data types can be converted to `Response` objects and used

Top-level options

| Option | Type | Default | Description |
| ---------------- | ------- | --------- | ------------------------------------------------------------------------------------------------------------------------ |
| `options.log` | object | `console` | By default set to a `console` wrapper. Setting log to `null` will turn off logging. |
| `options.worker` | boolean | `true` | If the selected loader is equipped with a worker url (and the runtime environment supports it) parse on a worker thread. |
| Option | Type | Default | Description |
| ------------------ | ------- | --------- | ------------------------------------------------------------------------------------------------------------------------ |
| `options.metadata` | boolean | `false` | Currently only implemented for `parseInBatches`, adds initial metadata batch |
| `options.log` | object | `console` | By default set to a `console` wrapper. Setting log to `null` will turn off logging. |
| `options.worker` | boolean | `true` | If the selected loader is equipped with a worker url (and the runtime environment supports it) parse on a worker thread. |
| `options.CDN` | string | - | Load workers and scripts from this source, defaults to `'https://unpkg.com/@loaders.gl'` |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will there still be a workerUrl parameter for each loader as well? In some, e.g. Terrain, there's a loader option for the worker url

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.. nothing has changed in the implementation. Just surfacing existing options. I think this works for libs but not for workers, I will mark it as experimental for now.

1 change: 1 addition & 0 deletions modules/core/src/javascript-utils/is-type.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export function isObject(value: any): boolean;
export function isPureObject(value: any): boolean;
export function isPromise(value: any): boolean;

export function isIterable(value: any): boolean;
Expand Down
34 changes: 11 additions & 23 deletions modules/core/src/javascript-utils/is-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ const isBoolean = x => typeof x === 'boolean';
const isFunction = x => typeof x === 'function';

export const isObject = x => x !== null && typeof x === 'object';

export const isPureObject = x => isObject(x) && x.constructor === {}.constructor;
export const isPromise = x => isObject(x) && isFunction(x.then);

export const isIterable = x => x && typeof x[Symbol.iterator] === 'function';

export const isAsyncIterable = x => x && typeof x[Symbol.asyncIterator] === 'function';

export const isIterator = x => x && isFunction(x.next);

export const isResponse = x =>
Expand All @@ -20,30 +18,20 @@ export const isResponse = x =>
export const isFile = x => typeof File !== 'undefined' && x instanceof File;
export const isBlob = x => typeof Blob !== 'undefined' && x instanceof Blob;

export const isWritableDOMStream = x => {
return isObject(x) && isFunction(x.abort) && isFunction(x.getWriter);
};
export const isWritableDOMStream = x =>
isObject(x) && isFunction(x.abort) && isFunction(x.getWriter);

export const isReadableDOMStream = x => {
return (
(typeof ReadableStream !== 'undefined' && x instanceof ReadableStream) ||
(isObject(x) && isFunction(x.tee) && isFunction(x.cancel) && isFunction(x.getReader))
// Not implemented in Firefox
// && isFunction(x.pipeTo)
);
};
export const isReadableDOMStream = x =>
(typeof ReadableStream !== 'undefined' && x instanceof ReadableStream) ||
(isObject(x) && isFunction(x.tee) && isFunction(x.cancel) && isFunction(x.getReader));
// Not implemented in Firefox: && isFunction(x.pipeTo)

// Check for Node.js `Buffer` without triggering bundler to include polyfill
export const isBuffer = x => x && typeof x === 'object' && x.isBuffer;

export const isWritableNodeStream = x => {
return isObject(x) && isFunction(x.end) && isFunction(x.write) && isBoolean(x.writable);
};

export const isReadableNodeStream = x => {
return isObject(x) && isFunction(x.read) && isFunction(x.pipe) && isBoolean(x.readable);
};

export const isWritableNodeStream = x =>
isObject(x) && isFunction(x.end) && isFunction(x.write) && isBoolean(x.writable);
export const isReadableNodeStream = x =>
isObject(x) && isFunction(x.read) && isFunction(x.pipe) && isBoolean(x.readable);
export const isReadableStream = x => isReadableDOMStream(x) || isReadableNodeStream(x);

export const isWritableStream = x => isWritableDOMStream(x) || isWritableNodeStream(x);
2 changes: 1 addition & 1 deletion modules/core/src/lib/api/load.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ import {DataType, LoaderObject} from '@loaders.gl/loader-utils';
* @param options
* @param context
*/
export function load(url: string | ArrayBuffer | File | Blob | Response | ReadableStream, loaders: LoaderObject | LoaderObject[], options?: object, context?: object): Promise<any>;
export function load(url: string | DataType, loaders: LoaderObject | LoaderObject[], options?: object, context?: object): Promise<any>;
6 changes: 3 additions & 3 deletions modules/core/src/lib/api/parse-in-batches.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {concatenateChunksAsync} from '@loaders.gl/loader-utils';
import {isLoaderObject} from '../loader-utils/normalize-loader';
import {mergeOptions} from '../loader-utils/merge-options';
import {normalizeOptions} from '../loader-utils/option-utils';
import {getLoaderContext} from '../loader-utils/context-utils';
import {getAsyncIteratorFromData} from '../loader-utils/get-data';
import {getLoaderContext} from '../loader-utils/get-loader-context';
import {selectLoader} from './select-loader';

export async function parseInBatches(data, loaders, options, url) {
Expand All @@ -21,7 +21,7 @@ export async function parseInBatches(data, loaders, options, url) {
const loader = selectLoader(null, loaders, options, {url});

// Normalize options
options = mergeOptions(loader, options, url);
options = normalizeOptions(options, loader, loaders, url);

const context = getLoaderContext({url, loaders}, options);

Expand Down
6 changes: 3 additions & 3 deletions modules/core/src/lib/api/parse-sync.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {selectLoader} from './select-loader';
import {isLoaderObject} from '../loader-utils/normalize-loader';
import {mergeOptions} from '../loader-utils/merge-options';
import {normalizeOptions} from '../loader-utils/option-utils';
import {getArrayBufferOrStringFromDataSync} from '../loader-utils/get-data';
import {getLoaders, getLoaderContext} from '../loader-utils/get-loader-context';
import {getLoaders, getLoaderContext} from '../loader-utils/context-utils';

export function parseSync(data, loaders, options, context) {
// Signature: parseSync(data, options, url)
Expand Down Expand Up @@ -32,7 +32,7 @@ export function parseSync(data, loaders, options, context) {
}

// Normalize options
options = mergeOptions(loader, options, url);
options = normalizeOptions(options, loader, candidateLoaders, url);

context = getLoaderContext({url, parseSync, loaders}, options);

Expand Down
6 changes: 3 additions & 3 deletions modules/core/src/lib/api/parse.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {assert, validateLoaderVersion} from '@loaders.gl/loader-utils';
import {isLoaderObject} from '../loader-utils/normalize-loader';
import {mergeOptions} from '../loader-utils/merge-options';
import {normalizeOptions} from '../loader-utils/option-utils';
import {getUrlFromData} from '../loader-utils/get-data';
import {getArrayBufferOrStringFromData} from '../loader-utils/get-data';
import {getLoaders, getLoaderContext} from '../loader-utils/get-loader-context';
import {getLoaders, getLoaderContext} from '../loader-utils/context-utils';
import parseWithWorker, {canParseWithWorker} from '../loader-utils/parse-with-worker';
import {selectLoader} from './select-loader';

Expand Down Expand Up @@ -41,7 +41,7 @@ export async function parse(data, loaders, options, context) {
}

// Normalize options
options = mergeOptions(loader, options, autoUrl);
options = normalizeOptions(options, loader, candidateLoaders, autoUrl);

// Get a context (if already present, will be unchanged)
context = getLoaderContext({url: autoUrl, parse, loaders: candidateLoaders}, options, context);
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/lib/api/register-loaders.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {normalizeLoader} from '../loader-utils/normalize-loader';
import {getGlobalLoaderState} from '../loader-utils/merge-options';
import {getGlobalLoaderState} from '../loader-utils/option-utils';

// Store global registered loaders on the global object to increase chances of cross loaders-version interoperability
// This use case is not reliable but can help when testing new versions of loaders.gl with existing frameworks
Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/lib/api/set-loader-options.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {setGlobalOptions} from '../loader-utils/merge-options';
import {setGlobalOptions} from '../loader-utils/option-utils';

// Set global loader options
export function setLoaderOptions(options) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {LoaderContext} from '@loaders.gl/loader-utils';

/**
*
* @param context
* @param options
* @param previousContext
*
* @param context
* @param options
* @param previousContext
*/
export function getLoaderContext(context: object, options: object, previousContext?: LoaderContext | null): LoaderContext;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export function getLoaderContext(context, options, previousContext = null) {
if (previousContext) {
return previousContext;
}

context = {
// TODO - determine how to inject fetch, fetch in options etc
fetch: context.fetch || fetchFile,
...context
};
Expand Down
140 changes: 0 additions & 140 deletions modules/core/src/lib/loader-utils/merge-options.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import {LoaderObject} from '@loaders.gl/loader-utils';

/**
* Set global loader options
* @param options
* @param options
*/
export function setGlobalOptions(options: object): void;

/**
* Merges options with global opts and loader defaults, also injects baseUri
* @param loader
* @param options
* @param url
* @param options
* @param loader
* @param loaders
* @param url
*/
export function mergeOptions(loader: LoaderObject, options: object, url?: string): object;
export function normalizeOptions(options: object, loader: LoaderObject, loaders?: LoaderObject[], url?: string): object;

/**
* Global state for loaders.gl. Stored on `global.loaders._state`
Expand Down
Loading