refactored bootmenu into extendable repls: ISOTerminal.prototype.boot.menu
All checks were successful
/ mirror_to_github (push) Successful in 35s
/ test (push) Successful in 6s

This commit is contained in:
Leon van Kammen 2025-01-24 17:21:26 +01:00
parent 1b5cf3febb
commit c537b49a4b
5 changed files with 76 additions and 63 deletions

View file

@ -19,7 +19,7 @@
* | `height` | `number` | 600 || * | `height` | `number` | 600 ||
* | `depth` | `number` | 0.03 || * | `depth` | `number` | 0.03 ||
* | `lineHeight` | `number` | 18 || * | `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 | | * | `padding` | `number`` | 18 | |
* | `maximized` | `boolean` | false | | * | `maximized` | `boolean` | false | |
* | `minimized` | `boolean` | false | | * | `minimized` | `boolean` | false | |
@ -75,7 +75,7 @@ if( typeof AFRAME != 'undefined '){
height: { type: 'number',"default": 600 }, height: { type: 'number',"default": 600 },
depth: { type: 'number',"default": 0.03 }, depth: { type: 'number',"default": 0.03 },
lineHeight: { type: 'number',"default": 18 }, 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 }, padding: { type: 'number',"default": 18 },
maximized: { type: 'boolean',"default":false}, maximized: { type: 'boolean',"default":false},
minimized: { type: 'boolean',"default":false}, minimized: { type: 'boolean',"default":false},

View file

@ -11,6 +11,7 @@ function ISOTerminal(instance,opts){
// compose object with functions // compose object with functions
for( let i in ISOTerminal.prototype ) obj[i] = ISOTerminal.prototype[i] for( let i in ISOTerminal.prototype ) obj[i] = ISOTerminal.prototype[i]
obj.emit('init') obj.emit('init')
instance.sceneEl.emit("isoterminal_init",{})
return obj return obj
} }
@ -270,18 +271,11 @@ ISOTerminal.prototype.startVM = function(opts){
let msglib = this.getLoaderMsg() let msglib = this.getLoaderMsg()
let msg = msglib.motd 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('status',msglib.loadmsg)
this.emit('serial-output-string', msg) this.emit('serial-output-string', msg)
if( this.opts.bootmenu == 'show'){
this.emit('bootmenu',{})
}
} }
ISOTerminal.prototype.bootISO = function(){ ISOTerminal.prototype.bootISO = function(){

View file

@ -2,6 +2,15 @@ ISOTerminal.addEventListener('ready', function(e){
setTimeout( () => this.boot(), 50 ) // because of autorestore.js 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){ ISOTerminal.prototype.boot = async function(e){
// set environment // set environment
let env = [ 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
}
}
}
}
]

View file

@ -26,7 +26,7 @@ if( typeof emulator != 'undefined' ){
let mimetype = getMimeType(file) let mimetype = getMimeType(file)
this.worker.read_file_world(file) this.worker.read_file_world(file)
.then( (data) => { .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 let blob = new Blob( [data], {type: getMimeType(file) }) // wrap Uint8Array into array
response = { response = {
headers: new Headers({ 'Content-Type': getMimeType(file) }), headers: new Headers({ 'Content-Type': getMimeType(file) }),

View file

@ -69,64 +69,26 @@ ISOTerminal.prototype.TermInit = function(){
]; ];
this.term.open(el) this.term.open(el)
this.term.el = el this.term.el = el
this.term.prompt = "\r> "
// you can override this REPL in index.html via :
//
// <script>
// document.querySelector('[isoterminal]')
// .components
// .isoterminal
// .term
// .term
// .setKeyHandler( (ch) => { ....} )
// </script>
//
// this might change in the future into something
// more convenient
this.term.setKeyHandler( (ch) => { this.term.setKeyHandler( (ch) => {
if( this.ready ){ if( this.boot.menu.selected ){
this.send(ch) // send to v86 webworker this.boot.menu.selected.keyHandler.call(this,ch)
}else{ }else if( (ch == "\n" || ch == "\r") ){
if( (ch == "\n" || ch == "\r") && typeof this.console == 'undefined' ){ let menuitem = this.boot.menu.find( (m) => m.key == this.lastChar )
switch( this.lastChar ){ if( menuitem ){
case '1': this.bootISO(); break; this.boot.menu.selected = menuitem
case '2': { menuitem.init.call(this)
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)
} }
this.lastChar = ch }else{
this.term.write(ch)
} }
this.lastChar = ch
}) })
aEntity.el.addEventListener('focus', () => el.querySelector("textarea").focus() ) aEntity.el.addEventListener('focus', () => el.querySelector("textarea").focus() )
aEntity.el.addEventListener('serial-output-string', (e) => { 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.term.emit('initTerm',this)
//aEntity.el.addEventListener('focus', () => this.vt100.focus() ) //aEntity.el.addEventListener('focus', () => this.vt100.focus() )