@deck.gl/core
Version:
deck.gl core library
97 lines (81 loc) • 2.35 kB
text/typescript
// deck.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import {load} from '@loaders.gl/core';
import type {ResourceManagerContext} from './resource-manager';
export type ResourceSubscriber<T = any> = {
onChange: (data: T | Promise<T>) => void;
};
export default class Resource<T = any> {
id: string;
context: ResourceManagerContext;
isLoaded!: boolean;
persistent?: boolean;
private _loadCount: number = 0;
private _subscribers = new Set<ResourceSubscriber<T>>();
private _data!: T | Promise<T> | string;
private _loader?: Promise<void>;
private _error?: Error;
private _content?: T;
constructor(id: string, data: T | Promise<T> | string, context: ResourceManagerContext) {
this.id = id;
this.context = context;
this.setData(data);
}
// consumer: {onChange: Function}
subscribe(consumer: ResourceSubscriber<T>): void {
this._subscribers.add(consumer);
}
unsubscribe(consumer: ResourceSubscriber<T>): void {
this._subscribers.delete(consumer);
}
inUse(): boolean {
return this._subscribers.size > 0;
}
delete(): void {
// Remove any resources created
}
getData(): T | Promise<T> {
return this.isLoaded
? this._error
? Promise.reject(this._error)
: this._content!
: this._loader!.then(() => this.getData());
}
setData(data: any, forceUpdate?: boolean) {
if (data === this._data && !forceUpdate) {
return;
}
this._data = data;
const loadCount = ++this._loadCount;
let loader = data;
if (typeof data === 'string') {
loader = load(data);
}
if (loader instanceof Promise) {
this.isLoaded = false;
this._loader = loader
.then(result => {
// check if source has changed
if (this._loadCount === loadCount) {
this.isLoaded = true;
this._error = undefined;
this._content = result;
}
})
.catch(error => {
if (this._loadCount === loadCount) {
this.isLoaded = true;
this._error = error || true;
}
});
} else {
this.isLoaded = true;
this._error = undefined;
this._content = data;
}
for (const subscriber of this._subscribers) {
subscriber.onChange(this.getData());
}
}
}