From c537b49a4bc469553a5e43f4ecf1bfe77597d0cb Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Fri, 24 Jan 2025 17:21:26 +0100 Subject: [PATCH] refactored bootmenu into extendable repls: ISOTerminal.prototype.boot.menu --- com/isoterminal.js | 4 +-- com/isoterminal/ISOTerminal.js | 14 +++----- com/isoterminal/feat/boot.js | 57 +++++++++++++++++++++++++++++++ com/isoterminal/feat/httpfs.js | 2 +- com/isoterminal/feat/term.js | 62 +++++++--------------------------- 5 files changed, 76 insertions(+), 63 deletions(-) diff --git a/com/isoterminal.js b/com/isoterminal.js index 0e32b44..c7783ab 100644 --- a/com/isoterminal.js +++ b/com/isoterminal.js @@ -19,7 +19,7 @@ * | `height` | `number` | 600 || * | `depth` | `number` | 0.03 || * | `lineHeight` | `number` | 18 || - * | `prompt` | `boolean` | true | boot straight into ISO or give user choice | + * | `bootmenu` | `boolean` | true | give user choice [or boot straight into ISO ] | * | `padding` | `number`` | 18 | | * | `maximized` | `boolean` | false | | * | `minimized` | `boolean` | false | | @@ -75,7 +75,7 @@ if( typeof AFRAME != 'undefined '){ height: { type: 'number',"default": 600 }, depth: { type: 'number',"default": 0.03 }, lineHeight: { type: 'number',"default": 18 }, - prompt: { type: 'boolean', "default": true }, // boot straight into ISO or give user choice + bootmenu: { type: 'string', "default": 'show' }, // show bootmenu or autosend key to bootmenu (key '1' e.g.) padding: { type: 'number',"default": 18 }, maximized: { type: 'boolean',"default":false}, minimized: { type: 'boolean',"default":false}, diff --git a/com/isoterminal/ISOTerminal.js b/com/isoterminal/ISOTerminal.js index 2a8d17c..c6d82db 100644 --- a/com/isoterminal/ISOTerminal.js +++ b/com/isoterminal/ISOTerminal.js @@ -11,6 +11,7 @@ function ISOTerminal(instance,opts){ // compose object with functions for( let i in ISOTerminal.prototype ) obj[i] = ISOTerminal.prototype[i] obj.emit('init') + instance.sceneEl.emit("isoterminal_init",{}) return obj } @@ -270,18 +271,11 @@ ISOTerminal.prototype.startVM = function(opts){ let msglib = this.getLoaderMsg() let msg = msglib.motd - if( this.opts.prompt ){ - msg += `\r -\r 1) boot ${String(this.opts.iso || "").replace(/.*\//,'')} Linux ❤️ -\r 2) just give me a javascript-console in WebXR [=instant] -\r -\renter number> ` - }else{ - bootISO() - } this.emit('status',msglib.loadmsg) this.emit('serial-output-string', msg) - + if( this.opts.bootmenu == 'show'){ + this.emit('bootmenu',{}) + } } ISOTerminal.prototype.bootISO = function(){ diff --git a/com/isoterminal/feat/boot.js b/com/isoterminal/feat/boot.js index b325f7c..53213e9 100644 --- a/com/isoterminal/feat/boot.js +++ b/com/isoterminal/feat/boot.js @@ -2,6 +2,15 @@ ISOTerminal.addEventListener('ready', function(e){ setTimeout( () => this.boot(), 50 ) // because of autorestore.js }) +ISOTerminal.addEventListener('bootmenu', function(e){ + let msg = '\n\r' + this.boot.menu.map( (m) => { + msg += `\r ${m.key}) ${m.title(this.opts)}\n` + }) + msg += `\n\r enter choice> ` + this.emit('serial-output-string', msg) +}) + ISOTerminal.prototype.boot = async function(e){ // set environment let env = [ @@ -23,4 +32,52 @@ ISOTerminal.prototype.boot = async function(e){ } } +ISOTerminal.prototype.boot.menu = [ + { + key: "1", + title: (opts) => `boot ${String(opts.iso || "").replace(/.*\//,'')} Linux ❤️ `, + init: function(){ this.bootISO() }, + keyHandler: (ch) => this.send(ch) // send to v86 webworker + }, + + { + key: "2", + title: (opts) => "just give me an javascript-console in WebXR instantly", + init: function(){ + this.prompt = "\r> " + this.emit('enable-console',{stdout:true}) + this.emit('status',"javascript console") + this.console = "" + setTimeout( () => this.emit('serial-output-string', this.prompt), 100 ) + }, + keyHandler: function(ch){ + let erase = false + if( ch == '\x7F' ){ + ch = "\b \b" // why does write() not just support \x7F ? + erase = true + } + this.emit('serial-output-string', ch) + const reset = () => { + this.console = "" + setTimeout( () => "\n\r"+this.emit('serial-output-string', this.prompt),100) + } + if( (ch == "\n" || ch == "\r") ){ + try{ + this.emit('serial-output-string', "\n\r") + if( this.console ) eval(this.console) + reset() + }catch(e){ + reset() + throw e // re throw + } + }else{ + if( erase ){ + this.console = this.console.split('').slice(0,-1).join('') + }else{ + this.console += ch + } + } + } + } +] diff --git a/com/isoterminal/feat/httpfs.js b/com/isoterminal/feat/httpfs.js index e40e58f..e0d410f 100644 --- a/com/isoterminal/feat/httpfs.js +++ b/com/isoterminal/feat/httpfs.js @@ -26,7 +26,7 @@ if( typeof emulator != 'undefined' ){ let mimetype = getMimeType(file) this.worker.read_file_world(file) .then( (data) => { - if( data == null ) throw `/mnt/${file} does not exist in ISO filesystem`" + if( data == null ) throw `/mnt/${file} does not exist in ISO filesystem` let blob = new Blob( [data], {type: getMimeType(file) }) // wrap Uint8Array into array response = { headers: new Headers({ 'Content-Type': getMimeType(file) }), diff --git a/com/isoterminal/feat/term.js b/com/isoterminal/feat/term.js index faa721d..c7ac40d 100644 --- a/com/isoterminal/feat/term.js +++ b/com/isoterminal/feat/term.js @@ -69,64 +69,26 @@ ISOTerminal.prototype.TermInit = function(){ ]; this.term.open(el) this.term.el = el - this.term.prompt = "\r> " - // you can override this REPL in index.html via : - // - // - // - // this might change in the future into something - // more convenient this.term.setKeyHandler( (ch) => { - if( this.ready ){ - this.send(ch) // send to v86 webworker - }else{ - if( (ch == "\n" || ch == "\r") && typeof this.console == 'undefined' ){ - switch( this.lastChar ){ - case '1': this.bootISO(); break; - case '2': { - this.emit('enable-console',{stdout:true}) - this.emit('status',"javascript console") - this.console = "" - setTimeout( () => this.term.write( this.term.prompt), 100 ) - break; - } - } - }else if( this.console != undefined ){ - this.term.write(ch) - const reset = () => { - this.console = "" - setTimeout( () => "\n\r"+this.term.write( this.term.prompt),100) - } - if( (ch == "\n" || ch == "\r") ){ - try{ - this.term.write("\n\r") - if( this.console ) eval(this.console) - reset() - }catch(e){ - reset() - throw e // re throw - } - }else{ - this.console += ch - } - }else{ - this.term.write(ch) + if( this.boot.menu.selected ){ + this.boot.menu.selected.keyHandler.call(this,ch) + }else if( (ch == "\n" || ch == "\r") ){ + let menuitem = this.boot.menu.find( (m) => m.key == this.lastChar ) + if( menuitem ){ + this.boot.menu.selected = menuitem + menuitem.init.call(this) } - this.lastChar = ch + }else{ + this.term.write(ch) } + this.lastChar = ch }) aEntity.el.addEventListener('focus', () => el.querySelector("textarea").focus() ) aEntity.el.addEventListener('serial-output-string', (e) => { - this.term.write(e.detail) + let msg = e.detail + this.term.write(msg) }) //aEntity.term.emit('initTerm',this) //aEntity.el.addEventListener('focus', () => this.vt100.focus() )