godot-rust / godot-rust/gdext

Panic when calling deferred reload through new typed API

Open
#1,249 15 comments 0 reactions 0 assignees View on GitHub
quality-of-life
Dominant language
Rust
Stars
5.2k
Forks
312
Avg merge
11h 10m
Merged PRs (30d)
10

Description

So, my build plugin is made with godot-rust, and it seems like GDExtensionManager's reload extension is incompatible when reloading the library it's being called from. This does make a lot of sense intuitively as the gdextension is still performing work inside that closure, but I thought it would be sensible to report it anyway. Here is the error message, but I don't know how to access anything else:

```bash
panicked at C:\Users\Sylbeth\scoop\persist\rustup\.cargo\git\checkouts\gdext-067f4b88e7bd088f\517053d\godot-core\src\private.rs:367:49:

thread panicked while processing panic. aborting.
```

The code for the build plugin's reloading I have here:

```rust
//! Build plugin, to manage the build script.

use std::sync::atomic::{AtomicBool, Ordering};

use godot::{
classes::{
EditorPlugin, GDExtensionManager, IEditorPlugin, editor_plugin::CustomControlContainer,
},
global::{godot_print, godot_str},
obj::{Base, WithBaseField, WithDeferredCall},
prelude::{GodotClass, godot_api},
};

use buttons::{BuildButtons, construct_build_buttons};

pub mod buttons;
pub mod commands;

static MUST_RELOAD: AtomicBool = AtomicBool::new(false);

/// A plugin that adds buttons for the ease of this gdext compilation.
#[derive(GodotClass)]
#[class(tool, init, base=EditorPlugin)]
pub struct BuildPlugin {
/// Buttons loaded by the plugin.
buttons: Option,

/// Base class of the node.
base: Base,
}

#[godot_api]
impl IEditorPlugin for BuildPlugin {
fn enter_tree(&mut self) {
let buttons = construct_build_buttons();
for button in buttons.iter() {
self.base_mut()
.add_control_to_container(CustomControlContainer::TOOLBAR, button);
}
self.buttons = Some(buttons);
}

fn ready(&mut self) {
godot_print!("BuildPlugin: Ready!");
}

fn process(&mut self, _delta: f32) {
if MUST_RELOAD.swap(false, Ordering::Acquire) {
GDExtensionManager::singleton().apply_deferred(|gdextension_manager| {
godot_print!("BuildPlugin: Reloading GDExtension.");
gdextension_manager
.reload_extension(&godot_str!("res://{}", env!("GDEXTENSION-FILE-PATH")));
});
}
}

fn exit_tree(&mut self) {
if let Some(buttons) = std::mem::replace(&mut self.buttons, None) {
for button in buttons {
self.base_mut()
.remove_control_from_container(CustomControlContainer::TOOLBAR, &button);
button.free();
}
}
}
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.