-
-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Array Functions(new and append) #55
Comments
It's mostly equivalent to this C code: RawArray raw; // the internal representation of an array
method_table->array_construct_default(&raw, nullptr); But Rust forces you to initialize variables and clearly state which ones are potentially uninitialized, so it's more ceremony. Also, typically we encapsulate this operation with
There is
Those classes and methods are also available in the |
I believe the implementation with #[test]
pub fn test_create_from_sys_init() {
use godot::prelude::Array;
use godot::sys;
use godot::sys::GodotFfi; // for from_sys_init
fn new_array() -> Array {
unsafe {
Array::from_sys_init(|self_ptr|{
let ctor = sys::method_table().array_construct_default;
ctor(self_ptr, std::ptr::null_mut());
})
}
}
let a = new_array();
assert!(a.get(0).is_none());
} (this compiles, but fails as a unit test, as I get "unchecked access to
|
Okay, the following code works to implement // i put this in the ready() function of my GodotExt impl:
use godot::{sys, builtin::StringName};
use sys::GodotFfi; // for Array.sys()
let a = Array::new();
assert!(a.get(0).is_none(), "the array should be empty!"); // (console complains out of bounds)
let vgpb = sys::interface_fn!(variant_get_ptr_builtin_method);
let name = StringName::from("append");
let hash = 3316032543; // hash for 'append' taken from the .json file
let meth = unsafe { vgpb(sys::VariantType::Array as i32, name.string_sys(), hash).unwrap() };
godot_print!("append method seems to exist! let's call it.");
for i in 0..10 {
let args = [ Variant::from(i) ];
let args_ptr : sys::GDExtensionConstTypePtr = args.as_ptr().cast();
let ret_null = std::ptr::null_mut();
unsafe { meth(a.sys(), &args_ptr, ret_null, args.len() as i32 ); }}
godot_print!("value after append(s): {}", a.to_variant()); // "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"" !! :) the only required changes to gdextension are to add the // godot-core/src/builtin/arrays.rs
impl Array {
pub fn new() -> Self {
Self::default()
}
pub fn default() -> Self {
unsafe {
Self::from_sys_init(|self_ptr| {
let ctor = sys::builtin_fn!(array_construct_default);
ctor(self_ptr, std::ptr::null_mut());
})
}
}
} The implementation of impl_variant_traits!(Array, array_to_variant, array_from_variant, Array); |
Interesting...if this does what I think it does(essentially looks up a method inside of a variant?), then this could be very useful for all kinds of methods. Thanks for sharing @tangentstorm! |
@thebigG thanks for posting your work-in-progress. I referred to it repeatedly while working this out yesterday! @Bromeon , @thebigG also seem to be correct about the ClassDB not containing the methods: let cdb_gmb = sys::interface_fn!(classdb_get_method_bind);
let ptrcall = sys::interface_fn!(object_method_bind_ptrcall);
let meth = unsafe { cdb_gmb(StringName::from("PackedInt32Array").string_sys(),
StringName::from("append").string_sys(),
694024632) }; // hash seems to be for each class/method pair, not just method name
if meth == std::ptr::null_mut() { godot_print!("PackedInt32Array::append not found in ClassDB!") } It says it's not found... This might kind of make sense because the As a sanity check, I went looking for let meth = unsafe { cdb_gmb(StringName::from("ColorRect").string_sys(),
StringName::from("set_color").string_sys(),
2920490490) }; // hash seems to be for each class/method pair, not just method name
if meth == std::ptr::null_mut() { godot_print!("method not found in ClassDB!") }
else { godot_print!("method found!") } |
Duplicate of #33? |
Indeed, arrays are now supported! @thebigG @tangentstorm regarding confusion, |
Hi there,
In the spirit of starting a discussion first rather than just implementing(potentially the wrong thing), I'm sharing my progress in this issue.
I started using the port and realized that Arrays are not complete. So I took a stab at implementing a ::new function and this is what I got so far:
This seems to work from GdScript.
From Rust code I'm sticking to the following pattern(not sure if this is the best way of doing this):
Ok, so we can create an empty array. So the next question is how do we append items to it? I thought that I might be able to do something like the following:
But it looks like
ClassDB
does not have "non-Node" classes such as Arrays? So I can't really just reach out to the engine and have it "append" something for me.Or am I wrong about that?
Is there a way to call the append/push_back functions from Rust at the moment? It seems like Rust GDNative did something similar with the
godot_pool_vector2_array_append_array family of functions
? But there might be something else going in the case of GDNative that I don't know since these are new APIs to me.Hope this is clear enough.
Thanks in advance.
The text was updated successfully, but these errors were encountered: