Coder Social home page Coder Social logo

There is no _input function about gdext HOT 6 CLOSED

godot-rust avatar godot-rust commented on May 31, 2024 1
There is no _input function

from gdext.

Comments (6)

bluenote10 avatar bluenote10 commented on May 31, 2024 2

FYI I tried out #136 (looking great!) to see how it handles the _input function, but it looks like it is running into the same issue: The event: Gd<InputEvent> provided by the engine seems to be freed already, and trying to do anything with it results in a panic. I'm still unsure if this is a bug in Godot itself, or if there is happening something on the FFI level that causes the object to be invalid.

from gdext.

bluenote10 avatar bluenote10 commented on May 31, 2024

Just did a small experiment. Interestingly just adding

fn input(&mut self) {
     unimplemented!()
}

there and modifying the VIRTUAL_METHOD_NAMES in godot-macros/src/godot_api.rs to

const VIRTUAL_METHOD_NAMES: [&str; 4] = ["ready", "input", "process", "physics_process"];

already does seem to do something, i.e., my callback was called successfully.

What didn't work is adding an argument event: InputEvent, because it doesn't satisfy the GodotFfi trait. I could imagine that this is the main work to do here, although I haven't figured out yet how the whole function call mechanism works.

from gdext.

Bromeon avatar Bromeon commented on May 31, 2024

What didn't work is adding an argument event: InputEvent, because it doesn't satisfy the GodotFfi trait. I could imagine that this is the main work to do here, although I haven't figured out yet how the whole function call mechanism works.

You could try Gd<InputEvent> instead of InputEvent -- all objects need to be transported via Gd smart pointer.


This fix is relatively easy by itself; just repeat the work for the methods listed -- but that's only half of the story.

We still don't support other virtual functions (declared by classes other than Node), and need a scalable approach for them. There were mostly two ideas around:

  1. Generate code for traits in the style of GodotExt for other classes.
    • This might add a ton of highly specialized tiny traits though, and require many impl blocks every time.
  2. Have a "fallback" mechanism to override virtual methods without the type safety.
    • Example syntax: #[func(override)] in a normal GodotApi block. Similar to how GDNative works but slightly more explicit.

from gdext.

bluenote10 avatar bluenote10 commented on May 31, 2024

You could try Gd instead of InputEvent

That indeed results in something that compiles, but crashes at runtime (note that it is after the input method has been called):

[...]
Experiment::input() called
ERROR: Condition "slot >= slot_max" is true. Returning: nullptr
   at: get_instance (./core/object/object.h:972)
thread '<unnamed>' panicked at 'as_ref_counted() on freed instance; maybe forgot to increment reference count?', /home/fabian/git/_ext/gdextension/godot-core/src/obj/gd.rs:344:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/fc594f15669680fa70d255faec3ca3fb507c3405/library/std/src/panicking.rs:575:5
   1: core::panicking::panic_fmt
             at /rustc/fc594f15669680fa70d255faec3ca3fb507c3405/library/core/src/panicking.rs:64:14
   2: godot_core::obj::gd::Gd<T>::as_ref_counted
             at /home/fabian/git/_ext/gdextension/godot-core/src/obj/gd.rs:344:9
   3: <godot_core::obj::traits::mem::StaticRefCount as godot_core::obj::traits::mem::Memory>::maybe_dec_ref
             at /home/fabian/git/_ext/gdextension/godot-core/src/obj/traits.rs:248:13
   4: <godot_core::obj::gd::Gd<T> as core::ops::drop::Drop>::drop
             at /home/fabian/git/_ext/gdextension/godot-core/src/obj/gd.rs:539:23
   5: core::ptr::drop_in_place<godot_core::obj::gd::Gd<godot_core::gen::classes::input_event::re_export::InputEvent>>
             at /rustc/fc594f15669680fa70d255faec3ca3fb507c3405/library/core/src/ptr/mod.rs:490:1
   6: <hello_world::experiment::Experiment as godot_core::bind::GodotExt>::input
             at ./rust/src/experiment.rs:38:5
   7: <hello_world::experiment::Experiment as godot_core::obj::traits::cap::ImplementsGodotExt>::__virtual_call::function
             at ./rust/src/experiment.rs:15:1
   8: <unknown>
   9: <unknown>
  10: <unknown>
  11: <unknown>
  12: <unknown>
  13: <unknown>
  14: <unknown>
  15: <unknown>
  16: <unknown>
  17: __libc_start_call_main
             at ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
  18: __libc_start_main_impl
             at ./csu/../csu/libc-start.c:392:3
  19: <unknown>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
fatal runtime error: failed to initiate panic, error 5

This fix is relatively easy by itself; just repeat the work for the methods listed

Still beyond the noob nevel 😉 What actually surprises me that git grep doesn't reveal any other occurrences of e.g. "physics_process", i.e., I haven't really found where the argument passing actually happens.

from gdext.

Bromeon avatar Bromeon commented on May 31, 2024

What actually surprises me that git grep doesn't reveal any other occurrences of e.g. "physics_process", i.e., I haven't really found where the argument passing actually happens.

That's not repeated, but defined here:

https://github.com/godot-rust/gdextension/blob/master/godot-macros/src/godot_api.rs#L262

from gdext.

bluenote10 avatar bluenote10 commented on May 31, 2024

A few more observations on this. When implementing the input method as

    fn input(&mut self, event: Gd<InputEvent>) {
        godot_print!("in input");
        godot_print!("instance_id: {}", event.instance_id());
        godot_print!("is_instance_valid: {}", event.is_instance_valid());
        godot_print!("ref count: {}", event.get_reference_count());
        godot_print!("event: {}", event);
    }

and running with tracing enabled, I'm getting this output:

image

So interestingly the object we are getting from the engine is already invalid. Whether the ref count makes sense in this case is unclear to me.

The crash comes the attempt to print the event. Removing that line causes a panic at the end of the generated macro function instead (the __virtual_call), leading to the backtrace posted above.

I'm wondering if this may require some special handling around gdext_ptrcall! macro here:

https://github.com/godot-rust/gdextension/blob/18f3a7b574b623e8331b2973de31f01c346a7164/godot-core/src/macros.rs#L403-L409

On the other hand, if the object provided by the engine is indeed garbage, we cannot really fix the ref count on Rust side, can we?

from gdext.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.