UNPKG

@evitcastudio/kit

Version:

A single-player/multiplayer framework for the Vylocity Game Engine.

159 lines (158 loc) 5.62 kB
import { EventEmitter } from './events/event-system'; const extensionToPath = { '.vyint': 'interface', '.vym': 'map', '.vyi': 'icon', '.vymac': 'macros', '.aac': 'sound', '.mp3': 'sound', '.wav': 'sound', '.m4a': 'sound', '.ogg': 'sound', '.flac': 'sound' }; export class Kit { /** * A record of all plugins registered with the Kit class. */ static plugins = {}; /** * A set of all plugin emitters. */ static emitters = new Map(); /** * A record of all event listeners. */ static events = {}; constructor() { throw new Error('[Kit] is not to be instantiated.'); } /** * Initialize the Kit class with plugins. * @deprecated Use `registerPlugin` instead. * @param pPlugins - An array of plugins to initialize. */ static init(pPlugins) { pPlugins.forEach(pPlugin => { this.registerPlugin(pPlugin); }); } static registerPlugin(pPlugin) { if (Array.isArray(pPlugin)) { const plugins = []; pPlugin.forEach(pPlugin => { const plugin = this.registerPlugin(pPlugin); if (plugin && !Array.isArray(plugin)) { plugins.push(plugin); } }); return plugins; } else { const plugin = new pPlugin(); const pluginName = plugin.name; if (!pluginName || typeof pluginName !== 'string' || !/^[a-zA-Z0-9-_]+$/.test(pluginName)) { throw new Error(`[Kit] Invalid plugin name: '${pluginName}'. The name must be a non-empty string containing only alphanumeric characters, dashes, or underscores.`); } if (Kit.plugins[pluginName]) { throw new Error(`[Kit] plugin with name '${pluginName}' is already registered.`); } const listener = function (pEvent) { Kit.emit(pEvent); }; const emitter = new EventEmitter(listener, plugin); Kit.emitters.set(pluginName, emitter); Kit.plugins[pluginName] = plugin; plugin._register(emitter); plugin.onRegistered(); return plugin; } } /** * Gets a plugin by name. * @param pName - String name of the plugin to retrieve. */ static getPlugin(pName) { const plugin = Kit.plugins[pName]; if (!plugin) { return undefined; } return plugin; } /** * Lists all registered plugins. */ static getPlugins() { return Object.keys(Kit.plugins); } /** * Emit an event to all listeners. * @param pEvent - The event to emit. */ static emit(pEvent) { const { plugin, event } = pEvent; const eventScope = `${plugin}-${event}`; if (!Kit.events[eventScope]) { return; } Kit.events[eventScope].forEach(pListener => pListener(pEvent)); } /** * Listen for an event. * @param pPluginName - The plugin namespace. * @param pEventName - The event name. * @param pListener - The listener to call when the event is emitted. */ static on(pPluginName, pEventName, pListener) { const eventScope = `${pPluginName}-${pEventName}`; if (!Kit.events[eventScope]) { Kit.events[eventScope] = []; } Kit.events[eventScope].push(pListener); } /** * Removes an event listener. * @param pPluginName - The plugin namespace. * @param pEventName - The event name. * @param pListener - The listener to remove. */ static off(pPluginName, pEventName, pListener) { const eventScope = `${pPluginName}-${pEventName}`; if (Kit.events[eventScope].includes(pListener)) { Kit.events[eventScope].splice(Kit.events[eventScope].indexOf(pListener), 1); } } /** * Sets the resource locator for the engine to reference the files we have in the resources folder. interface | map | icon | macro | sound are checked for. * @param pData - An array of each file that was found in the resources folder. */ static setResource(pData) { pData.forEach((pResource) => { const extensionMatch = pResource.fileName.match(/\.[^.]+$/); const fileNameWithoutExtensionMatch = pResource.fileName.match(/(.+?)(?=\.[^.]+$|$)/); if (extensionMatch && fileNameWithoutExtensionMatch) { const extension = extensionMatch[0]; const fileNameWithoutExtension = fileNameWithoutExtensionMatch[0]; const resourceType = extensionToPath[extension]; if (resourceType) { globalThis.VYLO.Resource.setResource(resourceType, fileNameWithoutExtension, `${pResource.resourceIdentifier}`); } } }); } /** * Sets the resources found in resources and preloads all interfaces found. */ static async setResources(pResourceJson) { if (!globalThis.VYLO) { throw new Error('[Kit] VYLO is not defined. Please ensure the VYLO variable is available in the global namespace.'); } if (pResourceJson) { const resources = Object.values(pResourceJson); // Group all data from separate arrays in object to one unified array of all resource data const consolidatedData = resources.flat(); // Set all the resources this.setResource(consolidatedData); } } }