improved performance on low-end smartphone
This commit is contained in:
parent
2e56d235ed
commit
9aff2133a0
|
@ -33,22 +33,25 @@ if( typeof AFRAME != 'undefined '){
|
||||||
|
|
||||||
AFRAME.registerComponent('isoterminal', {
|
AFRAME.registerComponent('isoterminal', {
|
||||||
schema: {
|
schema: {
|
||||||
iso: { type:"string", "default":"https://forgejo.isvery.ninja/assets/xrsh-buildroot/main/xrsh.iso" },
|
iso: { type:"string", "default":"https://forgejo.isvery.ninja/assets/xrsh-buildroot/main/xrsh.iso" },
|
||||||
overlayfs: { type:"string"},
|
overlayfs: { type:"string"},
|
||||||
cols: { type: 'number',"default": 80 },
|
cols: { type: 'number',"default": 80 },
|
||||||
rows: { type: 'number',"default": 20 },
|
rows: { type: 'number',"default": 20 },
|
||||||
padding: { type: 'number',"default": 18 },
|
padding: { type: 'number',"default": 18 },
|
||||||
minimized: { type: 'boolean',"default":false},
|
minimized: { type: 'boolean',"default":false},
|
||||||
maximized: { type: 'boolean',"default":false},
|
maximized: { type: 'boolean',"default":false},
|
||||||
transparent: { type:'boolean', "default":false }, // need good gpu
|
muteUntilPrompt:{ type: 'boolean',"default":true}, // mute stdout until a prompt is detected in ISO
|
||||||
xterm: { type: 'boolean', "default":true }, // use xterm.js? (=slower)
|
HUD: { type: 'boolean',"default":false}, // link to camera movement
|
||||||
memory: { type: 'number', "default":48 }, // VM memory (in MB)
|
transparent: { type:'boolean', "default":false }, // need good gpu
|
||||||
bufferLatency:{ type: 'number', "default":300 }, // in ms: bufferlatency from webworker to xterm (batch-update every char to texture)
|
xterm: { type: 'boolean', "default":true }, // use xterm.js? (=slower)
|
||||||
canvasLatency:{ type: 'number', "default":300 } // in ms: time between canvas re-draws
|
memory: { type: 'number', "default":64 }, // VM memory (in MB)
|
||||||
|
bufferLatency: { type: 'number', "default":300 }, // in ms: bufferlatency from webworker to xterm (batch-update every char to texture)
|
||||||
|
canvasLatency: { type: 'number', "default":300 } // in ms: time between canvas re-draws
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function(){
|
init: function(){
|
||||||
this.el.object3D.visible = false
|
this.el.object3D.visible = false
|
||||||
|
this.initHud()
|
||||||
fetch(this.data.iso,{method: 'HEAD'})
|
fetch(this.data.iso,{method: 'HEAD'})
|
||||||
.then( (res) => {
|
.then( (res) => {
|
||||||
if( res.status != 200 ) throw 'not found'
|
if( res.status != 200 ) throw 'not found'
|
||||||
|
@ -267,6 +270,7 @@ if( typeof AFRAME != 'undefined '){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.el.addEventListener('obbcollisionstarted', focus(false) )
|
||||||
this.el.sceneEl.addEventListener('enter-vr', focus(false) )
|
this.el.sceneEl.addEventListener('enter-vr', focus(false) )
|
||||||
this.el.sceneEl.addEventListener('enter-ar', focus(false) )
|
this.el.sceneEl.addEventListener('enter-ar', focus(false) )
|
||||||
this.el.sceneEl.addEventListener('exit-vr', focus(true) )
|
this.el.sceneEl.addEventListener('exit-vr', focus(true) )
|
||||||
|
@ -275,6 +279,14 @@ if( typeof AFRAME != 'undefined '){
|
||||||
instance.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
|
instance.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
|
||||||
},
|
},
|
||||||
|
|
||||||
|
initHud: function(){
|
||||||
|
if( AFRAME.utils.device.isMobile() ) this.data.HUD = true
|
||||||
|
if( this.data.HUD ){
|
||||||
|
document.querySelector('[camera]').appendChild( this.el )
|
||||||
|
this.el.setAttribute("position","0 -0.03 -0.4")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
events:{
|
events:{
|
||||||
|
|
||||||
// combined AFRAME+DOM reactive events
|
// combined AFRAME+DOM reactive events
|
||||||
|
|
|
@ -17,12 +17,14 @@ function ISOTerminal(instance,opts){
|
||||||
ISOTerminal.prototype.emit = function(event,data,sender){
|
ISOTerminal.prototype.emit = function(event,data,sender){
|
||||||
data = data || false
|
data = data || false
|
||||||
const evObj = new CustomEvent(event, {detail: data} )
|
const evObj = new CustomEvent(event, {detail: data} )
|
||||||
// forward event to worker/instance/AFRAME element or component-function
|
//this.preventFrameDrop( () => {
|
||||||
// this feels complex, but actually keeps event- and function-names more concise in codebase
|
// forward event to worker/instance/AFRAME element or component-function
|
||||||
this.dispatchEvent( evObj )
|
// this feels complex, but actually keeps event- and function-names more concise in codebase
|
||||||
if( sender != "instance" && this.instance ) this.instance.dispatchEvent(evObj)
|
this.dispatchEvent( evObj )
|
||||||
if( sender != "worker" && this.worker ) this.worker.postMessage({event,data})
|
if( sender != "instance" && this.instance ) this.instance.dispatchEvent(evObj)
|
||||||
if( sender !== undefined && typeof this[event] == 'function' ) this[event].apply(this, data && data.push ? data : [data] )
|
if( sender != "worker" && this.worker ) this.worker.postMessage({event,data}, this.getTransferable(data) )
|
||||||
|
if( sender !== undefined && typeof this[event] == 'function' ) this[event].apply(this, data && data.push ? data : [data] )
|
||||||
|
//})
|
||||||
}
|
}
|
||||||
|
|
||||||
ISOTerminal.addEventListener = (event,cb) => {
|
ISOTerminal.addEventListener = (event,cb) => {
|
||||||
|
@ -45,7 +47,9 @@ ISOTerminal.prototype.send = function(str, ttyNr){
|
||||||
}else this.emulator.keyboard_send_text(str) // vga screen
|
}else this.emulator.keyboard_send_text(str) // vga screen
|
||||||
}else{
|
}else{
|
||||||
this.convert.toUint8Array( str ).map( (c) => {
|
this.convert.toUint8Array( str ).map( (c) => {
|
||||||
this.worker.postMessage({event:`serial${ttyNr}-input`,data:c})
|
this.preventFrameDrop(
|
||||||
|
() => this.worker.postMessage({event:`serial${ttyNr}-input`,data:c})
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +137,6 @@ ISOTerminal.prototype.start = function(opts){
|
||||||
|
|
||||||
this.worker = new Worker("com/isoterminal/worker.js");
|
this.worker = new Worker("com/isoterminal/worker.js");
|
||||||
this.worker.onmessage = (e) => {
|
this.worker.onmessage = (e) => {
|
||||||
const xr = this.instance.sceneEl.renderer.xr
|
|
||||||
const {event,data} = e.data
|
const {event,data} = e.data
|
||||||
const cb = (event,data) => () => {
|
const cb = (event,data) => () => {
|
||||||
if( data.promiseId ){
|
if( data.promiseId ){
|
||||||
|
@ -141,12 +144,7 @@ ISOTerminal.prototype.start = function(opts){
|
||||||
}else this.emit(event,data,"worker") // forward event to world
|
}else this.emit(event,data,"worker") // forward event to world
|
||||||
|
|
||||||
}
|
}
|
||||||
// don't let workers cause framerate dropping
|
this.preventFrameDrop( cb(event,data) )
|
||||||
if( xr.isPresenting ){
|
|
||||||
xr.getSession().requestAnimationFrame(cb(event,data))
|
|
||||||
}else{
|
|
||||||
window.requestAnimationFrame(cb(event,data))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -160,7 +158,7 @@ ISOTerminal.prototype.start = function(opts){
|
||||||
this.id = this.id == undefined ? 0 : this.id
|
this.id = this.id == undefined ? 0 : this.id
|
||||||
data.id = this.id++
|
data.id = this.id++
|
||||||
// Send id and task to WebWorker
|
// Send id and task to WebWorker
|
||||||
this.worker.postMessage(data)
|
this.preventFrameDrop( () => this.worker.postMessage(data,getTransferable(data) ) )
|
||||||
return new Promise(resolve => this.resolvers[data.id] = resolve);
|
return new Promise(resolve => this.resolvers[data.id] = resolve);
|
||||||
}.bind(this.worker.postMessage)
|
}.bind(this.worker.postMessage)
|
||||||
|
|
||||||
|
@ -196,12 +194,52 @@ ISOTerminal.prototype.start = function(opts){
|
||||||
'Transcending earthly limits'
|
'Transcending earthly limits'
|
||||||
]
|
]
|
||||||
|
|
||||||
const loadmsg = loading[ Math.floor(Math.random()*1000) % loading.length ] + "..(please wait..)"
|
const empower = [
|
||||||
|
"FOSS gives users control over their software, offering freedom to modify and share",
|
||||||
|
"Feeling powerless with tech? FOSS escapes a mindset known as learned helplessness",
|
||||||
|
"FOSS breaks this cycle by showing that anyone can learn and contribute",
|
||||||
|
"Proprietary software can make users dependent, but FOSS offers real choices",
|
||||||
|
"FOSS communities provide support and encourage users to develop new skills",
|
||||||
|
"Learned helplessness fades when we realize tech isn’t too complex to understand",
|
||||||
|
"FOSS empowers users to customize and improve their tools",
|
||||||
|
"Engaging with FOSS helps build confidence and self-reliance in tech",
|
||||||
|
"FOSS tools are accessible and often better than closed alternatives",
|
||||||
|
"FOSS shows that anyone can shape the digital world with curiosity and effort",
|
||||||
|
"Linux can revive old computers, extending their life and reducing e-waste",
|
||||||
|
"Many lightweight Linux distributions run smoothly on older hardware",
|
||||||
|
"Installing Linux on aging devices keeps them functional instead of sending them to the landfill",
|
||||||
|
"Linux uses fewer resources, making it ideal for reusing older machines",
|
||||||
|
"By using Linux, you can avoid buying new hardware, cutting down on tech waste",
|
||||||
|
"Instead of discarding slow devices, Linux can bring them back to life",
|
||||||
|
"Linux supports a wide range of devices, helping to prevent e-waste",
|
||||||
|
"Open-source drivers in Linux enable compatibility with old peripherals, reducing the need for replacements",
|
||||||
|
"Free Linux software helps users avoid planned obsolescence in commercial products",
|
||||||
|
"Switching to Linux promotes sustainability by reducing demand for new gadgets and lowering e-waste"
|
||||||
|
]
|
||||||
|
|
||||||
|
const motd = `
|
||||||
|
\r[38;5;57m . . ____ _____________ ________. ._. ._. . .
|
||||||
|
\r[38;5;93m . . .\\ \\/ /\\______ \\/ _____// | \\. .
|
||||||
|
\r[38;5;93m . . . \\ / | _/\\_____ \\/ ~ \\ .
|
||||||
|
\r[38;5;129m . . . / \\ | | \\/ \\ Y / .
|
||||||
|
\r[38;5;165m . . ./___/\\ \\ |____|_ /_______ /\\___|_ /. .
|
||||||
|
\r[38;5;201m . . . . . .\\_/. . . . \\/ . . . .\\/ . . _ \\/ . .
|
||||||
|
\r[38;5;165m ▬▬▬▬▬▬▬▬ https://xrsh.isvery.ninja ▬▬▬▬▬▬▬▬▬▬▬▬
|
||||||
|
\r[38;5;165m local-first, polyglot, unixy WebXR IDE & runtime
|
||||||
|
\r
|
||||||
|
\r credits: NLnet | @nlnet@nlnet.nl
|
||||||
|
\r MrDoob | THREE.js
|
||||||
|
\r Diego Marcos | AFRAME.js
|
||||||
|
\r Leon van Kammen | @lvk@mastodon.online
|
||||||
|
\r Fabien Benetou | @utopiah@mastodon.pirateparty.be
|
||||||
|
`
|
||||||
|
|
||||||
const text_color = "\r[38;5;129m"
|
const text_color = "\r[38;5;129m"
|
||||||
const text_reset = "\033[0m"
|
const text_reset = "\033[0m"
|
||||||
|
const loadmsg = "\n\r "+loading[ Math.floor(Math.random()*1000) % loading.length ] + "..[please wait]"
|
||||||
|
const empowermsg = "\n\r "+text_reset+'"'+empower[ Math.floor(Math.random()*1000) % empower.length ] + '"\n\r'
|
||||||
this.emit('status',loadmsg)
|
this.emit('status',loadmsg)
|
||||||
this.emit('serial-output-string', text_color + loadmsg + text_reset + "\n\r")
|
this.emit('serial-output-string', motd + empowermsg + text_color + loadmsg + text_reset+"\n\r")
|
||||||
|
|
||||||
|
|
||||||
this.addEventListener('emulator-started', async (e) => {
|
this.addEventListener('emulator-started', async (e) => {
|
||||||
|
|
||||||
|
@ -222,17 +260,25 @@ ISOTerminal.prototype.start = function(opts){
|
||||||
const str = e.detail
|
const str = e.detail
|
||||||
|
|
||||||
// lets scan for a prompt so we can send a 'ready' event to the world
|
// lets scan for a prompt so we can send a 'ready' event to the world
|
||||||
if( !this.ready && str.match(/\n(\/ #|~%|\[.*\]>)/) ){
|
if( !this.ready && str.match(/\n(\/ #|~%|\[.*\]>)/) ) this.postBoot()
|
||||||
this.emit('postReady',{})
|
|
||||||
this.ready = true
|
if( this.ready || !this.opts.muteUntilPrompt ) this.emit('serial-output-string', e.detail )
|
||||||
setTimeout( () => this.emit('ready',{}), 500 )
|
|
||||||
}
|
|
||||||
if( this.ready ) this.emit('serial-output-string', e.detail )
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ISOTerminal.prototype.postBoot = function(cb){
|
||||||
|
this.emit('postReady',{})
|
||||||
|
this.ready = true
|
||||||
|
setTimeout( () => {
|
||||||
|
this.emit('ready',{})
|
||||||
|
if( cb ) cb()
|
||||||
|
}, 500 )
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is allows (unsophisticated) outputbuffering
|
||||||
ISOTerminal.prototype.bufferOutput = function(byte,cb,latency){
|
ISOTerminal.prototype.bufferOutput = function(byte,cb,latency){
|
||||||
const resetBuffer = () => ({str:""})
|
const resetBuffer = () => ({str:""})
|
||||||
this.buffer = this.buffer || resetBuffer()
|
this.buffer = this.buffer || resetBuffer()
|
||||||
|
@ -247,3 +293,26 @@ ISOTerminal.prototype.bufferOutput = function(byte,cb,latency){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ISOTerminal.prototype.preventFrameDrop = function(cb){
|
||||||
|
// don't let workers cause framerate dropping
|
||||||
|
const xr = this.instance.sceneEl.renderer.xr
|
||||||
|
if( xr.isPresenting ){
|
||||||
|
xr.getSession().requestAnimationFrame(cb)
|
||||||
|
}else{
|
||||||
|
window.requestAnimationFrame(cb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISOTerminal.prototype.getTransferable = function(data){
|
||||||
|
function isTransferable(obj) {
|
||||||
|
return obj instanceof ArrayBuffer ||
|
||||||
|
obj instanceof MessagePort ||
|
||||||
|
obj instanceof ImageBitmap ||
|
||||||
|
(typeof OffscreenCanvas !== 'undefined' && obj instanceof OffscreenCanvas) ||
|
||||||
|
(typeof ReadableStream !== 'undefined' && obj instanceof ReadableStream) ||
|
||||||
|
(typeof WritableStream !== 'undefined' && obj instanceof WritableStream) ||
|
||||||
|
(typeof TransformStream !== 'undefined' && obj instanceof TransformStream);
|
||||||
|
}
|
||||||
|
if( isTransferable(data) ) console.log("Transferable!")
|
||||||
|
if( isTransferable(data) ) return isTransferable(data) ? [data] : undefined
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
if( typeof emulator != 'undefined' ){
|
if( typeof emulator != 'undefined' ){
|
||||||
// inside worker-thread
|
// inside worker-thread
|
||||||
|
|
||||||
this['emulator.restore_state'] = async function(){
|
this['emulator.restore_state'] = async function(data){
|
||||||
await emulator.restore_state.apply(emulator, arguments[0])
|
await emulator.restore_state(data)
|
||||||
|
console.log("restored state")
|
||||||
this.postMessage({event:"state_restored",data:false})
|
this.postMessage({event:"state_restored",data:false})
|
||||||
}
|
}
|
||||||
this['emulator.save_state'] = async function(){
|
this['emulator.save_state'] = async function(){
|
||||||
let state = await emulator.save_state.apply(emulator, arguments[0])
|
console.log("saving session")
|
||||||
|
let state = await emulator.save_state()
|
||||||
this.postMessage({event:"state_saved",data:state})
|
this.postMessage({event:"state_saved",data:state})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,23 +33,8 @@ if( typeof emulator != 'undefined' ){
|
||||||
state = this.convert.base64ToArrayBuffer( stateBase64 )
|
state = this.convert.base64ToArrayBuffer( stateBase64 )
|
||||||
|
|
||||||
this.addEventListener('state_restored', function(){
|
this.addEventListener('state_restored', function(){
|
||||||
this.emit('postReady',e)
|
// simulate / fastforward boot events
|
||||||
setTimeout( () => {
|
this.postBoot( () => this.send("l\n") )
|
||||||
this.emit('ready',e)
|
|
||||||
// press CTRL+a l (=gnu screen redisplay)
|
|
||||||
setTimeout( () => this.send("l\n"),400 )
|
|
||||||
// reload index.js
|
|
||||||
this.emulator.read_file("root/index.js")
|
|
||||||
.then( this.convert.Uint8ArrayToString )
|
|
||||||
.then( this.runJavascript )
|
|
||||||
.catch( console.error )
|
|
||||||
// reload index.html
|
|
||||||
this.emulator.read_file("root/index.html")
|
|
||||||
.then( this.convert.Uint8ArrayToString )
|
|
||||||
.then( this.runHTML )
|
|
||||||
.catch( console.error )
|
|
||||||
|
|
||||||
}, 500 )
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.worker.postMessage({event:'emulator.restore_state',data:state})
|
this.worker.postMessage({event:'emulator.restore_state',data:state})
|
||||||
|
@ -55,13 +42,13 @@ if( typeof emulator != 'undefined' ){
|
||||||
})
|
})
|
||||||
|
|
||||||
this.save = async () => {
|
this.save = async () => {
|
||||||
const state = await this.worker.postMessage({event:"save_state",data:false})
|
const state = await this.worker.postMessage({event:"emulator.save_state",data:false})
|
||||||
console.log( String(this.convert.arrayBufferToBase64(state)).substr(0,5) )
|
|
||||||
localforage.setItem("state", this.convert.arrayBufferToBase64(state) )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addEventListener('state_saved', function(data){
|
this.addEventListener('state_saved', function(e){
|
||||||
debugger
|
const state = e.detail
|
||||||
|
localforage.setItem("state", this.convert.arrayBufferToBase64(state) )
|
||||||
|
console.log("state saved")
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener("beforeunload", function (e) {
|
window.addEventListener("beforeunload", function (e) {
|
||||||
|
|
|
@ -14,8 +14,7 @@ ISOTerminal.prototype.boot = async function(e){
|
||||||
|
|
||||||
if( this.serial_input == 0 ){
|
if( this.serial_input == 0 ){
|
||||||
if( !this.noboot ){
|
if( !this.noboot ){
|
||||||
let boot = "source /etc/profile\n"
|
this.send("source /etc/profile # \\o/ FOSS powa!\n")
|
||||||
this.send(boot+"\n")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,6 @@
|
||||||
importScripts("libv86.js");
|
importScripts("libv86.js");
|
||||||
importScripts("ISOTerminal.js") // we don't instance it again here (just use its functions)
|
importScripts("ISOTerminal.js") // we don't instance it again here (just use its functions)
|
||||||
|
|
||||||
//var emulator = new V86({
|
|
||||||
// wasm_path: "../build/v86.wasm",
|
|
||||||
// memory_size: 32 * 1024 * 1024,
|
|
||||||
// vga_memory_size: 2 * 1024 * 1024,
|
|
||||||
// bios: {
|
|
||||||
// url: "../bios/seabios.bin",
|
|
||||||
// },
|
|
||||||
// vga_bios: {
|
|
||||||
// url: "../bios/vgabios.bin",
|
|
||||||
// },
|
|
||||||
// cdrom: {
|
|
||||||
// url: "../images/linux4.iso",
|
|
||||||
// },
|
|
||||||
// autostart: true,
|
|
||||||
//});
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//emulator.add_listener("serial0-output-byte", function(byte)
|
|
||||||
//{
|
|
||||||
// var chr = String.fromCharCode(byte);
|
|
||||||
// this.postMessage(chr);
|
|
||||||
//}.bind(this));
|
|
||||||
//
|
|
||||||
//this.onmessage = function(e)
|
|
||||||
//{
|
|
||||||
// emulator.serial0_send(e.data);
|
|
||||||
//};
|
|
||||||
|
|
||||||
this.runISO = function(opts){
|
this.runISO = function(opts){
|
||||||
if( opts.cdrom && !opts.cdrom.url.match(/^http/) ) opts.cdrom.url = "../../"+opts.cdrom.url
|
if( opts.cdrom && !opts.cdrom.url.match(/^http/) ) opts.cdrom.url = "../../"+opts.cdrom.url
|
||||||
if( opts.bzimage && !opts.cdrom.url.match(/^http/) ) opts.bzimage.url = "../../"+opts.bzimage.url
|
if( opts.bzimage && !opts.cdrom.url.match(/^http/) ) opts.bzimage.url = "../../"+opts.bzimage.url
|
||||||
|
|
21
com/xterm.js
21
com/xterm.js
|
@ -103,8 +103,8 @@ AFRAME.registerComponent('xterm', {
|
||||||
init: function () {
|
init: function () {
|
||||||
const terminalElement = document.createElement('div')
|
const terminalElement = document.createElement('div')
|
||||||
terminalElement.setAttribute('style', `
|
terminalElement.setAttribute('style', `
|
||||||
width: ${Math.floor( window.innerWidth * 0.7 )}px;
|
width: 800px;
|
||||||
height: ${Math.floor( window.innerHeight * 0.7 )}px;
|
height: ${Math.floor( 800 * 0.527 )}px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
`)
|
`)
|
||||||
|
|
||||||
|
@ -133,6 +133,8 @@ AFRAME.registerComponent('xterm', {
|
||||||
return theme
|
return theme
|
||||||
}, {})
|
}, {})
|
||||||
|
|
||||||
|
this.fontSize = 14
|
||||||
|
|
||||||
const term = this.term = new Terminal({
|
const term = this.term = new Terminal({
|
||||||
logLevel:"off",
|
logLevel:"off",
|
||||||
theme: theme,
|
theme: theme,
|
||||||
|
@ -141,12 +143,13 @@ AFRAME.registerComponent('xterm', {
|
||||||
disableStdin: false,
|
disableStdin: false,
|
||||||
rows: this.data.rows,
|
rows: this.data.rows,
|
||||||
cols: this.data.cols,
|
cols: this.data.cols,
|
||||||
fontSize: 14,
|
fontSize: this.fontSize,
|
||||||
lineHeight: 1.15,
|
lineHeight: 1.15,
|
||||||
|
useFlowControl: true,
|
||||||
rendererType: this.renderType // 'dom' // 'canvas'
|
rendererType: this.renderType // 'dom' // 'canvas'
|
||||||
})
|
})
|
||||||
|
|
||||||
this.tick = AFRAME.utils.throttle( () => {
|
this.tick = AFRAME.utils.throttleLeadingAndTrailing( () => {
|
||||||
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)
|
||||||
|
@ -165,7 +168,7 @@ AFRAME.registerComponent('xterm', {
|
||||||
const $screen = terminalElement.querySelector('.xterm-screen')
|
const $screen = terminalElement.querySelector('.xterm-screen')
|
||||||
$screen.style.width = '100%'
|
$screen.style.width = '100%'
|
||||||
|
|
||||||
term.on('refresh', AFRAME.utils.throttle( () => this.update(), 150 ) )
|
term.on('refresh', AFRAME.utils.throttleLeadingAndTrailing( () => this.update(), 150 ) )
|
||||||
term.on('data', (data) => {
|
term.on('data', (data) => {
|
||||||
this.el.emit('xterm-input', data)
|
this.el.emit('xterm-input', data)
|
||||||
})
|
})
|
||||||
|
@ -200,14 +203,14 @@ AFRAME.registerComponent('xterm', {
|
||||||
|
|
||||||
if( type == 'dom'){
|
if( type == 'dom'){
|
||||||
this.el.dom.appendChild(this.el.terminalElement)
|
this.el.dom.appendChild(this.el.terminalElement)
|
||||||
this.term.setOption('fontSize', 14 )
|
this.term.setOption('fontSize', this.fontSize )
|
||||||
this.term.setOption('rendererType',type )
|
this.term.setOption('rendererType',type )
|
||||||
this.renderType = type
|
this.renderType = type
|
||||||
}
|
}
|
||||||
|
|
||||||
if( type == 'canvas'){
|
if( type == 'canvas'){
|
||||||
this.el.appendChild(this.el.terminalElement)
|
this.el.appendChild(this.el.terminalElement)
|
||||||
this.term.setOption('fontSize', 48 )
|
this.term.setOption('fontSize', this.fontSize * 3 )
|
||||||
this.term.setOption('rendererType',type )
|
this.term.setOption('rendererType',type )
|
||||||
this.renderType = type
|
this.renderType = type
|
||||||
this.update()
|
this.update()
|
||||||
|
@ -218,8 +221,8 @@ AFRAME.registerComponent('xterm', {
|
||||||
this.cursorCanvas = this.el.terminalElement.querySelector('.xterm-cursor-layer')
|
this.cursorCanvas = this.el.terminalElement.querySelector('.xterm-cursor-layer')
|
||||||
// Create a texture from the canvas
|
// Create a texture from the canvas
|
||||||
const canvasTexture = new THREE.Texture(this.canvas)
|
const canvasTexture = new THREE.Texture(this.canvas)
|
||||||
//canvasTexture.minFilter = THREE.LinearFilter
|
//canvasTexture.minFilter = THREE.NearestFilter //LinearFilter
|
||||||
//canvasTexture.magFilter = THREE.LinearFilter
|
//canvasTexture.magFilter = THREE.LinearMipMapLinearFilter //THREE.NearestFilter //LinearFilter
|
||||||
canvasTexture.needsUpdate = true; // Ensure the texture updates
|
canvasTexture.needsUpdate = true; // Ensure the texture updates
|
||||||
let plane = this.el.planeText.getObject3D("mesh") //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()
|
||||||
|
|
Loading…
Reference in New Issue