From 9d9e091a7a4eb76775d3c17bc066bcb3af2877e2 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sun, 14 Apr 2024 20:39:26 -0400 Subject: [PATCH] Add process management --- src/UI/UIWindowTaskManager.js | 1 + src/definitions.js | 35 ++++++++++++++++++++ src/helpers.js | 27 +++++++++++++-- src/initgui.js | 2 ++ src/services/InstanceService.js | 5 --- src/services/ProcessService.js | 58 +++++++++++++++++++++++++++++++++ 6 files changed, 121 insertions(+), 7 deletions(-) delete mode 100644 src/services/InstanceService.js create mode 100644 src/services/ProcessService.js diff --git a/src/UI/UIWindowTaskManager.js b/src/UI/UIWindowTaskManager.js index 21f65bb9..4d2dd815 100644 --- a/src/UI/UIWindowTaskManager.js +++ b/src/UI/UIWindowTaskManager.js @@ -1,6 +1,7 @@ import UIWindow from "./UIWindow.js"; const UIWindowTaskManager = async function UIWindowTaskManager () { + const svc_process = globalThis.services.get('process'); const sample_data = [ { name: 'root', diff --git a/src/definitions.js b/src/definitions.js index 872e6315..130d14cd 100644 --- a/src/definitions.js +++ b/src/definitions.js @@ -19,3 +19,38 @@ export class Service { // }; + +export class Process { + constructor ({ uuid, parent, meta }) { + this.uuid = uuid; + this.parent = parent; + this.meta = meta; + + this._construct(); + } + + _construct () {} + + get type () { + const _to_type_name = (name) => { + return name.replace(/Process$/, '').toLowerCase(); + }; + return this.type || _to_type_name(this.constructor.name) || + 'invalid' + } +}; + +export class InitProccess extends Process { + static created_ = false; + + _construct () { + if (InitProccess.created_) { + throw new Error('InitProccess already created'); + } + + InitProccess.created_ = true; + } +} + +export class PortalProcess extends Process {}; +export class PseudoProcess extends Process {}; diff --git a/src/helpers.js b/src/helpers.js index ebbe9f1c..5fdfdfd4 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -36,6 +36,7 @@ import update_username_in_gui from './helpers/update_username_in_gui.js'; import update_title_based_on_uploads from './helpers/update_title_based_on_uploads.js'; import content_type_to_icon from './helpers/content_type_to_icon.js'; import UIWindowDownloadDirProg from './UI/UIWindowDownloadDirProg.js'; +import { PortalProcess } from "./definitions.js"; window.is_auth = ()=>{ if(localStorage.getItem("auth_token") === null || auth_token === null) @@ -1675,6 +1676,24 @@ window.launch_app = async (options)=>{ // add file_signature to options file_signature = file_signature.items; } + + // ----------------------------------- + // Create entry to track the "portal" + // (portals are processese in Puter's GUI) + // ----------------------------------- + const portal = new PortalProcess({ + uuid, + parent: options.parent_instance_id, + meta: { + launch_options: options, + app_info: app_info, + } + }); + const svc_process = globalThis.services.get('process'); + svc_process.register(portal); + + let el_win; + //------------------------------------ // Explorer //------------------------------------ @@ -1692,7 +1711,7 @@ window.launch_app = async (options)=>{ title = path.dirname(options.path); // open window - UIWindow({ + el_win = UIWindow({ element_uuid: uuid, icon: icon, path: options.path ?? window.home_path, @@ -1803,7 +1822,7 @@ window.launch_app = async (options)=>{ console.log('backgrounded??', app_info.background); - const el_win = UIWindow({ + el_win = UIWindow({ element_uuid: uuid, title: title, iframe_url: iframe_url.href, @@ -1854,6 +1873,10 @@ window.launch_app = async (options)=>{ }) } } + + $(el_win).on('remove', () => { + svc_process.unregister(portal.uuid); + }); } window.open_item = async function(options){ diff --git a/src/initgui.js b/src/initgui.js index 83cf4ccb..4d0d19cd 100644 --- a/src/initgui.js +++ b/src/initgui.js @@ -38,6 +38,7 @@ import { ThemeService } from './services/ThemeService.js'; import UIWindowThemeDialog from './UI/UIWindowThemeDialog.js'; import { BroadcastService } from './services/BroadcastService.js'; import UIWindowTaskManager from './UI/UIWindowTaskManager.js'; +import { ProcessService } from './services/ProcessService.js'; const launch_services = async function () { const services_l_ = []; @@ -53,6 +54,7 @@ const launch_services = async function () { register('broadcast', new BroadcastService()); register('theme', new ThemeService()); + register('process', new ProcessService()) for (const [_, instance] of services_l_) { await instance._init(); diff --git a/src/services/InstanceService.js b/src/services/InstanceService.js deleted file mode 100644 index 25498270..00000000 --- a/src/services/InstanceService.js +++ /dev/null @@ -1,5 +0,0 @@ -import { Service } from "../definitions"; - -export class InstanceService extends Service { - // -} \ No newline at end of file diff --git a/src/services/ProcessService.js b/src/services/ProcessService.js new file mode 100644 index 00000000..d31832e9 --- /dev/null +++ b/src/services/ProcessService.js @@ -0,0 +1,58 @@ +import { InitProccess, Service } from "../definitions.js"; + +// The NULL UUID is also the UUID for the init process. +const NULL_UUID = '00000000-0000-0000-0000-000000000000'; + +export class ProcessService extends Service { + async _init () { + this.processes = []; + this.processes_map = new Map(); + this.uuid_to_treelist = new Map(); + + const root = new InitProccess({ + uuid: NULL_UUID, + }); + this.register_(root); + } + + register (process) { + this.register_(process); + this.attach_to_parent_(process); + } + + register_ (process) { + this.processes.push(process); + this.processes_map.set(process.uuid, process); + this.uuid_to_treelist.set(process.uuid, []); + } + + attach_to_parent_ (process) { + process.parent = process.parent ?? NULL_UUID; + const parent_list = this.uuid_to_treelist.get(process.parent); + parent_list.push(process); + } + + unregister (uuid) { + const process = this.processes_map.get(uuid); + if ( ! process ) { + throw new Error(`Process with uuid ${uuid} not found`); + } + + this.processes_map.delete(uuid); + this.processes.splice(this.processes.indexOf(process), 1); + + const parent_list = this.uuid_to_treelist.get(process.parent.uuid); + parent_list.splice(parent_list.indexOf(process), 1); + + const children = this.uuid_to_treelist.get(process.uuid); + + delete this.uuid_to_treelist[process.uuid]; + this.processes.splice(this.processes.indexOf(process), 1); + + // Transfer children to init process + for ( const child of children ) { + child.parent = NULL_UUID; + this.attach_to_parent_(child); + } + } +}