mirror of
https://github.com/billsonnn/nitro-renderer.git
synced 2025-03-05 16:22:37 +01:00
199 lines
5.5 KiB
TypeScript
199 lines
5.5 KiB
TypeScript
import { BaseTexture, Resource, Texture } from '@pixi/core';
|
|
import { Spritesheet } from '@pixi/spritesheet';
|
|
import { ArrayBufferToBase64, NitroBundle } from '../utils';
|
|
import { GraphicAssetCollection } from './GraphicAssetCollection';
|
|
import { IAssetData } from './IAssetData';
|
|
import { IAssetManager } from './IAssetManager';
|
|
import { IGraphicAsset } from './IGraphicAsset';
|
|
import { IGraphicAssetCollection } from './IGraphicAssetCollection';
|
|
|
|
export class AssetManager implements IAssetManager
|
|
{
|
|
public static _INSTANCE: IAssetManager = new AssetManager();
|
|
|
|
private _textures: Map<string, Texture<Resource>> = new Map();
|
|
private _collections: Map<string, IGraphicAssetCollection> = new Map();
|
|
|
|
public getTexture(name: string): Texture<Resource>
|
|
{
|
|
if(!name) return null;
|
|
|
|
const existing = this._textures.get(name);
|
|
|
|
if(!existing) return null;
|
|
|
|
return existing;
|
|
}
|
|
|
|
public setTexture(name: string, texture: Texture<Resource>): void
|
|
{
|
|
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);
|
|
}
|
|
|
|
return collection;
|
|
}
|
|
|
|
public async downloadAsset(url: string): Promise<boolean>
|
|
{
|
|
return await this.downloadAssets([url]);
|
|
}
|
|
|
|
public async downloadAssets(urls: string[]): Promise<boolean>
|
|
{
|
|
if(!urls || !urls.length) return true;
|
|
|
|
const responses = await Promise.all(urls.map(url => fetch(url)));
|
|
|
|
if(!responses || !responses.length) return false;
|
|
|
|
try
|
|
{
|
|
for(const response of responses)
|
|
{
|
|
const contentType = response.headers.get('Content-Type');
|
|
|
|
switch(contentType)
|
|
{
|
|
case 'application/octet-stream': {
|
|
const nitroBundle = new NitroBundle(await response.arrayBuffer());
|
|
|
|
await this.processAsset(nitroBundle.baseTexture, (nitroBundle.jsonFile as IAssetData));
|
|
break;
|
|
}
|
|
case 'image/png':
|
|
case 'image/jpeg':
|
|
case 'image/gif': {
|
|
const base64 = ArrayBufferToBase64(await response.arrayBuffer());
|
|
const baseTexture = BaseTexture.from(`data:${contentType};base64,${base64}`);
|
|
|
|
const createAsset = async () =>
|
|
{
|
|
const texture = new Texture(baseTexture);
|
|
|
|
this.setTexture(response.url, texture);
|
|
};
|
|
|
|
if(baseTexture.valid)
|
|
{
|
|
await createAsset();
|
|
}
|
|
else
|
|
{
|
|
await new Promise<void>((resolve, reject) =>
|
|
{
|
|
baseTexture.once('update', async () =>
|
|
{
|
|
await createAsset();
|
|
|
|
return resolve();
|
|
});
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
catch (err)
|
|
{
|
|
console.error(err);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private async processAsset(baseTexture: BaseTexture, data: IAssetData): Promise<void>
|
|
{
|
|
const spritesheetData = data.spritesheet;
|
|
|
|
if(!baseTexture || !spritesheetData || !Object.keys(spritesheetData).length)
|
|
{
|
|
this.createCollection(data, null);
|
|
|
|
return;
|
|
}
|
|
|
|
const createAsset = async () =>
|
|
{
|
|
const spritesheet = new Spritesheet(baseTexture, spritesheetData);
|
|
|
|
return new Promise<void>((resolve, reject) =>
|
|
{
|
|
spritesheet.parse(() =>
|
|
{
|
|
this.createCollection(data, spritesheet);
|
|
|
|
return resolve();
|
|
});
|
|
});
|
|
};
|
|
|
|
if(baseTexture.valid)
|
|
{
|
|
await createAsset();
|
|
}
|
|
else
|
|
{
|
|
await new Promise<void>((resolve, reject) =>
|
|
{
|
|
baseTexture.once('update', async () =>
|
|
{
|
|
await createAsset();
|
|
|
|
return resolve();
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
public get collections(): Map<string, IGraphicAssetCollection>
|
|
{
|
|
return this._collections;
|
|
}
|
|
}
|