@evitcastudio/kit
Version:
A single-player/multiplayer framework for the Vylocity Game Engine.
159 lines (158 loc) • 5.62 kB
JavaScript
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);
}
}
}