Improve unregistering XR interfaces so we don't get crashes in GDExtensions by destroying the XRServer too early

This commit is contained in:
Bastiaan Olij 2021-09-28 12:15:00 +10:00
parent 4f4f73b82f
commit 0623d3676b
3 changed files with 43 additions and 4 deletions

View file

@ -2689,8 +2689,9 @@ void Main::cleanup(bool p_force) {
rendering_server->global_variables_clear(); rendering_server->global_variables_clear();
if (xr_server) { if (xr_server) {
// cleanup now before we pull the rug from underneath... // Now that we're unregistering properly in plugins we need to keep access to xr_server for a little longer
memdelete(xr_server); // We do however unset our primary interface
xr_server->set_primary_interface(Ref<XRInterface>());
} }
unregister_driver_types(); unregister_driver_types();
@ -2706,6 +2707,10 @@ void Main::cleanup(bool p_force) {
unregister_scene_types(); unregister_scene_types();
unregister_server_types(); unregister_server_types();
if (xr_server) {
memdelete(xr_server);
}
if (audio_server) { if (audio_server) {
audio_server->finish(); audio_server->finish();
memdelete(audio_server); memdelete(audio_server);

View file

@ -32,15 +32,30 @@
#include "mobile_vr_interface.h" #include "mobile_vr_interface.h"
Ref<MobileVRInterface> mobile_vr;
void register_mobile_vr_types() { void register_mobile_vr_types() {
GDREGISTER_CLASS(MobileVRInterface); GDREGISTER_CLASS(MobileVRInterface);
if (XRServer::get_singleton()) { if (XRServer::get_singleton()) {
Ref<MobileVRInterface> mobile_vr;
mobile_vr.instantiate(); mobile_vr.instantiate();
XRServer::get_singleton()->add_interface(mobile_vr); XRServer::get_singleton()->add_interface(mobile_vr);
} }
} }
void unregister_mobile_vr_types() { void unregister_mobile_vr_types() {
if (mobile_vr.is_valid()) {
// uninitialise our interface if it is initialised
if (mobile_vr->is_initialized()) {
mobile_vr->uninitialize();
}
// unregister our interface from the XR server
if (XRServer::get_singleton()) {
XRServer::get_singleton()->remove_interface(mobile_vr);
}
// and release
mobile_vr.unref();
}
} }

View file

@ -33,15 +33,34 @@
#include "webxr_interface.h" #include "webxr_interface.h"
#include "webxr_interface_js.h" #include "webxr_interface_js.h"
#ifdef JAVASCRIPT_ENABLED
Ref<WebXRInterfaceJS> webxr;
#endif
void register_webxr_types() { void register_webxr_types() {
GDREGISTER_VIRTUAL_CLASS(WebXRInterface); GDREGISTER_VIRTUAL_CLASS(WebXRInterface);
#ifdef JAVASCRIPT_ENABLED #ifdef JAVASCRIPT_ENABLED
Ref<WebXRInterfaceJS> webxr;
webxr.instantiate(); webxr.instantiate();
XRServer::get_singleton()->add_interface(webxr); XRServer::get_singleton()->add_interface(webxr);
#endif #endif
} }
void unregister_webxr_types() { void unregister_webxr_types() {
#ifdef JAVASCRIPT_ENABLED
if (webxr.is_valid()) {
// uninitialise our interface if it is initialised
if (webxr->is_initialized()) {
webxr->uninitialize();
}
// unregister our interface from the XR server
if (XRServer::get_singleton()) {
XRServer::get_singleton()->remove_interface(webxr);
}
// and release
webxr.unref();
}
#endif
} }