UNPKG

mdx-m3-viewer

Version:

A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.

210 lines 7.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TriggerData = void 0; const tokenstream_1 = require("../../../utils/jass2/tokenstream"); const file_1 = require("../../ini/file"); /** * Trigger data needed to load a WTG file. */ class TriggerData { constructor() { this.types = {}; this.functions = [{}, {}, {}, {}]; this.presets = {}; this.externalTypes = {}; this.externalFunctions = [{}, {}, {}, {}]; this.externalPresets = {}; } addTriggerData(buffer, isExternal) { let types = this.types; let functions = this.functions; let presets = this.presets; if (isExternal) { types = this.externalTypes; functions = this.externalFunctions; presets = this.externalPresets; } const triggerData = new file_1.IniFile(); triggerData.load(buffer); let section = triggerData.getSection('TriggerTypes'); if (section) { this.addTriggerTypes(types, section); } section = triggerData.getSection('TriggerEvents'); if (section) { this.addTriggerDataFunctions(functions[0], section, 1); } section = triggerData.getSection('TriggerConditions'); if (section) { this.addTriggerDataFunctions(functions[1], section, 1); } section = triggerData.getSection('TriggerActions'); if (section) { this.addTriggerDataFunctions(functions[2], section, 1); } section = triggerData.getSection('TriggerCalls'); if (section) { this.addTriggerDataFunctions(functions[3], section, 3); } section = triggerData.getSection('TriggerParams'); if (section) { this.addTriggerDataPresets(presets, section); } } addTriggerTypes(types, section) { for (const [key, value] of section) { // We know the values are going to be strings. const tokens = value.split(','); types[key.toLowerCase()] = tokens[4] || ''; } } addTriggerDataFunctions(functions, section, skipped) { for (const [key, value] of section) { // We don't care about metadata lines. if (key[0] !== '_') { // We know the values are going to be strings. const tokens = value.split(','); const args = []; // Can be used by actions to make aliases. const scriptName = section.get(`_${key}_scriptname`) || null; let returnType = null; // TriggerCalls have a return type. if (skipped === 3) { returnType = tokens[2]; } for (let i = skipped, l = tokens.length; i < l; i++) { const token = tokens[i]; // We don't care about constants. if (Number.isNaN(parseFloat(token)) && token !== 'nothing' && token !== '') { args.push(token); } } functions[key.toLowerCase()] = { args, scriptName, returnType }; } } } addTriggerDataPresets(presets, section) { for (const [key, value] of section) { // We know the values are going to be strings. const tokens = value.split(','); // Note that the operators are enclosed by "" for some reason. // Note that string literals are enclosed by backticks. presets[key.toLowerCase()] = tokens[2].replace(/"/g, '').replace(/`/g, '"'); } } addJassFunctions(jass) { const stream = new tokenstream_1.default(jass); let token; while ((token = stream.read()) !== undefined) { if (token === 'native' || token === 'function') { const scriptName = stream.read(); if (scriptName) { token = stream.read(); if (token === 'takes') { const args = []; const token = stream.readSafe(); // nothing or type if (token !== 'nothing') { args.push(token); stream.readSafe(); while (stream.read() === ',') { args.push(stream.readSafe()); stream.readSafe(); } } else { stream.read(); // returns } let returnType = stream.readSafe(); if (returnType === 'nothing') { returnType = null; } const name = scriptName.toLowerCase(); const signature = { args, scriptName, returnType }; // There is no way to know if this signature could be used as a TriggerAction or TriggerCall. // So try to always add to TriggerAction... this.externalFunctions[2][name] = signature; // ...and if there is a return type, add also to TriggerCall. if (returnType !== 'nothing') { this.externalFunctions[3][name] = signature; } } } } } } /** * Given a type, return its base type. * * Returns the given type if its not a child type. */ getBaseType(type) { type = type.toLowerCase(); let base = this.types[type]; if (base === undefined) { base = this.externalTypes[type]; } // Same as !base, but be explicit to be clearer. if (base === '' || base === undefined) { return type; } return base; } isBaseFunction(type, name) { name = name.toLowerCase(); if (this.functions[type][name]) { return true; } return false; } /** * Gets the signature of the given function. */ getFunction(type, name) { name = name.toLowerCase(); let args = this.functions[type][name]; if (!args) { args = this.externalFunctions[type][name]; } return args; } /** * Get the type of a function given its name. * Returns -1 if the function isn't recognized. */ getFunctionType(name) { name = name.toLowerCase(); const functions = this.functions; for (let i = 0; i < 4; i++) { if (functions[i][name]) { return i; } } return -1; } /** * Gets a preset value. */ getPreset(name) { name = name.toLowerCase(); let preset = this.presets[name]; if (preset === undefined) { preset = this.externalPresets[name]; } return preset; } /** * Is the given preset a custom or standard one? */ isCustomPreset(name) { name = name.toLowerCase(); if (this.presets[name] !== undefined) { return false; } if (this.externalPresets[name] !== undefined) { return true; } throw new Error(`Failed to find a preset: ${name}`); } } exports.TriggerData = TriggerData; //# sourceMappingURL=triggerdata.js.map