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

206 lines
5.8 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 { Spritesheet } from '@pixi/spritesheet';
2022-11-17 12:44:32 -05:00
import { NitroLogger } from '../common';
2022-11-09 17:55:03 -05:00
import { ArrayBufferToBase64, NitroBundle } from '../utils';
2022-10-30 00:02:19 -04:00
import { GraphicAssetCollection } from './GraphicAssetCollection';
2022-11-09 17:55:03 -05:00
import { IAssetData } from './IAssetData';
import { IAssetManager } from './IAssetManager';
import { IGraphicAsset } from './IGraphicAsset';
import { IGraphicAssetCollection } from './IGraphicAssetCollection';
2021-03-16 22:02:09 -04:00
2022-11-09 17:55:03 -05:00
export class AssetManager implements IAssetManager
2021-03-16 22:02:09 -04:00
{
2022-11-09 17:55:03 -05:00
public static _INSTANCE: IAssetManager = new AssetManager();
2021-03-16 22:02:09 -04:00
2022-11-09 17:55:03 -05:00
private _textures: Map<string, Texture<Resource>> = new Map();
private _collections: Map<string, IGraphicAssetCollection> = new Map();
2021-03-16 22:02:09 -04:00
2021-07-14 03:10:54 -04:00
public getTexture(name: string): Texture<Resource>
2021-03-16 22:02:09 -04:00
{
2022-11-08 16:50:16 -05:00
if(!name) return null;
2021-03-16 22:02:09 -04:00
const existing = this._textures.get(name);
2022-11-08 16:50:16 -05:00
if(!existing) return null;
2021-03-16 22:02:09 -04:00
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
{
2022-11-08 16:50:16 -05:00
if(!name || !texture) return;
2021-03-16 22:02:09 -04:00
this._textures.set(name, texture);
}
public getAsset(name: string): IGraphicAsset
{
2022-11-08 16:50:16 -05:00
if(!name) return null;
2021-03-16 22:02:09 -04:00
2022-11-08 16:50:16 -05:00
for(const collection of this._collections.values())
2021-03-16 22:02:09 -04:00
{
2022-11-08 16:50:16 -05:00
if(!collection) continue;
2021-03-16 22:02:09 -04:00
const existing = collection.getAsset(name);
2022-11-08 16:50:16 -05:00
if(!existing) continue;
2021-03-16 22:02:09 -04:00
return existing;
}
return null;
}
public getCollection(name: string): IGraphicAssetCollection
{
2022-11-08 16:50:16 -05:00
if(!name) return null;
2021-03-16 22:02:09 -04:00
const existing = this._collections.get(name);
2022-11-08 16:50:16 -05:00
if(!existing) return null;
2021-03-16 22:02:09 -04:00
return existing;
}
public createCollection(data: IAssetData, spritesheet: Spritesheet): IGraphicAssetCollection
{
2022-11-08 16:50:16 -05:00
if(!data) return null;
2021-03-16 22:02:09 -04:00
const collection = new GraphicAssetCollection(data, spritesheet);
2022-11-08 16:50:16 -05:00
if(collection)
2021-03-16 22:02:09 -04:00
{
2022-11-08 16:50:16 -05:00
for(const [name, texture] of collection.textures.entries()) this.setTexture(name, texture);
2021-03-16 22:02:09 -04:00
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-11-14 00:22:26 -05:00
public async downloadAsset(url: string): Promise<boolean>
2021-03-16 22:02:09 -04:00
{
2022-11-14 00:22:26 -05:00
return await this.downloadAssets([url]);
2021-03-16 22:02:09 -04:00
}
2022-11-14 00:22:26 -05:00
public async downloadAssets(urls: string[]): Promise<boolean>
2021-03-16 22:02:09 -04:00
{
if(!urls || !urls.length) return Promise.resolve(true);
2022-11-14 00:22:26 -05:00
try
2022-04-10 02:58:33 -04:00
{
2022-12-09 06:41:49 -03:00
for(const url of urls)
2021-03-16 22:02:09 -04:00
{
2022-12-09 06:41:49 -03:00
const response = await fetch(url);
if(response.status !== 200) continue;
let contentType = 'application/octet-stream';
2022-12-09 06:41:49 -03:00
if(response.headers.has('Content-Type'))
{
2022-12-09 06:41:49 -03:00
contentType = response.headers.get('Content-Type');
}
2021-03-16 22:02:09 -04:00
2022-11-14 00:22:26 -05:00
switch(contentType)
2021-03-16 22:02:09 -04:00
{
2022-11-14 00:22:26 -05:00
case 'application/octet-stream': {
2022-12-09 06:41:49 -03:00
const buffer = await response.arrayBuffer();
const nitroBundle = new NitroBundle(buffer);
2022-04-11 12:19:38 -04:00
2022-12-09 06:41:49 -03:00
await this.processAsset(
nitroBundle.baseTexture,
nitroBundle.jsonFile as IAssetData
);
2022-11-14 00:22:26 -05:00
break;
2022-04-11 12:19:38 -04:00
}
2022-11-14 00:22:26 -05:00
case 'image/png':
case 'image/jpeg':
case 'image/gif': {
2022-12-09 06:41:49 -03:00
const buffer = await response.arrayBuffer();
const base64 = ArrayBufferToBase64(buffer);
2022-12-09 06:41:49 -03:00
const baseTexture = BaseTexture.from(
`data:${ contentType };base64,${ base64 }`
);
2022-11-14 00:22:26 -05:00
const createAsset = async () =>
2022-04-11 12:19:38 -04:00
{
const texture = new Texture(baseTexture);
2022-12-09 06:41:49 -03:00
this.setTexture(url, texture);
2022-11-14 00:22:26 -05:00
};
2021-03-16 22:02:09 -04:00
2022-11-14 00:22:26 -05:00
if(baseTexture.valid)
{
await createAsset();
}
else
{
await new Promise<void>((resolve, reject) =>
{
baseTexture.once('update', async () =>
{
await createAsset();
return resolve();
});
});
}
break;
2022-04-11 12:19:38 -04:00
}
2021-03-16 22:02:09 -04:00
}
}
2022-11-17 12:44:32 -05:00
return Promise.resolve(true);
2022-11-14 00:22:26 -05:00
}
catch (err)
{
2022-11-17 12:44:32 -05:00
NitroLogger.error(err);
2022-11-14 00:22:26 -05:00
return Promise.resolve(false);
2022-11-17 12:44:32 -05:00
}
2022-04-10 02:58:33 -04:00
}
2021-03-16 22:02:09 -04:00
2022-11-14 00:22:26 -05:00
private async processAsset(baseTexture: BaseTexture, data: IAssetData): Promise<void>
2022-04-10 02:58:33 -04:00
{
const spritesheetData = data.spritesheet;
2021-03-16 22:02:09 -04:00
2022-11-08 16:50:16 -05:00
if(!baseTexture || !spritesheetData || !Object.keys(spritesheetData).length)
2022-04-11 12:19:38 -04:00
{
this.createCollection(data, null);
return;
}
2022-11-14 00:22:26 -05:00
const createAsset = async () =>
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
await spritesheet.parse();
2022-04-10 02:58:33 -04:00
this.createCollection(data, spritesheet);
2022-04-11 12:19:38 -04:00
};
2021-03-16 22:02:09 -04:00
2022-11-08 16:50:16 -05:00
if(baseTexture.valid)
2022-04-11 12:19:38 -04:00
{
2022-11-14 00:22:26 -05:00
await createAsset();
2022-04-11 12:19:38 -04:00
}
else
{
2022-11-14 00:22:26 -05:00
await new Promise<void>((resolve, reject) =>
{
baseTexture.once('update', async () =>
{
await createAsset();
return resolve();
});
});
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;
}
}