@awayjs/stage
Version:
Stage for AwayJS
154 lines (129 loc) • 4.95 kB
text/typescript
import { Rectangle, URLLoaderDataFormat, URLRequest, ParserBase, ParserUtils, ResourceDependency, XmlUtils } from '@awayjs/core';
import { ImageSampler } from '../image/ImageSampler';
import { BitmapImage2D } from '../image/BitmapImage2D';
/**
* TextureAtlasParser provides a "parser" for natively supported image types (jpg, png). While it simply loads bytes into
* a loader object, it wraps it in a BitmapImage2DResource so resource management can happen consistently without
* exception cases.
*/
export class TextureAtlasParser extends ParserBase {
private _doc: Node;
private _imagePath: string;
private _imageData: BitmapImage2D;
private _subTextureNodes: NodeList;
private _parseState: TextureAtlasParserState = TextureAtlasParserState.PARSE_XML;
/**
* Creates a new TextureAtlasParser object.
* @param uri The url or id of the data or file to be parsed.
* @param extra The holder for extra contextual data that the parser might need.
*/
constructor() {
super(URLLoaderDataFormat.TEXT);
}
/**
* Indicates whether or not a given file extension is supported by the parser.
* @param extension The file extension of a potential file to be parsed.
* @return Whether or not the given file type is supported.
*/
public static supportsType(extension: string): boolean {
extension = extension.toLowerCase();
return extension == 'xml';
}
/**
* Tests whether a data block can be parsed by the parser.
* @param data The data block to potentially be parsed.
* @return Whether or not the given data is supported.
*/
public static supportsData(data: any): boolean {
try {
const content: string = ParserUtils.toString(data);
if (content.indexOf('TextureAtlas') != -1 || content.indexOf('textureatlas') != -1)
return true;
return false;
} catch (e) {
return false;
}
}
/**
* @inheritDoc
*/
public resolveDependency(resourceDependency: ResourceDependency): void {
if (resourceDependency.assets.length) {
this._imageData = <BitmapImage2D> resourceDependency.assets[0];
this.finalizeAsset(this._imageData);
this._parseState = TextureAtlasParserState.PARSE_SUBTEXTURES;
} else {
this._parseState = TextureAtlasParserState.PARSE_COMPLETE;
}
}
/**
* @inheritDoc
*/
public resolveDependencyFailure(resourceDependency: ResourceDependency): void {
this._parseState = TextureAtlasParserState.PARSE_COMPLETE;
}
/**
* @inheritDoc
*/
protected proceedParsing(): void {
switch (this._parseState) {
case TextureAtlasParserState.PARSE_XML:
try {
this._doc = XmlUtils.getChildrenWithTag(XmlUtils.strToXml(this.getTextData()), 'TextureAtlas')[0];
this._imagePath = XmlUtils.readAttributeValue(this._doc, 'imagePath');
this._subTextureNodes = XmlUtils.getChildrenWithTag(this._doc, 'SubTexture');
this._parseState = TextureAtlasParserState.PARSE_IMAGE;
if (this.hasTime())
this.proceedParsing();
} catch (Error) {
this.dieWithError('TextureAtlasParser Error parsing XML');
}
break;
case TextureAtlasParserState.PARSE_IMAGE:
if (this._imagePath) {
this.addDependency(this._imagePath, new URLRequest(this._imagePath));
this.pauseAndRetrieveDependencies();
} else {
this.dieWithError('TextureAtlasParser Missing imagePath attribute in XML');
}
break;
case TextureAtlasParserState.PARSE_SUBTEXTURES:
var sampler: ImageSampler;
var element: Node;
var x: string;
var y: string;
var width: string;
var height: string;
var len: number = this._subTextureNodes.length;
for (let i: number = 0; i < len; i++) {
element = this._subTextureNodes[i];
sampler = new ImageSampler();
//setup subtexture rect
x = XmlUtils.readAttributeValue(element, 'x');
y = XmlUtils.readAttributeValue(element, 'y');
width = XmlUtils.readAttributeValue(element, 'width');
height = XmlUtils.readAttributeValue(element, 'height');
if (x || y || width || height)
sampler.imageRect = new Rectangle(parseInt(x) / this._imageData.width, parseInt(y) / this._imageData.height, parseInt(width) / this._imageData.width, parseInt(height) / this._imageData.height);
//setup frame rect
x = XmlUtils.readAttributeValue(element, 'frameX');
y = XmlUtils.readAttributeValue(element, 'frameY');
width = XmlUtils.readAttributeValue(element, 'frameWidth');
height = XmlUtils.readAttributeValue(element, 'frameHeight');
if (x || y || width || height)
sampler.frameRect = new Rectangle(parseInt(x), parseInt(y), parseInt(width), parseInt(height));
this.finalizeAsset(sampler, XmlUtils.readAttributeValue(element, 'name'));
}
this._parseState = TextureAtlasParserState.PARSE_COMPLETE;
break;
case TextureAtlasParserState.PARSE_COMPLETE:
return this.finishParsing();
}
}
}
enum TextureAtlasParserState {
PARSE_XML,
PARSE_IMAGE,
PARSE_SUBTEXTURES,
PARSE_COMPLETE,
}