mirror of
https://github.com/billsonnn/nitro-renderer.git
synced 2024-11-26 17:30:52 +01:00
Update asset loader to async
This commit is contained in:
parent
206c5eaa1c
commit
c21eb0e699
@ -1,7 +1,5 @@
|
||||
import { BaseTexture, Resource, Texture } from '@pixi/core';
|
||||
import { Loader, LoaderResource } from '@pixi/loaders';
|
||||
import { Spritesheet } from '@pixi/spritesheet';
|
||||
import { NitroLogger } from '../common';
|
||||
import { ArrayBufferToBase64, NitroBundle } from '../utils';
|
||||
import { GraphicAssetCollection } from './GraphicAssetCollection';
|
||||
import { IAssetData } from './IAssetData';
|
||||
@ -79,123 +77,77 @@ export class AssetManager implements IAssetManager
|
||||
return collection;
|
||||
}
|
||||
|
||||
public downloadAsset(assetUrl: string, cb: (status: boolean) => void): void
|
||||
public async downloadAsset(url: string): Promise<boolean>
|
||||
{
|
||||
this.downloadAssets([assetUrl], cb);
|
||||
return await this.downloadAssets([url]);
|
||||
}
|
||||
|
||||
public downloadAssets(assetUrls: string[], cb: (status: boolean) => void): void
|
||||
public async downloadAssets(urls: string[]): Promise<boolean>
|
||||
{
|
||||
if(!assetUrls || !assetUrls.length)
|
||||
if(!urls || !urls.length) return true;
|
||||
|
||||
const responses = await Promise.all(urls.map(url => fetch(url)));
|
||||
|
||||
if(!responses || !responses.length) return false;
|
||||
|
||||
try
|
||||
{
|
||||
cb(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const loader = new Loader();
|
||||
|
||||
for(const url of assetUrls)
|
||||
{
|
||||
if(!url) continue;
|
||||
|
||||
loader
|
||||
.add({
|
||||
url,
|
||||
crossOrigin: 'anonymous',
|
||||
loadType: LoaderResource.LOAD_TYPE.XHR,
|
||||
xhrType: LoaderResource.XHR_RESPONSE_TYPE.BUFFER
|
||||
});
|
||||
}
|
||||
|
||||
let remaining = assetUrls.length;
|
||||
|
||||
const onDownloaded = (status: boolean, url: string) =>
|
||||
{
|
||||
if(!status)
|
||||
for(const response of responses)
|
||||
{
|
||||
NitroLogger.error('Failed to download asset', url);
|
||||
const contentType = response.headers.get('Content-Type');
|
||||
|
||||
loader.destroy();
|
||||
|
||||
cb(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
remaining--;
|
||||
|
||||
if(!remaining)
|
||||
{
|
||||
loader.destroy();
|
||||
|
||||
cb(true);
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
loader.load((loader, resources) =>
|
||||
{
|
||||
for(const key in resources)
|
||||
{
|
||||
const resource = resources[key];
|
||||
|
||||
if(!resource || resource.error || !resource.xhr)
|
||||
switch(contentType)
|
||||
{
|
||||
onDownloaded(false, resource.url);
|
||||
case 'application/octet-stream': {
|
||||
const nitroBundle = new NitroBundle(await response.arrayBuffer());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const resourceType = (resource.xhr.getResponseHeader('Content-Type') || 'application/octet-stream');
|
||||
|
||||
if(resourceType === 'application/octet-stream')
|
||||
{
|
||||
const nitroBundle = new NitroBundle(resource.data);
|
||||
|
||||
this.processAsset(nitroBundle.baseTexture, (nitroBundle.jsonFile as IAssetData), status =>
|
||||
{
|
||||
onDownloaded(status, resource.url);
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if((resourceType === 'image/png') || (resourceType === 'image/jpeg') || (resourceType === 'image/gif'))
|
||||
{
|
||||
const base64 = ArrayBufferToBase64(resource.data);
|
||||
const baseTexture = new BaseTexture(`data:${resourceType};base64,${base64}`);
|
||||
|
||||
if(baseTexture.valid)
|
||||
{
|
||||
const texture = new Texture(baseTexture);
|
||||
|
||||
this.setTexture(resource.name, texture);
|
||||
|
||||
onDownloaded(true, resource.url);
|
||||
await this.processAsset(nitroBundle.baseTexture, (nitroBundle.jsonFile as IAssetData));
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseTexture.once('update', () =>
|
||||
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(resource.name, texture);
|
||||
this.setTexture(response.url, texture);
|
||||
};
|
||||
|
||||
onDownloaded(true, resource.url);
|
||||
});
|
||||
if(baseTexture.valid)
|
||||
{
|
||||
await createAsset();
|
||||
}
|
||||
else
|
||||
{
|
||||
await new Promise<void>((resolve, reject) =>
|
||||
{
|
||||
baseTexture.once('update', async () =>
|
||||
{
|
||||
await createAsset();
|
||||
|
||||
return resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
onDownloaded(false, resource.url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
catch (err)
|
||||
{
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private processAsset(baseTexture: BaseTexture, data: IAssetData, onDownloaded: (status: boolean) => void): void
|
||||
private async processAsset(baseTexture: BaseTexture, data: IAssetData): Promise<void>
|
||||
{
|
||||
const spritesheetData = data.spritesheet;
|
||||
|
||||
@ -203,30 +155,39 @@ export class AssetManager implements IAssetManager
|
||||
{
|
||||
this.createCollection(data, null);
|
||||
|
||||
onDownloaded(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const createAsset = () =>
|
||||
const createAsset = async () =>
|
||||
{
|
||||
const spritesheet = new Spritesheet(baseTexture, spritesheetData);
|
||||
|
||||
spritesheet.parse(() =>
|
||||
return new Promise<void>((resolve, reject) =>
|
||||
{
|
||||
this.createCollection(data, spritesheet);
|
||||
spritesheet.parse(() =>
|
||||
{
|
||||
this.createCollection(data, spritesheet);
|
||||
|
||||
onDownloaded(true);
|
||||
return resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if(baseTexture.valid)
|
||||
{
|
||||
createAsset();
|
||||
await createAsset();
|
||||
}
|
||||
else
|
||||
{
|
||||
baseTexture.once('update', () => createAsset());
|
||||
await new Promise<void>((resolve, reject) =>
|
||||
{
|
||||
baseTexture.once('update', async () =>
|
||||
{
|
||||
await createAsset();
|
||||
|
||||
return resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ export interface IAssetManager
|
||||
getAsset(name: string): IGraphicAsset;
|
||||
getCollection(name: string): IGraphicAssetCollection;
|
||||
createCollection(data: IAssetData, spritesheet: Spritesheet): IGraphicAssetCollection;
|
||||
downloadAssets(urls: string[], cb: Function): void;
|
||||
downloadAsset(url: string, cb: Function): void;
|
||||
downloadAssets(urls: string[]): Promise<boolean>;
|
||||
downloadAsset(url: string): Promise<boolean>;
|
||||
collections: Map<string, IGraphicAssetCollection>;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ export class AvatarAssetDownloadLibrary extends EventDispatcher implements IAvat
|
||||
if(asset) this._state = AvatarAssetDownloadLibrary.LOADED;
|
||||
}
|
||||
|
||||
public downloadAsset(): void
|
||||
public async downloadAsset(): Promise<void>
|
||||
{
|
||||
if(!this._assets || (this._state === AvatarAssetDownloadLibrary.LOADING) || (this._state === AvatarAssetDownloadLibrary.LOADED)) return;
|
||||
|
||||
@ -51,15 +51,13 @@ export class AvatarAssetDownloadLibrary extends EventDispatcher implements IAvat
|
||||
|
||||
this._state = AvatarAssetDownloadLibrary.LOADING;
|
||||
|
||||
this._assets.downloadAsset(this._downloadUrl, (flag: boolean) =>
|
||||
{
|
||||
if(flag)
|
||||
{
|
||||
this._state = AvatarAssetDownloadLibrary.LOADED;
|
||||
const status = await this._assets.downloadAsset(this._downloadUrl);
|
||||
|
||||
this.dispatchEvent(new AvatarRenderLibraryEvent(AvatarRenderLibraryEvent.DOWNLOAD_COMPLETE, this));
|
||||
}
|
||||
});
|
||||
if(!status) return;
|
||||
|
||||
this._state = AvatarAssetDownloadLibrary.LOADED;
|
||||
|
||||
this.dispatchEvent(new AvatarRenderLibraryEvent(AvatarRenderLibraryEvent.DOWNLOAD_COMPLETE, this));
|
||||
}
|
||||
|
||||
public get libraryName(): string
|
||||
|
@ -36,7 +36,7 @@ export class EffectAssetDownloadLibrary extends EventDispatcher implements IEffe
|
||||
if(asset) this._state = EffectAssetDownloadLibrary.LOADED;
|
||||
}
|
||||
|
||||
public downloadAsset(): void
|
||||
public async downloadAsset(): Promise<void>
|
||||
{
|
||||
if(!this._assets || (this._state === EffectAssetDownloadLibrary.LOADING) || (this._state === EffectAssetDownloadLibrary.LOADED)) return;
|
||||
|
||||
@ -53,19 +53,17 @@ export class EffectAssetDownloadLibrary extends EventDispatcher implements IEffe
|
||||
|
||||
this._state = EffectAssetDownloadLibrary.LOADING;
|
||||
|
||||
this._assets.downloadAsset(this._downloadUrl, (flag: boolean) =>
|
||||
{
|
||||
if(flag)
|
||||
{
|
||||
this._state = EffectAssetDownloadLibrary.LOADED;
|
||||
const status = await this._assets.downloadAsset(this._downloadUrl);
|
||||
|
||||
const collection = this._assets.getCollection(this._libraryName);
|
||||
if(!status) return;
|
||||
|
||||
if(collection) this._animation = collection.data.animations;
|
||||
this._state = EffectAssetDownloadLibrary.LOADED;
|
||||
|
||||
this.dispatchEvent(new AvatarRenderEffectLibraryEvent(AvatarRenderEffectLibraryEvent.DOWNLOAD_COMPLETE, this));
|
||||
}
|
||||
});
|
||||
const collection = this._assets.getCollection(this._libraryName);
|
||||
|
||||
if(collection) this._animation = collection.data.animations;
|
||||
|
||||
this.dispatchEvent(new AvatarRenderEffectLibraryEvent(AvatarRenderEffectLibraryEvent.DOWNLOAD_COMPLETE, this));
|
||||
}
|
||||
|
||||
public get libraryName(): string
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { BaseTexture, Resource, Texture } from '@pixi/core';
|
||||
import { Loader, LoaderResource } from '@pixi/loaders';
|
||||
import { Spritesheet } from '@pixi/spritesheet';
|
||||
import { FurnitureType, GetAssetManager, GraphicAssetCollection, GraphicAssetGifCollection, IAssetData, IEventDispatcher, IFurnitureData, IFurnitureDataListener, IGraphicAssetCollection, IGraphicAssetGifCollection, IPetColorResult, IRoomContentListener, IRoomContentLoader, IRoomObject, ISessionDataManager, NitroBundle, NitroConfiguration, NitroLogger, RoomObjectCategory, RoomObjectUserType, RoomObjectVariable, RoomObjectVisualizationType } from '../../api';
|
||||
import { NitroEvent } from '../../events';
|
||||
@ -481,94 +480,48 @@ export class RoomContentLoader implements IFurnitureDataListener, IRoomContentLo
|
||||
return false;
|
||||
}
|
||||
|
||||
public downloadAsset(type: string, events: IEventDispatcher): void
|
||||
public async downloadAsset(type: string, events: IEventDispatcher): Promise<void>
|
||||
{
|
||||
const assetUrls: string[] = this.getAssetUrls(type);
|
||||
const assetUrl: string = this.getAssetUrls(type)?.[0];
|
||||
|
||||
if(!assetUrls || !assetUrls.length) return;
|
||||
if(!assetUrl || !assetUrl.length) return;
|
||||
|
||||
if((this._pendingContentTypes.indexOf(type) >= 0) || this.getOrRemoveEventDispatcher(type)) return;
|
||||
|
||||
this._pendingContentTypes.push(type);
|
||||
this._events.set(type, events);
|
||||
|
||||
const loader = new Loader();
|
||||
|
||||
for(const url of assetUrls)
|
||||
try
|
||||
{
|
||||
if(!url || !url.length) continue;
|
||||
const response = await fetch(assetUrl);
|
||||
const contentType = response.headers.get('Content-Type');
|
||||
|
||||
loader
|
||||
.add({
|
||||
url,
|
||||
crossOrigin: 'anonymous',
|
||||
loadType: LoaderResource.LOAD_TYPE.XHR,
|
||||
xhrType: LoaderResource.XHR_RESPONSE_TYPE.BUFFER
|
||||
});
|
||||
switch(contentType)
|
||||
{
|
||||
case 'application/octet-stream': {
|
||||
const nitroBundle = new NitroBundle(await response.arrayBuffer());
|
||||
|
||||
await this.processAsset(nitroBundle.baseTexture, (nitroBundle.jsonFile as IAssetData));
|
||||
|
||||
const events = this._events.get(type);
|
||||
|
||||
if(!events) return;
|
||||
|
||||
events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_SUCCESS, type));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
let remaining = assetUrls.length;
|
||||
|
||||
const onDownloaded = (status: boolean, url: string) =>
|
||||
catch (err)
|
||||
{
|
||||
if(!status)
|
||||
{
|
||||
NitroLogger.error('Failed to download asset', url);
|
||||
|
||||
loader.destroy();
|
||||
|
||||
events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_FAILURE, type));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
remaining--;
|
||||
|
||||
if(!remaining)
|
||||
{
|
||||
loader.destroy();
|
||||
|
||||
const events = this._events.get(type);
|
||||
|
||||
if(!events) return;
|
||||
|
||||
events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_SUCCESS, type));
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
loader.load((loader, resources) =>
|
||||
{
|
||||
for(const key in resources)
|
||||
{
|
||||
const resource = resources[key];
|
||||
|
||||
if(!resource || resource.error || !resource.xhr)
|
||||
{
|
||||
onDownloaded(false, resource.url);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const resourceType = (resource.xhr.getResponseHeader('Content-Type') || 'application/octet-stream');
|
||||
|
||||
if(resourceType === 'application/octet-stream')
|
||||
{
|
||||
const nitroBundle = new NitroBundle(resource.data);
|
||||
|
||||
this.processAsset(nitroBundle.baseTexture, (nitroBundle.jsonFile as IAssetData), status =>
|
||||
{
|
||||
onDownloaded(status, resource.url);
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
});
|
||||
events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_FAILURE, type));
|
||||
}
|
||||
}
|
||||
|
||||
private processAsset(baseTexture: BaseTexture, data: IAssetData, onDownloaded: (status: boolean) => void): void
|
||||
private async processAsset(baseTexture: BaseTexture, data: IAssetData): Promise<void>
|
||||
{
|
||||
const spritesheetData = data.spritesheet;
|
||||
|
||||
@ -576,30 +529,39 @@ export class RoomContentLoader implements IFurnitureDataListener, IRoomContentLo
|
||||
{
|
||||
this.createCollection(data, null);
|
||||
|
||||
onDownloaded(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const createAsset = () =>
|
||||
const createAsset = async () =>
|
||||
{
|
||||
const spritesheet = new Spritesheet(baseTexture, spritesheetData);
|
||||
|
||||
spritesheet.parse(() =>
|
||||
return new Promise<void>((resolve, reject) =>
|
||||
{
|
||||
this.createCollection(data, spritesheet);
|
||||
spritesheet.parse(() =>
|
||||
{
|
||||
this.createCollection(data, spritesheet);
|
||||
|
||||
onDownloaded(true);
|
||||
return resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if(baseTexture.valid)
|
||||
{
|
||||
createAsset();
|
||||
await createAsset();
|
||||
}
|
||||
else
|
||||
{
|
||||
baseTexture.once('update', () => createAsset());
|
||||
await new Promise<void>((resolve, reject) =>
|
||||
{
|
||||
baseTexture.once('update', async () =>
|
||||
{
|
||||
await createAsset();
|
||||
|
||||
return resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ export class FurnitureRoomBrandingLogic extends FurnitureLogic
|
||||
super.mouseEvent(event, geometry);
|
||||
}
|
||||
|
||||
private downloadBackground(): void
|
||||
private async downloadBackground(): Promise<void>
|
||||
{
|
||||
const model = this.object && this.object.model;
|
||||
|
||||
@ -216,17 +216,16 @@ export class FurnitureRoomBrandingLogic extends FurnitureLogic
|
||||
|
||||
if(!texture)
|
||||
{
|
||||
asset.downloadAsset(imageUrl, (flag: boolean) =>
|
||||
const status = await asset.downloadAsset(imageUrl);
|
||||
|
||||
if(!status)
|
||||
{
|
||||
if(flag)
|
||||
{
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADING_FAILED));
|
||||
}
|
||||
});
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADING_FAILED));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { RenderTexture, Resource, Texture } from '@pixi/core';
|
||||
import { Resource, Texture } from '@pixi/core';
|
||||
import { Matrix } from '@pixi/math';
|
||||
import { IGraphicAsset, IRoomObjectSprite, RoomObjectVariable } from '../../../../../api';
|
||||
import { NitroSprite, PixiApplicationProxy } from '../../../../../pixi-proxy';
|
||||
import { NitroSprite, TextureUtils } from '../../../../../pixi-proxy';
|
||||
import { IsometricImageFurniVisualization } from './IsometricImageFurniVisualization';
|
||||
|
||||
export class FurnitureGuildIsometricBadgeVisualization extends IsometricImageFurniVisualization
|
||||
@ -42,8 +42,6 @@ export class FurnitureGuildIsometricBadgeVisualization extends IsometricImageFur
|
||||
const matrix = new Matrix();
|
||||
const difference = (asset.width / texture.width);
|
||||
|
||||
console.log(((0.5 * difference) * texture.width));
|
||||
|
||||
switch(this.direction)
|
||||
{
|
||||
case 2:
|
||||
@ -52,7 +50,7 @@ export class FurnitureGuildIsometricBadgeVisualization extends IsometricImageFur
|
||||
matrix.c = 0;
|
||||
matrix.d = (difference * scale);
|
||||
matrix.tx = 0;
|
||||
matrix.ty = 20;
|
||||
matrix.ty = ((0.5 * difference) * texture.width);
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
@ -74,18 +72,40 @@ export class FurnitureGuildIsometricBadgeVisualization extends IsometricImageFur
|
||||
|
||||
const sprite = new NitroSprite(texture);
|
||||
|
||||
sprite.transform.setFromMatrix(matrix);
|
||||
|
||||
sprite.position.set(0);
|
||||
|
||||
return TextureUtils.generateTexture(sprite);
|
||||
|
||||
/* const renderTexture = RenderTexture.create({
|
||||
width: asset.width,
|
||||
height: asset.height
|
||||
});
|
||||
|
||||
PixiApplicationProxy.instance.renderer.render(sprite, {
|
||||
renderTexture,
|
||||
clear: true,
|
||||
});
|
||||
|
||||
return renderTexture; */
|
||||
|
||||
/* const sprite = new NitroSprite(texture);
|
||||
|
||||
const renderTexture = RenderTexture.create({
|
||||
width: (asset.width + matrix.tx),
|
||||
height: (asset.height + matrix.ty)
|
||||
});
|
||||
|
||||
sprite.position.set(0)
|
||||
|
||||
PixiApplicationProxy.instance.renderer.render(sprite, {
|
||||
renderTexture,
|
||||
clear: true,
|
||||
transform: matrix
|
||||
});
|
||||
|
||||
return renderTexture;
|
||||
return renderTexture; */
|
||||
}
|
||||
|
||||
protected getLayerColor(scale: number, layerId: number, colorId: number): number
|
||||
|
@ -106,17 +106,22 @@ export class BadgeImageManager implements IDisposable
|
||||
|
||||
this._requestedBadges.set(badgeName, true);
|
||||
|
||||
this._assets.downloadAsset(url, (flag: boolean) =>
|
||||
{
|
||||
if(flag)
|
||||
this._assets
|
||||
.downloadAsset(url)
|
||||
.then(status =>
|
||||
{
|
||||
if(!status) return;
|
||||
|
||||
this._requestedBadges.delete(badgeName);
|
||||
|
||||
const texture = this._assets.getTexture(url);
|
||||
|
||||
if(texture && this._sessionDataManager) this._sessionDataManager.events.dispatchEvent(new BadgeImageReadyEvent(badgeName, texture.clone()));
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(err =>
|
||||
{
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
else if(type === BadgeImageManager.GROUP_BADGE)
|
||||
|
Loading…
Reference in New Issue
Block a user