@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
74 lines (64 loc) • 2.27 kB
text/typescript
import {Object3D} from 'three';
import {CoreObjectType, ObjectContent} from '../../geometry/ObjectContent';
import {CoreLoaderGeometry} from '../Geometry';
import {BaseLoaderLoadOptions, CoreBaseLoader} from '../_Base';
import type {BaseGeoLoaderOutput, OnSuccess, OnProgress, OnError} from './Common';
import {isPromise} from '../../Type';
export abstract class BaseGeoLoader<O extends BaseGeoLoaderOutput> {
abstract load: (url: string, onSuccess: OnSuccess<O>, onProgress?: OnProgress, onError?: OnError) => void;
}
export abstract class BaseLoaderHandler<
O extends BaseGeoLoaderOutput,
OC extends ObjectContent<CoreObjectType>
> extends CoreBaseLoader<string> {
protected _loader: BaseGeoLoader<O> | undefined;
reset() {
this._loader = undefined;
}
async load(options: BaseLoaderLoadOptions): Promise<OC[] | undefined> {
const loader = await this._getLoader(options);
if (!loader) {
console.warn('no loader', this);
return;
}
const url = this._urlToLoad();
return new Promise(async (resolve) => {
CoreLoaderGeometry.incrementInProgressLoadsCount();
await CoreLoaderGeometry.waitForMaxConcurrentLoadsQueueFreed();
loader.load(
url,
(object: O) => {
CoreLoaderGeometry.decrementInProgressLoadsCount(url, object);
const result = this._onLoadSuccess(object);
if (isPromise(result)) {
result.then((newObjects) => {
resolve(newObjects);
});
} else {
resolve(result);
}
},
(progress) => {},
(event: ErrorEvent) => {
CoreLoaderGeometry.decrementInProgressLoadsCount(url);
const message = this._errorMessage(url, event);
options.node?.states.error.set(message);
}
);
});
}
protected _errorMessage(url: string, event: ErrorEvent) {
return `could not load geometry from ${url} (Error: ${event.message})`;
}
protected abstract _getLoader(options: BaseLoaderLoadOptions): Promise<BaseGeoLoader<O>>;
protected abstract _onLoadSuccess(o: O): OC[] | Promise<OC[]>;
}
export abstract class BaseObject3DLoaderHandler<O extends BaseGeoLoaderOutput> extends BaseLoaderHandler<O, Object3D> {
protected _onLoadSuccess(o: O): Object3D[] | Promise<Object3D[]> {
if (o instanceof Object3D) {
return [o];
} else {
return [];
}
}
}