@bscotch/gml-parser
Version:
A parser for GML (GameMaker Language) files for programmatic manipulation and analysis of GameMaker projects.
64 lines • 2.85 kB
JavaScript
import { pathy } from '@bscotch/pathy';
import { assert } from './util.js';
export class Spine {
path;
_content;
constructor(path) {
this.path = pathy(path);
assert(this.path.hasExtension('json'), `Spine file must be a JSON file: ${this.path}`);
}
/**
* Compute a simplified summary of the Spine content
* for use in the Sprite Editor UI.
*/
async summarize() {
const content = await this.getContent();
return {
skinNames: content.skins?.map((skin) => skin.name) || [],
eventNames: Object.keys(content.events || {}),
slotNames: content.slots?.map((slot) => slot.name) || [],
animations: Object.keys(content.animations || {}).map((animationName) => {
const animation = content.animations[animationName];
const summary = {
name: animationName,
duration: recursivelyFindMaxTime(animation),
events: animation.events || [],
};
return summary;
}),
};
}
async getContent() {
if (!this._content) {
await this.reload();
}
return this._content;
}
async reload() {
assert(await this.path.exists(), `Spine file does not exist: ${this.path}`);
const content = await this.path.read();
assert(content && content.skeleton && content.skeleton.spine, `Spine file does not have a valid 'skeleton/spine' path: ${this.path}`);
assert(!content.bones || Array.isArray(content.bones), `Spine file has invalid 'bones' data: ${this.path}`);
assert(!content.slots || Array.isArray(content.slots), `Spine file has invalid 'slots' data: ${this.path}`);
assert(!content.skins || Array.isArray(content.skins), `Spine file has invalid 'skins' data: ${this.path}`);
assert(!content.events ||
(typeof content.events === 'object' && !Array.isArray(content.events)), `Spine file has invalid 'events' data: ${this.path}`);
assert(!content.animations ||
(typeof content.animations === 'object' &&
!Array.isArray(content.animations)), `Spine file has invalid 'animations' data: ${this.path}`);
this._content = content;
}
}
function recursivelyFindMaxTime(data, current_max = 0) {
if (typeof data !== 'object' || data === null) {
return current_max;
}
if (Array.isArray(data)) {
return Math.max(...data.map((d) => recursivelyFindMaxTime(d, current_max)), current_max);
}
if ('time' in data && typeof data.time === 'number') {
return Math.max(data.time, current_max);
}
return Math.max(...Object.values(data).map((d) => recursivelyFindMaxTime(d, current_max)), current_max);
}
//# sourceMappingURL=spine.js.map