Skip to content

Commit 6a4342f

Browse files
added remotestorage
1 parent c79af59 commit 6a4342f

File tree

7 files changed

+477
-47
lines changed

7 files changed

+477
-47
lines changed

com/isoterminal.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,15 +304,17 @@ if( typeof AFRAME != 'undefined '){
304304
remotekeyboard: "com/isoterminal/feat/remotekeyboard.js",
305305
indexhtml: "com/isoterminal/feat/index.html.js",
306306
indexjs: "com/isoterminal/feat/index.js.js",
307-
autorestore: "com/isoterminal/feat/autorestore.js",
308307
pastedropFeat: "com/isoterminal/feat/pastedrop.js",
309308
httpfs: "com/isoterminal/feat/httpfs.js",
309+
autorestore: "com/isoterminal/feat/autorestore.js",
310310
}
311311
if( this.data.emulator == 'fbterm' ){
312312
features['fbtermjs'] = "com/isoterminal/term.js"
313313
features['fbterm'] = "com/isoterminal/feat/term.js"
314314
}
315315
await AFRAME.utils.require(features)
316+
// this one extends autorestore.js
317+
await AFRAME.utils.require({remotestorage: "com/isoterminal/feat/remotestorage.js"})
316318

317319
this.el.setAttribute("selfcontainer","")
318320

com/isoterminal/ISOTerminal.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ ISOTerminal.prototype.startVM = function(opts){
256256
this.v86opts = opts
257257

258258
this.addEventListener('emulator-started', async (e) => {
259+
if( this.boot.fromImage ) return this.emit('serial-output-string', "\r[!] downloading session...please wait\n\r[!] this could take a while depending on your connection..\n\r")
259260

260261
let line = ''
261262
this.ready = false
@@ -278,12 +279,17 @@ ISOTerminal.prototype.startVM = function(opts){
278279
}
279280

280281
ISOTerminal.prototype.bootISO = function(){
282+
const getImage = (str) => decodeURIComponent(
283+
str.match(/\&img=/) ? str.replace(/.*img=/,'').replace(/\&.*/,'') : ''
284+
)
281285
let msglib = this.getLoaderMsg()
282286
this.emit('status',msglib.loadmsg)
283287
let msg = "\n\r" + msglib.empowermsg + msglib.text_color + msglib.loadmsg + msglib.text_reset
284288
this.emit('serial-output-string', msg)
285-
this.emit('runISO',{...this.v86opts, bufferLatency: this.opts.bufferLatency })
286-
289+
if( getImage(this.boot.hash) ){
290+
this.boot.fromImage = true
291+
}
292+
this.emit('runISO',{...this.v86opts, bufferLatency: this.opts.bufferLatency, img: getImage(this.boot.hash) })
287293
}
288294

289295

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1+
// this is restoring state to/from the v86 emulator
2+
// however instead of passing the huge blob between webworker/browser
3+
// we transfer it via localforage as a base64 string
4+
15
if( typeof emulator != 'undefined' ){
26
// inside worker-thread
37
importScripts("localforage.js") // we don't instance it again here (just use its functions)
48

59
this.restore_state = async function(data){
10+
// fastforward instance state
11+
this.opts.muteUntilPrompt = false
12+
this.ready = true
13+
614
return new Promise( (resolve,reject) => {
715
localforage.getItem("state", async (err,stateBase64) => {
816
if( stateBase64 && !err ){
@@ -15,15 +23,20 @@ if( typeof emulator != 'undefined' ){
1523
})
1624
}
1725
this.save_state = async function(){
18-
console.log("saving session")
19-
let state = await emulator.save_state()
20-
localforage.setDriver([
21-
localforage.INDEXEDDB,
22-
localforage.WEBSQL,
23-
localforage.LOCALSTORAGE
24-
]).then( () => {
25-
localforage.setItem("state", ISOTerminal.prototype.convert.arrayBufferToBase64(state) )
26-
console.log("state saved")
26+
return new Promise( async (resolve,reject ) => {
27+
console.log("saving session")
28+
let state = await emulator.save_state()
29+
localforage.setDriver([
30+
localforage.INDEXEDDB,
31+
localforage.WEBSQL,
32+
localforage.LOCALSTORAGE
33+
])
34+
.then( () => {
35+
localforage.setItem("state", ISOTerminal.prototype.convert.arrayBufferToBase64(state) )
36+
console.log("state saved")
37+
resolve()
38+
})
39+
.catch( reject )
2740
})
2841
}
2942

@@ -32,50 +45,62 @@ if( typeof emulator != 'undefined' ){
3245
// inside browser-thread
3346
ISOTerminal.addEventListener('emulator-started', function(e){
3447
this.autorestore(e)
48+
this.emit("autorestore-installed")
3549
})
3650

37-
ISOTerminal.prototype.autorestore = async function(e){
51+
ISOTerminal.prototype.restore = async function(e){
3852

39-
localforage.setDriver([
40-
localforage.INDEXEDDB,
41-
localforage.WEBSQL,
42-
localforage.LOCALSTORAGE
43-
]).then( () => {
53+
const onGetItem = (err,stateBase64) => {
54+
const askConfirm = () => {
55+
if( window.localStorage.getItem("restorestate") == "true" ) return true
56+
try{
57+
const scene = document.querySelector('a-scene');
58+
if( scene.is('ar-mode') ) scene.exitAR()
59+
if( scene.is('vr-mode') ) scene.exitVR()
60+
}catch(e){}
61+
return confirm( "Continue old session?" )
62+
}
4463

45-
localforage.getItem("state", async (err,stateBase64) => {
46-
const askConfirm = () => {
47-
if( window.localStorage.getItem("restorestate") == "true" ) return true
48-
try{
49-
const scene = document.querySelector('a-scene');
50-
if( scene.is('ar-mode') ) scene.exitAR()
51-
if( scene.is('vr-mode') ) scene.exitVR()
52-
}catch(e){}
53-
return confirm('continue last session?')
54-
}
55-
if( stateBase64 && !err && document.location.hash.length < 2 && askConfirm() ){
56-
this.noboot = true // see feat/boot.js
57-
try{
58-
await this.worker.restore_state()
64+
if( stateBase64 && !err && document.location.hash.length < 2 && askConfirm() ){
65+
this.noboot = true // see feat/boot.js
66+
try{
67+
this.worker.restore_state()
68+
.then( () => {
5969
// simulate / fastforward boot events
6070
this.postBoot( () => {
61-
this.send("l\n")
62-
this.send("hook wakeup\n")
71+
// force redraw terminal issue
72+
this.send("l")
73+
setTimeout( () => this.send("l"), 200 )
74+
//this.send("12")
75+
this.emit("exec",["source /etc/profile.sh; hook wakeup\n"])
76+
this.emit("restored")
6377
})
64-
}catch(e){ console.error(e) }
65-
}
66-
})
67-
68-
this.save = async () => {
69-
await this.worker.save_state()
78+
})
79+
}catch(e){ console.error(e) }
7080
}
81+
}
82+
83+
const doRestore = () => {
84+
85+
localforage.getItem("state", (err,stateBase64) => onGetItem(err,stateBase64) )
7186

7287
window.addEventListener("beforeunload", function (e) {
7388
var confirmationMessage = "Sure you want to leave?\nTIP: enter 'save' to continue this session later";
7489
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
7590
return confirmationMessage; //Webkit, Safari, Chrome
7691
});
7792

78-
})
93+
}
94+
95+
localforage.setDriver([
96+
localforage.INDEXEDDB,
97+
localforage.WEBSQL,
98+
localforage.LOCALSTORAGE
99+
])
100+
.then( () => doRestore() )
101+
79102
}
80103

104+
ISOTerminal.prototype.autorestore = ISOTerminal.prototype.restore // alias to launch during boot
105+
81106
}

com/isoterminal/feat/boot.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
ISOTerminal.addEventListener('ready', function(e){
2-
setTimeout( () => this.boot(), 50 ) // because of autorestore.js
2+
setTimeout( () => this.boot(), 50 ) // allow other features/plugins to settle first (autorestore.js e.g.)
33
})
44

55
ISOTerminal.prototype.bootMenu = function(e){
@@ -17,7 +17,7 @@ ISOTerminal.prototype.bootMenu = function(e){
1717

1818
}else{ // autoboot
1919
if( this.term ){
20-
this.term.handler( e.detail.bootMenu || e.detail.bootMenuURL )
20+
this.term.handler( String(e.detail.bootMenu || e.detail.bootMenuURL).charAt(0) )
2121
this.term.handler("\n")
2222
}
2323
}
@@ -33,10 +33,17 @@ ISOTerminal.prototype.boot = async function(e){
3333
'export BROWSER=1',
3434
]
3535
for ( let i in document.location ){
36-
if( typeof document.location[i] == 'string' ){
36+
if( typeof document.location[i] == 'string' && !String(i).match(/(hash|search)/) ){
3737
env.push( 'export '+String(i).toUpperCase()+'="'+decodeURIComponent( document.location[i]+'"') )
3838
}
3939
}
40+
41+
// we export the cached hash/query (because they might be gone due to remotestorage plugin)
42+
if( this.boot.hash.charAt(2) == '&' ){ // strip bootoption
43+
this.boot.hashExBoot = `#` + this.boot.hash.substr(3)
44+
}
45+
env.push( 'export HASH="'+decodeURIComponent( this.boot.hashExBoot || this.boot.hash ) +'"' )
46+
env.push( 'export QUERY="'+decodeURIComponent( this.boot.query ) +'"' )
4047
await this.worker.create_file("profile.browser", this.convert.toUint8Array( env.join('\n') ) )
4148

4249
if( this.serial_input == 0 ){
@@ -47,8 +54,12 @@ ISOTerminal.prototype.boot = async function(e){
4754

4855
}
4956

50-
// here REPL's can be defined
57+
ISOTerminal.prototype.boot.fromImage = false
5158
ISOTerminal.prototype.boot.menu = []
59+
ISOTerminal.prototype.boot.hash = document.location.hash
60+
ISOTerminal.prototype.boot.query = document.location.search
61+
62+
// here REPL's can be defined
5263

5364
// REPL: iso
5465
if( typeof window.PromiseWorker != 'undefined' ){ // if xrsh v86 is able to run in in worker

0 commit comments

Comments
 (0)