Use dummy driver when JS AudioContext is unavailable.
This commit is contained in:
parent
399e2c1db0
commit
357e99a31e
|
@ -36,6 +36,15 @@
|
|||
|
||||
AudioDriverJavaScript *AudioDriverJavaScript::singleton = NULL;
|
||||
|
||||
bool AudioDriverJavaScript::is_available() {
|
||||
return EM_ASM_INT({
|
||||
if (!(window.AudioContext || window.webkitAudioContext)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}) != 0;
|
||||
}
|
||||
|
||||
const char *AudioDriverJavaScript::get_name() const {
|
||||
return "JavaScript";
|
||||
}
|
||||
|
@ -207,12 +216,14 @@ void AudioDriverJavaScript::finish_async() {
|
|||
|
||||
/* clang-format off */
|
||||
EM_ASM({
|
||||
var ref = Module.IDHandler.get($0);
|
||||
const id = $0;
|
||||
var ref = Module.IDHandler.get(id);
|
||||
Module.async_finish.push(new Promise(function(accept, reject) {
|
||||
if (!ref) {
|
||||
console.log("Ref not found!", $0, Module.IDHandler);
|
||||
console.log("Ref not found!", id, Module.IDHandler);
|
||||
setTimeout(accept, 0);
|
||||
} else {
|
||||
Module.IDHandler.remove(id);
|
||||
const context = ref['context'];
|
||||
// Disconnect script and input.
|
||||
ref['script'].disconnect();
|
||||
|
@ -226,7 +237,6 @@ void AudioDriverJavaScript::finish_async() {
|
|||
});
|
||||
}
|
||||
}));
|
||||
Module.IDHandler.remove($0);
|
||||
}, id);
|
||||
/* clang-format on */
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class AudioDriverJavaScript : public AudioDriver {
|
|||
int buffer_length;
|
||||
|
||||
public:
|
||||
static bool is_available();
|
||||
void mix_to_js();
|
||||
void process_capture(float sample);
|
||||
|
||||
|
|
|
@ -74,10 +74,17 @@ void main_loop_callback() {
|
|||
}
|
||||
if (os->main_loop_iterate()) {
|
||||
emscripten_cancel_main_loop(); // Cancel current loop and wait for finalize_async.
|
||||
/* clang-format off */
|
||||
EM_ASM({
|
||||
// This will contain the list of operations that need to complete before cleanup.
|
||||
Module.async_finish = [];
|
||||
Module.async_finish = [
|
||||
// Always contains at least one async promise, to avoid firing immediately if nothing is added.
|
||||
new Promise(function(accept, reject) {
|
||||
setTimeout(accept, 0);
|
||||
})
|
||||
];
|
||||
});
|
||||
/* clang-format on */
|
||||
os->get_main_loop()->finish();
|
||||
os->finalize_async(); // Will add all the async finish functions.
|
||||
EM_ASM({
|
||||
|
|
|
@ -297,7 +297,7 @@ EM_BOOL OS_JavaScript::keydown_callback(int p_event_type, const EmscriptenKeyboa
|
|||
}
|
||||
os->input->parse_input_event(ev);
|
||||
// Resume audio context after input in case autoplay was denied.
|
||||
os->audio_driver_javascript.resume();
|
||||
os->resume_audio();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -390,7 +390,7 @@ EM_BOOL OS_JavaScript::mouse_button_callback(int p_event_type, const EmscriptenM
|
|||
|
||||
os->input->parse_input_event(ev);
|
||||
// Resume audio context after input in case autoplay was denied.
|
||||
os->audio_driver_javascript.resume();
|
||||
os->resume_audio();
|
||||
// Prevent multi-click text selection and wheel-click scrolling anchor.
|
||||
// Context menu is prevented through contextmenu event.
|
||||
return true;
|
||||
|
@ -742,7 +742,7 @@ EM_BOOL OS_JavaScript::touch_press_callback(int p_event_type, const EmscriptenTo
|
|||
os->input->parse_input_event(ev);
|
||||
}
|
||||
// Resume audio context after input in case autoplay was denied.
|
||||
os->audio_driver_javascript.resume();
|
||||
os->resume_audio();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1099,6 +1099,12 @@ MainLoop *OS_JavaScript::get_main_loop() const {
|
|||
return main_loop;
|
||||
}
|
||||
|
||||
void OS_JavaScript::resume_audio() {
|
||||
if (audio_driver_javascript) {
|
||||
audio_driver_javascript->resume();
|
||||
}
|
||||
}
|
||||
|
||||
bool OS_JavaScript::main_loop_iterate() {
|
||||
|
||||
if (is_userfs_persistent() && sync_wait_time >= 0) {
|
||||
|
@ -1166,7 +1172,9 @@ void OS_JavaScript::finalize_async() {
|
|||
});
|
||||
Module.listeners = {};
|
||||
});
|
||||
audio_driver_javascript.finish_async();
|
||||
if (audio_driver_javascript) {
|
||||
audio_driver_javascript->finish_async();
|
||||
}
|
||||
}
|
||||
|
||||
void OS_JavaScript::finalize() {
|
||||
|
@ -1176,6 +1184,9 @@ void OS_JavaScript::finalize() {
|
|||
emscripten_webgl_commit_frame();
|
||||
memdelete(visual_server);
|
||||
emscripten_webgl_destroy_context(webgl_ctx);
|
||||
if (audio_driver_javascript) {
|
||||
memdelete(audio_driver_javascript);
|
||||
}
|
||||
}
|
||||
|
||||
// Miscellaneous
|
||||
|
@ -1415,11 +1426,15 @@ OS_JavaScript::OS_JavaScript(int p_argc, char *p_argv[]) {
|
|||
|
||||
main_loop = NULL;
|
||||
visual_server = NULL;
|
||||
audio_driver_javascript = NULL;
|
||||
|
||||
idb_available = false;
|
||||
sync_wait_time = -1;
|
||||
|
||||
AudioDriverManager::add_driver(&audio_driver_javascript);
|
||||
if (AudioDriverJavaScript::is_available()) {
|
||||
audio_driver_javascript = memnew(AudioDriverJavaScript);
|
||||
AudioDriverManager::add_driver(audio_driver_javascript);
|
||||
}
|
||||
|
||||
Vector<Logger *> loggers;
|
||||
loggers.push_back(memnew(StdLogger));
|
||||
|
|
|
@ -66,7 +66,7 @@ class OS_JavaScript : public OS_Unix {
|
|||
|
||||
MainLoop *main_loop;
|
||||
int video_driver_index;
|
||||
AudioDriverJavaScript audio_driver_javascript;
|
||||
AudioDriverJavaScript *audio_driver_javascript;
|
||||
VisualServer *visual_server;
|
||||
|
||||
bool idb_available;
|
||||
|
@ -93,6 +93,8 @@ class OS_JavaScript : public OS_Unix {
|
|||
static void file_access_close_callback(const String &p_file, int p_flags);
|
||||
|
||||
protected:
|
||||
void resume_audio();
|
||||
|
||||
virtual int get_current_video_driver() const;
|
||||
|
||||
virtual void initialize_core();
|
||||
|
|
Loading…
Reference in New Issue