UNPKG

@adjust/core

Version:

A framework for creating highly customisable open source software

194 lines 9.08 kB
Object.defineProperty(exports, "__esModule", { value: true }); const electron_1 = require("electron"); const ipcMain_1 = require("../../communication/ipcMain"); const programState_1 = require("../programState"); const extendedObject_1 = require("../../utils/extendedObject"); const serialize_1 = require("../../utils/serialize"); const viewNotFound_type_1 = require("../../modules/viewNotFound.type"); const registry_1 = require("../../registry/registry"); /** * Keeps track of all windows and is able to create new ones * Also takes care of sending module updates to windows */ class WindowManagerSingleton { /** * Creates a window manager */ constructor() { // Stores all of the windows in the app this.windows = {}; // Stores the windows that are being opened this.openingWindows = {}; // Listen for updates of module counts ipcMain_1.IpcMain.on("WindowManager.updateCount", (windowID, moduleID, count) => { // Get the window data to update const windowData = this.windows[windowID]; if (windowData) { const currentCount = windowData.moduleCounts[moduleID] || 0; // Check if a listener should be registered if (currentCount == 0 && count != 0) this.listenToModule(moduleID, windowID); // Check if a listener should be removed if (currentCount != 0 && count == 0) this.stopListeningToModule(moduleID, windowID); // Update the count windowData.moduleCounts[moduleID] = count; } }); // Listen for windows requesting states ipcMain_1.IpcMain.on("WindowManager.getState", (moduleID) => { return this.getModuleData(moduleID); }); // Listen for module calls ipcMain_1.IpcMain.on("WindowManager.moduleCall", (moduleID, methodName, args) => { // Get the module by its request path const module = programState_1.ProgramState.getModule(moduleID); // Get the method to call on the module const method = module[methodName]; // Call the method method.apply(module, args); }); } /** * Create the view not found module if not created already */ async createViewNotFoundModule() { // Don't do anything of the module was already created if (this.viewNotFoundModule) return; // Create the module as a root otherwise // @ts-ignore this.viewNotFoundModule = await registry_1.Registry.createRoot({ type: viewNotFound_type_1.ViewNotFoundID }); } /** * Opens the window with the given ID * @param windowID The ID of the window to open * @param moduleID The ID of the root view of the window * @param options The extra options to pass to the window * @returns The browser window that was created */ async openWindow(windowID, moduleID, options = {}) { // Make sure the electron app is ready first await new Promise(res => (electron_1.app.isReady() ? res() : electron_1.app.once("ready", res))); // Make sure we have a view not found module await this.createViewNotFoundModule(); // Check if the window isn't open already const windowData = this.windows[windowID]; if (windowData) return windowData.window; // Check if the window isn't currently being opened const windowPromise = this.openingWindows[windowID]; if (windowPromise) return windowPromise; // Create a promise that resolves when the window is loaded return (this.openingWindows[windowID] = new Promise(async (resolve, reject) => { // Create the browser window const browserWindow = new electron_1.BrowserWindow(Object.assign({ width: 800, height: 600 }, options, { webPreferences: Object.assign({ nodeIntegration: true }, options.webPreferences) })); // Open the index page browserWindow.loadURL(`file://${__dirname}/window.html`); browserWindow.customID = windowID; // While debugging, TODO: add debug check browserWindow.webContents.openDevTools(); // Wait for the window to indicate it was loaded, and assign it its id await ipcMain_1.IpcMain.once(`WindowManager.loaded:${windowID}`); // Set the root view of the window and assign a viewNotFound view of the window const promises = [ ipcMain_1.IpcMain.send(browserWindow, "WindowIndex.setRoot", moduleID.toString()), ipcMain_1.IpcMain.send(browserWindow, "WindowIndex.setViewNotFound", this.viewNotFoundModule.toString()), ]; await Promise.all(promises); // Remove the promise delete this.openingWindows[windowID]; // Store the window this.windows[windowID] = { window: browserWindow, moduleCounts: {}, }; // Return the browserWindow resolve(browserWindow); })); } /** * Closes the window with the given ID * @param windowID The ID of the window to close */ async closeWindow(windowID) { // Wait for the window to fully open if it isn't yet const windowPromise = this.openingWindows[windowID]; if (windowPromise) await windowPromise; // Check if the window is open at all const windowData = this.windows[windowID]; if (!windowData) return; // Close the window windowData.window.close(); // Get rid of window data delete this.windows[windowID]; } /** * Adds listeners to the module to forward its data to a window's GuiManager * @param moduleID The moduleID of the module to forward to a window * @param windowID The id of the window to forward the data to */ listenToModule(moduleID, windowID) { // Get the window from the windows const windowData = this.windows[windowID]; if (!windowData) return; const window = windowData.window; // Get the module by its request path const module = programState_1.ProgramState.getModule(moduleID); // Add a listener to the state module.getStateObject().on("change", (changedProps) => { ipcMain_1.IpcMain.send(window, "ViewManager.sendUpdate", moduleID.toString(), serialize_1.Serialize.serialize(changedProps)); }, `windowManager.${windowID}`); // Add a listener to the settings module.getSettingsObject().on("change", (prop, value) => { ipcMain_1.IpcMain.send(window, "ViewManager.sendUpdate", moduleID.toString(), serialize_1.Serialize.serialize(extendedObject_1.ExtendedObject.translatePathToObject(`~settings.${prop}`, value))); }, `windowManager.${windowID}`); } /** * Removes the listeners from the module to stop forwarding its data to a window's GuiManager * @param moduleID The moduleID of the module that is forwarding to a window * @param windowID The id of the window the module is forwarding the data to */ stopListeningToModule(moduleID, windowID) { // Get the window from the windows const windowData = this.windows[windowID]; if (!windowData) return; // Get the module by its ID const module = programState_1.ProgramState.getModule(moduleID); // Check if the module exists, since the module might have already fully been destroyed by this point if (module) { // Remove the programState's listener of the state module.getStateObject().off("change", `windowManager.${windowID}`); // Remove the programState's listener of the settings module.getSettingsObject().off("change", `windowManager.${windowID}`); } } /** * Obtains the current data of the module * @param moduleID The moduleID of the module to get the data for * @returns The data of the module data */ getModuleData(moduleID) { // Get the module instance const module = programState_1.ProgramState.getModule(moduleID); if (!module) return; // Get the state of the module const state = module.getStateObject().serialize(); // Get the settings of the module const settings = module .getSettingsObject() .getSettings() .serialize(); // Add the settings to the state data state["_settings"] = settings; return state; } } exports.WindowManager = new WindowManagerSingleton(); //# sourceMappingURL=windowManager.js.map