How To Change Emscripten Browser Input Method From Window.prompt To Something More Sensible?
Solution 1:
From what I understand you could try the following:
- Implement selecting a file in Javascript and access it via Javascript
Blob
interface. Allocate some memory in Emscripten
var buf = Module._malloc( blob.size );
Write the content of your
Blob
into the returned memory location from Javascript.Module.HEAPU8.set( new Uint8Array(blob), buf );
Pass that memory location to a second Emscripten compiled function, which then processes the file content and
Deallocate allocated memory.
Module._free( buf );
Best to read the wiki first.
Solution 2:
A way would be to use the Emscripten Filesystem API, for example by calling FS.init in the Module preRun function, passing a custom function as the standard input.
var Module = {
preRun: function() {
functionstdin() {
// Return ASCII code of character, or null if no input
}
var stdout = null; // Keep as defaultvar stderr = null; // Keep as default
FS.init(stdin, stdout, stderr);
}
};
The function is quite low-level: is must deal with one character at a time. To read some data from a blob, you could do something like:
var data = newInt8Array([1,2,3,4,5]);
var blob = newBlob([array], {type: 'application/octet-binary'});
var reader = newFileReader();
var result;
reader.addEventListener("loadend", function() {
result = newInt8Array(reader.result);
});
var i = 0;
varModule = {
preRun: function() {
functionstdin() {
if (if < result.byteLength {
var code = result[i];
++i;
return code;
} else {
returnnull;
}
}
var stdout = null; // Keep as defaultvar stderr = null; // Keep as defaultFS.init(stdin, stdout, stderr);
}
};
Note (as you have hinted), due to the asynchronous nature of the reader, there could be a race condition: the reader must have loaded before you can expect the data at the standard input. You might need to implement some mechanism to avoid this in a real case. Depending on your exact requirements, you could make it so the Emscripten program doesn't actually call main()
until you have the data:
var fileRead = false;
var initialised = false;
var result;
var array = newInt8Array([1,2,3,4,5]);
var blob = newBlob([array], {type: 'application/octet-binary'});
var reader = newFileReader();
reader.addEventListener("loadend", function() {
result = newInt8Array(reader.result);
fileRead = true;
runIfCan();
});
reader.readAsArrayBuffer(blob);
var i = 0;
varModule = {
preRun: function() {
functionstdin() {
if (i < result.byteLength)
{
var code = result[i];
++i;
return code;
} else{
returnnull;
}
}
var stdout = null;
var stderr = null;
FS.init(stdin, stdout, stderr);
initialised = true;
runIfCan();
},
noInitialRun: true
};
functionrunIfCan() {
if (fileRead && initialised) {
// Module.run() doesn't seem to work hereModule.callMain();
}
}
Note: this is a version of my answer at Providing stdin to an emscripten HTML program? , but with focus on the standard input, and adding parts about passing data from a Blob.
Post a Comment for "How To Change Emscripten Browser Input Method From Window.prompt To Something More Sensible?"