nitro-renderer/src/core/asset/AssetManager.ts

217 lines
5.6 KiB
TypeScript
Raw Normal View History

2022-04-10 02:58:33 -04:00
import { BaseTexture, Resource, Texture } from '@pixi/core';
2021-08-02 23:48:00 -04:00
import { Loader, LoaderResource } from '@pixi/loaders';
import { Spritesheet } from '@pixi/spritesheet';
2021-07-14 03:10:54 -04:00
import { IGraphicAsset } from '../../room';
2021-03-16 22:02:09 -04:00
import { GraphicAssetCollection } from '../../room/object/visualization/utils/GraphicAssetCollection';
import { IGraphicAssetCollection } from '../../room/object/visualization/utils/IGraphicAssetCollection';
import { Disposable } from '../common/disposable/Disposable';
import { INitroLogger } from '../common/logger/INitroLogger';
import { NitroLogger } from '../common/logger/NitroLogger';
import { IAssetManager } from './IAssetManager';
import { IAssetData } from './interfaces';
import { NitroBundle } from './NitroBundle';
export class AssetManager extends Disposable implements IAssetManager
{
private _logger: INitroLogger;
2021-07-14 03:10:54 -04:00
private _textures: Map<string, Texture<Resource>>;
2021-07-13 16:34:41 -04:00
private _collections: Map<string, IGraphicAssetCollection>;
2021-03-16 22:02:09 -04:00
constructor()
{
super();
2022-03-02 19:21:30 -05:00
this._logger = new NitroLogger(this.constructor.name);
this._textures = new Map();
this._collections = new Map();
2021-03-16 22:02:09 -04:00
}
public static removeFileExtension(name: string): string
{
return (name.substring(0, name.lastIndexOf('.')) || name);
}
2021-07-14 03:10:54 -04:00
public getTexture(name: string): Texture<Resource>
2021-03-16 22:02:09 -04:00
{
if(!name) return null;
const existing = this._textures.get(name);
if(!existing) return null;
return existing;
}
2021-07-14 03:10:54 -04:00
public setTexture(name: string, texture: Texture<Resource>): void
2021-03-16 22:02:09 -04:00
{
if(!name || !texture) return;
this._textures.set(name, texture);
}
public getAsset(name: string): IGraphicAsset
{
if(!name) return null;
for(const collection of this._collections.values())
{
if(!collection) continue;
const existing = collection.getAsset(name);
if(!existing) continue;
return existing;
}
return null;
}
public getCollection(name: string): IGraphicAssetCollection
{
if(!name) return null;
const existing = this._collections.get(name);
if(!existing) return null;
return existing;
}
public createCollection(data: IAssetData, spritesheet: Spritesheet): IGraphicAssetCollection
{
if(!data) return null;
const collection = new GraphicAssetCollection(data, spritesheet);
if(collection)
{
for(const [ name, texture ] of collection.textures.entries()) this.setTexture(name, texture);
this._collections.set(collection.name, collection);
}
2021-07-13 16:34:41 -04:00
return collection;
2021-03-16 22:02:09 -04:00
}
2022-04-10 02:58:33 -04:00
public downloadAsset(assetUrl: string, cb: (status: boolean) => void): void
2021-03-16 22:02:09 -04:00
{
2022-04-10 02:58:33 -04:00
this.downloadAssets([ assetUrl ], cb);
2021-03-16 22:02:09 -04:00
}
2022-04-10 02:58:33 -04:00
public downloadAssets(assetUrls: string[], cb: (status: boolean) => void): void
2021-03-16 22:02:09 -04:00
{
if(!assetUrls || !assetUrls.length)
{
cb(true);
2022-04-10 02:58:33 -04:00
return;
2021-03-16 22:02:09 -04:00
}
2022-04-10 02:58:33 -04:00
const loader = new Loader();
2021-03-16 22:02:09 -04:00
for(const url of assetUrls)
{
if(!url) continue;
loader
2021-07-13 16:34:41 -04:00
.add({
url,
crossOrigin: 'anonymous',
xhrType: url.endsWith('.nitro') ? LoaderResource.XHR_RESPONSE_TYPE.BUFFER : LoaderResource.XHR_RESPONSE_TYPE.JSON
2022-04-10 02:58:33 -04:00
});
2021-03-16 22:02:09 -04:00
}
2022-04-10 02:58:33 -04:00
let remaining = assetUrls.length;
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
const onDownloaded = (status: boolean, url: string) =>
2021-03-16 22:02:09 -04:00
{
2022-04-10 02:58:33 -04:00
if(!status)
{
this._logger.error('Failed to download asset: ' + url);
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
loader.destroy();
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
cb(false);
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
return;
}
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
remaining--;
if(!remaining)
2021-03-16 22:02:09 -04:00
{
2022-04-10 02:58:33 -04:00
loader.destroy();
cb(true);
2021-03-16 22:02:09 -04:00
return;
}
2022-04-10 02:58:33 -04:00
};
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
loader.load((loader, resources) =>
{
for(const key in resources)
2021-03-16 22:02:09 -04:00
{
2022-04-10 02:58:33 -04:00
const resource = resources[key];
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
if(!resource || resource.error)
2021-03-16 22:02:09 -04:00
{
2022-04-10 02:58:33 -04:00
onDownloaded(false, resource.url);
2021-03-16 22:02:09 -04:00
return;
}
2022-04-10 02:58:33 -04:00
if(resource.extension === 'nitro')
2021-03-16 22:02:09 -04:00
{
2022-04-10 02:58:33 -04:00
const nitroBundle = new NitroBundle(resource.data);
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
this.processAsset(nitroBundle.baseTexture, (nitroBundle.jsonFile as IAssetData), status =>
2021-03-16 22:02:09 -04:00
{
2022-04-10 02:58:33 -04:00
onDownloaded(true, resource.url);
2021-03-16 22:02:09 -04:00
});
2022-04-10 02:58:33 -04:00
continue;
}
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
if(resource.type === LoaderResource.TYPE.IMAGE)
{
if(resource.texture) this.setTexture(resource.name, resource.texture);
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
onDownloaded(true, resource.url);
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
continue;
2021-03-16 22:02:09 -04:00
}
}
2022-04-10 02:58:33 -04:00
});
}
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
private processAsset(baseTexture: BaseTexture, data: IAssetData, onDownloaded: (status: boolean) => void): void
{
const spritesheetData = data.spritesheet;
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
if(spritesheetData && Object.keys(spritesheetData).length)
2021-03-16 22:02:09 -04:00
{
2022-04-10 02:58:33 -04:00
const spritesheet = new Spritesheet(baseTexture, spritesheetData);
2021-03-16 22:02:09 -04:00
2022-04-10 02:58:33 -04:00
spritesheet.parse(() =>
2021-03-16 22:02:09 -04:00
{
2022-04-10 02:58:33 -04:00
this.createCollection(data, spritesheet);
onDownloaded(true);
});
2021-03-16 22:02:09 -04:00
return;
}
2022-04-10 02:58:33 -04:00
this.createCollection(data, null);
onDownloaded(true);
2021-03-16 22:02:09 -04:00
}
2021-07-13 16:34:41 -04:00
public get collections(): Map<string, IGraphicAssetCollection>
2021-03-16 22:02:09 -04:00
{
return this._collections;
}
}