Created
August 16, 2019 09:27
-
-
Save TimvanScherpenzeel/5ac2871df7a5cf13d3576a8d93cc67c7 to your computer and use it in GitHub Desktop.
Loading a .binpack file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private loadBinpack = (item: ILoadItem): Promise<any> => | |
this.loadArrayBuffer(item).then((data: TVoidable<ArrayBuffer>): any => { | |
if (data) { | |
let content = null; | |
let contentArray = null; | |
let binaryChunk: TNullable<ArrayBuffer> = null; | |
let byteOffset = null; | |
let chunkIndex = 0; | |
let chunkLength = 0; | |
let chunkType = null; | |
const headerMagic = new Uint8Array(data, 0, 4).reduce( | |
(magic, char) => (magic += String.fromCharCode(char)), | |
'' | |
); | |
assert(headerMagic === 'BINP', 'AssetLoader -> Unsupported Binpacker header'); | |
const chunkView = new DataView(data, 12); | |
while (chunkIndex < chunkView.byteLength) { | |
chunkLength = chunkView.getUint32(chunkIndex, true); | |
chunkIndex += 4; | |
chunkType = chunkView.getUint32(chunkIndex, true); | |
chunkIndex += 4; | |
if (chunkType === 0x4e4f534a) { | |
contentArray = new Uint8Array(data, 12 + chunkIndex, chunkLength); | |
content = contentArray.reduce((str, char) => (str += String.fromCharCode(char)), ''); | |
} else if (chunkType === 0x004e4942) { | |
byteOffset = 12 + chunkIndex; | |
binaryChunk = data.slice(byteOffset, byteOffset + chunkLength); | |
} | |
chunkIndex += chunkLength; | |
} | |
assert(content !== null, 'AssetLoader -> JSON content chunk not found'); | |
if (content && binaryChunk) { | |
const jsonChunk = JSON.parse(content); | |
return Promise.resolve( | |
Promise.all( | |
jsonChunk.map( | |
(entry: { | |
name: string; | |
mimeType: string; | |
bufferStart: number; | |
bufferEnd: number; | |
}) => { | |
const { name, mimeType } = entry; | |
const binary = | |
binaryChunk && binaryChunk.slice(entry.bufferStart, entry.bufferEnd); | |
assert(binary !== null, 'AssetLoader -> Binary content chunk not found'); | |
const blob = | |
binary && | |
new Blob([new Uint8Array(binary)], { | |
type: mimeType, | |
}); | |
const loaderType = this.getLoaderByFileExtension(name); | |
const url = URL.createObjectURL(blob); | |
assert( | |
loaderType === ELoaderKey.JSON || | |
loaderType === ELoaderKey.Text || | |
loaderType === ELoaderKey.Image || | |
loaderType === ELoaderKey.XML, | |
'AssetLoader -> Binpack currently only supports JSON, plain text, XML (SVG) and images' | |
); | |
switch (loaderType) { | |
case ELoaderKey.JSON: | |
return { id: name, src: this.loadJSON({ src: url, id: name }) }; | |
case ELoaderKey.Text: | |
return { id: name, src: this.loadText({ src: url, id: name }) }; | |
case ELoaderKey.XML: | |
return { id: name, src: this.loadXML({ src: url, id: name }) }; | |
case ELoaderKey.Image: | |
default: | |
return { id: name, src: this.loadImage({ src: url, id: name }) }; | |
} | |
} | |
) | |
).then((assets: any) => | |
Object.assign({}, ...assets.map((asset: any) => { | |
return { [asset.id]: asset.src }; | |
})) | |
) | |
); | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment