Support persisting filesystem

This commit is contained in:
momo5502
2025-06-15 17:33:29 +02:00
parent b51dd0e94a
commit 8ece8a556d
5 changed files with 48 additions and 11 deletions

View File

@@ -9,7 +9,7 @@ onmessage = async (event) => {
switch (data.message) {
case "run":
runEmulation(payload.file, payload.options);
runEmulation(payload.file, payload.options, payload.persist);
break;
case "event":
msgQueue.push(payload);
@@ -38,10 +38,19 @@ function logLine(text) {
}
}
function notifyExit(code) {
function notifyExit(code, persist) {
flushLines();
sendMessage("end", code);
self.close();
const finishExecution = () => {
sendMessage("end", code);
self.close();
};
if (persist) {
FS.syncfs(false, finishExecution);
} else {
finishExecution();
}
}
function handleMessage(message) {
@@ -56,7 +65,7 @@ function getMessageFromQueue() {
return msgQueue.shift();
}
function runEmulation(file, options) {
function runEmulation(file, options, persist) {
const mainArguments = [...options, "-e", "./root", file];
globalThis.Module = {
@@ -71,8 +80,8 @@ function runEmulation(file, options) {
},
print: logLine,
printErr: logLine,
onAbort: () => notifyExit(null),
onExit: notifyExit,
onAbort: () => notifyExit(null, persist),
onExit: (code) => notifyExit(code, persist),
postRun: flushLines,
};

View File

@@ -83,6 +83,17 @@ export class SettingsMenu extends React.Component<SettingsMenuProps, Settings> {
/>
<Label htmlFor="settings-buffer">Buffer stdout</Label>
</div>
<div className="flex gap-6">
<Checkbox
id="settings-persist"
checked={this.state.persist}
onCheckedChange={(checked: boolean) => {
this.setState({ persist: checked });
}}
/>
<Label htmlFor="settings-persist">Persist filesystem</Label>
</div>
</div>
);
}

View File

@@ -75,6 +75,7 @@ export class Emulator {
data: {
file,
options: translateSettings(settings),
persist: settings.persist,
},
});
}

View File

@@ -105,13 +105,25 @@ export class Playground extends React.Component<
location.reload();
}
initFilesys() {
if (this.state.filesystemPromise) {
_onEmulatorStateChanged(s: EmulationState, persistFs: boolean) {
if (s == EmulationState.Stopped && persistFs) {
this.setState({ filesystemPromise: null, filesystem: null });
this.initFilesys(true);
} else {
this.forceUpdate();
}
}
initFilesys(force: boolean = false) {
if (!force && this.state.filesystemPromise) {
return this.state.filesystemPromise;
}
const promise = new Promise<Filesystem>((resolve) => {
this.logLine("Loading filesystem...");
if (!force) {
this.logLine("Loading filesystem...");
}
setupFilesystem(
(current, total, file) => {
this.logLine(`Processing filesystem (${current}/${total}): ${file}`);
@@ -172,9 +184,11 @@ export class Playground extends React.Component<
await this.state.filesystemPromise;
}
const persistFs = this.state.settings.persist;
const new_emulator = new Emulator(
(l) => this.logLines(l),
(_) => this.forceUpdate(),
(s) => this._onEmulatorStateChanged(s, persistFs),
);
new_emulator.onTerminate().then(() => this.setState({ emulator: null }));

View File

@@ -3,6 +3,7 @@ export interface Settings {
concise: boolean;
silent: boolean;
bufferStdout: boolean;
persist: boolean;
}
export function createDefaultSettings(): Settings {
@@ -11,6 +12,7 @@ export function createDefaultSettings(): Settings {
concise: false,
silent: false,
bufferStdout: true,
persist: false,
};
}