feat/webworker: work in progress [might break]
/ test (push) Successful in 6s Details

This commit is contained in:
Leon van Kammen 2024-10-03 10:41:53 +00:00
parent 0f3c7a0184
commit 0e8d173289
5 changed files with 51 additions and 30 deletions

View File

@ -42,7 +42,9 @@ if( typeof AFRAME != 'undefined '){
maximized: { type: 'boolean',"default":false}, maximized: { type: 'boolean',"default":false},
transparent: { type:'boolean', "default":false }, // need good gpu transparent: { type:'boolean', "default":false }, // need good gpu
xterm: { type: 'boolean', "default":true }, // use xterm.js? (=slower) xterm: { type: 'boolean', "default":true }, // use xterm.js? (=slower)
memory: { type: 'number', "default":48 } // VM memory (in MB) memory: { type: 'number', "default":48 }, // VM memory (in MB)
bufferLatency:{ type: 'number', "default":200 } // bufferlatency from worker to xterm
// (re-uploading the canvas per character is slooow)
}, },
init: function(){ init: function(){
@ -210,8 +212,7 @@ if( typeof AFRAME != 'undefined '){
instance.addEventListener('DOMready', () => { instance.addEventListener('DOMready', () => {
//instance.setAttribute("html-as-texture-in-xr", `domid: #${this.el.dom.id}`) //instance.setAttribute("html-as-texture-in-xr", `domid: #${this.el.dom.id}`)
//instance.winbox.resize(720,380) //instance.winbox.resize(720,380)
let size = this.data.xterm ? 'width: 1024px; height:600px' let size = `width: ${Math.floor(this.data.cols*8.65)}; height: ${Math.floor(this.data.rows*21.1)}`
: 'width: 720px; height:455px'
instance.setAttribute("window", `title: xrsh.iso; uid: ${instance.uid}; attach: #overlay; dom: #${instance.dom.id}; ${size}; min: ${this.data.minimized}; max: ${this.data.maximized}`) instance.setAttribute("window", `title: xrsh.iso; uid: ${instance.uid}; attach: #overlay; dom: #${instance.dom.id}; ${size}; min: ${this.data.minimized}; max: ${this.data.maximized}`)
}) })
@ -257,15 +258,19 @@ if( typeof AFRAME != 'undefined '){
instance.addEventListener('window.onresize', resize ) instance.addEventListener('window.onresize', resize )
instance.addEventListener('window.onmaximize', resize ) instance.addEventListener('window.onmaximize', resize )
const focus = (e) => { const focus = (showdom) => (e) => {
if( this.el.components.xterm ){ if( this.el.components.xterm ){
this.el.components.xterm.term.focus() this.el.components.xterm.term.focus()
} }
if( this.el.components.window ){
this.el.components.window.show( showdom )
}
} }
//instance.addEventListener('obbcollisionstarted', focus )
this.el.sceneEl.addEventListener('enter-vr', focus ) this.el.sceneEl.addEventListener('enter-vr', focus(false) )
this.el.sceneEl.addEventListener('enter-ar', focus ) this.el.sceneEl.addEventListener('enter-ar', focus(false) )
this.el.sceneEl.addEventListener('exit-vr', focus(true) )
this.el.sceneEl.addEventListener('exit-ar', focus(true) )
instance.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera instance.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
}, },

View File

@ -32,7 +32,6 @@ ISOTerminal.addEventListener = (event,cb) => {
} }
ISOTerminal.prototype.exec = function(shellscript){ ISOTerminal.prototype.exec = function(shellscript){
console.log("exec:"+shellscript)
this.send(shellscript+"\n",1) this.send(shellscript+"\n",1)
} }
@ -197,8 +196,9 @@ ISOTerminal.prototype.start = function(opts){
let line = '' let line = ''
let ready = false let ready = false
this.addEventListener(`serial0-output-byte`, async (e) => { this.addEventListener(`serial0-output-byte`, async (e) => {
this.emit("serial-output-byte",e.detail) // send to xterm
const byte = e.detail const byte = e.detail
//this.emit("serial-output-byte",byte) // send to xterm
this.bufferOutput(`serial-output-byte`, byte)
var chr = String.fromCharCode(byte); var chr = String.fromCharCode(byte);
if(chr < " " && chr !== "\n" && chr !== "\t" || chr > "~") return if(chr < " " && chr !== "\n" && chr !== "\t" || chr > "~") return
@ -206,8 +206,8 @@ ISOTerminal.prototype.start = function(opts){
{ {
var new_line = line; var new_line = line;
line = ""; line = "";
} } else if(chr >= " " && chr <= "~"){ line += chr }
else if(chr >= " " && chr <= "~"){ line += chr }
if( !ready && line.match(/^(\/ #|~%|\[.*\]>)/) ){ if( !ready && line.match(/^(\/ #|~%|\[.*\]>)/) ){
this.emit('postReady',{}) this.emit('postReady',{})
setTimeout( () => this.emit('ready',{}), 500 ) setTimeout( () => this.emit('ready',{}), 500 )
@ -217,3 +217,17 @@ ISOTerminal.prototype.start = function(opts){
}); });
} }
ISOTerminal.prototype.bufferOutput = function(type,byte){
this.buffer = this.buffer || {str:""}
if( this.buffer.id ) this.buffer.str += String.fromCharCode(byte)
else{
this.emit(type, byte ) // leading call
this.buffer.id = setTimeout( () => { // trailing calls
if( this.buffer.str ){
this.emit('serial-output-string', this.buffer.str )
}
this.buffer = {str:""}
}, this.opts.bufferLatency || 250)
}
}

View File

@ -71,8 +71,8 @@ this.runISO = function(opts){
}) })
} }
//importScripts("feat/javascript.js") importScripts("feat/javascript.js")
//importScripts("feat/index.html.js") importScripts("feat/index.html.js")
} }
/* /*
* forward events/functions so non-worker world can reach them * forward events/functions so non-worker world can reach them

View File

@ -63,5 +63,9 @@ AFRAME.registerComponent('window', {
this.el.setAttribute("grabbable","") this.el.setAttribute("grabbable","")
},
show: function(state){
this.el.dom.closest('.winbox').style.display = state ? '' : 'none'
} }
}) })

View File

@ -113,7 +113,13 @@ AFRAME.registerComponent('xterm', {
overflow: hidden; overflow: hidden;
`) `)
this.el.setAttribute("geometry",`primitive: plane; width:2; height:${this.data.rows*5/this.data.cols}*2`) // setup slightly bigger black backdrop (this.el.getObject3D("mesh"))
// and terminal text (this.el.planeText.getObject("mesh"))
this.el.setAttribute("geometry",`primitive: box; width:2.07; height:${this.data.rows*5.3/this.data.cols}*2; depth: -0.12`)
this.el.setAttribute("material","shader:flat; color:black; opacity:0.5; transparent:true; ")
this.el.planeText = document.createElement('a-entity')
this.el.planeText.setAttribute("geometry",`primitive: plane; width:2; height:${this.data.rows*5/this.data.cols}*2`)
this.el.appendChild(this.el.planeText)
this.el.terminalElement = terminalElement this.el.terminalElement = terminalElement
@ -148,7 +154,7 @@ AFRAME.registerComponent('xterm', {
if( this.el.sceneEl.renderer.xr.isPresenting ){ if( this.el.sceneEl.renderer.xr.isPresenting ){
// workaround // workaround
// xterm relies on window.requestAnimationFrame (which is not called WebXR immersive mode) // xterm relies on window.requestAnimationFrame (which is not called WebXR immersive mode)
this.term._core.viewport._innerRefresh() //this.term._core.viewport._innerRefresh()
this.term._core.renderer._renderDebouncer._innerRefresh() this.term._core.renderer._renderDebouncer._innerRefresh()
} }
},150) },150)
@ -156,15 +162,6 @@ AFRAME.registerComponent('xterm', {
this.term.open(terminalElement) this.term.open(terminalElement)
this.term.focus() this.term.focus()
this.setRenderType('dom') this.setRenderType('dom')
const refresh = term._core.renderer._renderDebouncer.refresh
let scene = this.el.sceneEl
term._core.renderer._renderDebouncer.refresh = function(){
refresh.apply(this,arguments)
if( scene.renderer.xr.isPresenting ){
this._innerRefresh()
}
}.bind(term._core.renderer._renderDebouncer)
terminalElement.querySelector('.xterm-viewport').style.background = 'transparent' terminalElement.querySelector('.xterm-viewport').style.background = 'transparent'
@ -191,7 +188,7 @@ AFRAME.registerComponent('xterm', {
update: function(){ update: function(){
if( this.renderType == 'canvas' ){ if( this.renderType == 'canvas' ){
const material = this.el.getObject3D('mesh').material const material = this.el.planeText.getObject3D('mesh').material
if (!material.map ) return if (!material.map ) return
if( this.cursorCanvas ) this.canvasContext.drawImage(this.cursorCanvas, 0,0) if( this.cursorCanvas ) this.canvasContext.drawImage(this.cursorCanvas, 0,0)
material.map.needsUpdate = true material.map.needsUpdate = true
@ -227,16 +224,17 @@ AFRAME.registerComponent('xterm', {
//canvasTexture.minFilter = THREE.LinearFilter //canvasTexture.minFilter = THREE.LinearFilter
//canvasTexture.magFilter = THREE.LinearFilter //canvasTexture.magFilter = THREE.LinearFilter
canvasTexture.needsUpdate = true; // Ensure the texture updates canvasTexture.needsUpdate = true; // Ensure the texture updates
let plane = this.el.getObject3D('mesh') let plane = this.el.planeText.getObject3D("mesh") //this.el.getObject3D('mesh')
if( plane.material ) plane.material.dispose() if( plane.material ) plane.material.dispose()
plane.material = new THREE.MeshBasicMaterial({ plane.material = new THREE.MeshBasicMaterial({
map: canvasTexture, // Set the texture from the canvas map: canvasTexture, // Set the texture from the canvas
transparent: false, // Set transparency transparent: false, // Set transparency
side: THREE.DoubleSide // Set to double-sided rendering //side: THREE.DoubleSide // Set to double-sided rendering
//blending: THREE.AdditiveBlending
}); });
this.el.getObject3D('mesh').scale.x = 0.3 this.el.object3D.scale.x = 0.2
this.el.getObject3D('mesh').scale.y = 0.3 this.el.object3D.scale.y = 0.2
this.el.getObject3D('mesh').scale.z = 0.3 this.el.object3D.scale.z = 0.2
},100) },100)
} }