const path = require('path'); const { Collection, Util } = require('../../util/'); const { Component, Module } = require('../../structure/interfaces'); class Registry { constructor(client) { this.client = client; this.components = new Collection(); } async loadComponents(dir, classToHandle) { const directory = path.join(process.cwd(), 'structure/client/', dir); //Finds directory of component folder relative to current working directory. const files = Util.readdirRecursive(directory); //Loops through all folders in the directory and returns the files. const loaded = []; for(const path of files) { const func = require(path); if(typeof func !== 'function') { this.client.logger.warn("Attempted to index an invalid function as a component."); delete require.cache[path]; continue; } const component = new func(this.client); //Instantiates the component class. if(classToHandle && !(component instanceof classToHandle)) { this.client.logger.warn("Attempted to load an invalid class."); delete require.cache[path]; continue; } loaded.push(await this.loadComponent(component, path)); } return loaded; } async loadComponent(component, directory) { if(!(component instanceof Component)) { delete require.cache[directory]; this.client.logger.warn("Attempted to load an invalid component."); return null; } if(this.components.has(component.resolveable)) { this.client.logger.warn("Attempted to reload an existing component."); return null; } if(directory) component.directory = directory; if(component.module && typeof component.module === 'string') { //Sets modules or "groups" for each component, specified by their properties. let module = this.components.get(`module:${component.module}`); if(!module) module = await this.loadComponent(new Module(this.client, { name: component.module })); this.components.set(module.resolveable, module); component.module = module; module.components.set(component.resolveable, component); } this.components.set(component.resolveable, component); this.client.emit('componentUpdate', { component, type: 'LOAD' }); return component; } async unloadComponent(component) { if(component.module) { component.module.components.delete(component.resolveable); } this.components.delete(component.resolveable); } } module.exports = Registry;