From a62d7a4bfbbc2733058f2579a2f4e2fe13dc1a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf-Andr=C3=A9=20Walla?= Date: Sat, 14 Sep 2024 09:16:56 +0200 Subject: [PATCH] Update Rust API and add an example to README --- README.md | 38 ++++++++++++++++++++++++++++++++-- program/cpp/api/variant.hpp | 2 ++ program/rust/src/godot/node.rs | 12 +++++++++++ src/sandbox_functions.cpp | 4 ++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5cf63211..a4d954ea 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ This extension exists to allow Godot creators to implement safe modding support, - Maximum scalability - Call functions and attach signals like GDScript +## Examples + ```C++ static void add_coin(const Node& player) { static int coins = 0; @@ -65,16 +67,48 @@ static void add_coin(const Node& player) { extern "C" Variant _on_body_entered(Node2D node) { if (node.get_name() != "Player") - return {}; + return Nil; get_node().queue_free(); // Remove the current coin! add_coin(node); - return {}; + return Nil; } ``` Script of a simple Coin pickup, with a counter that updates a label in the tree of the player. This script can be attached to the Coin just like GDScript. +```Rust +#[no_mangle] +pub fn _physics_process(delta: f64) -> Variant { + if Engine::is_editor_hint() { + return Variant::new_nil(); + } + + let slime = get_node(); + let sprite = get_node_from_path("AnimatedSprite2D"); + + let flip_h = sprite.call("is_flipped_h", &[]); + let direction: f32 = (flip_h.to_bool() as i32 as f32 - 0.5) * -2.0; + + let mut pos = slime.call("get_position", &[]).to_vec2(); + pos.x += direction * SPEED * delta as f32; + + slime.call("set_position", &[Variant::new_vec2(pos)]); + + let ray_right = get_node_from_path("raycast_right"); + let ray_left = get_node_from_path("raycast_left"); + if direction > 0.0 && ray_right.call("is_colliding", &[]).to_bool() { + sprite.call("set_flip_h", &[Variant::new_bool(true)]); + } + else if direction < 0.0 && ray_left.call("is_colliding", &[]).to_bool() { + sprite.call("set_flip_h", &[Variant::new_bool(false)]); + } + + Variant::new_nil() +} +``` +The Rust API is still under development, but simple scripts are possible. + You may also have a look at our [demo repository](https://github.com/libriscv/godot-sandbox-demo) for the Godot Sandbox. It's a tiny platformer that uses C++ and Rust. ## Contributing diff --git a/program/cpp/api/variant.hpp b/program/cpp/api/variant.hpp index 09fd3524..bcbd5b9f 100644 --- a/program/cpp/api/variant.hpp +++ b/program/cpp/api/variant.hpp @@ -309,6 +309,8 @@ inline Variant::Variant(T value) static_assert(!std::is_same_v, "Unsupported type"); } +#define Nil Variant() + inline Variant Variant::string_name(const std::string &name) { Variant v; v.internal_create_string(STRING_NAME, name); diff --git a/program/rust/src/godot/node.rs b/program/rust/src/godot/node.rs index f2abd609..a52b4f68 100644 --- a/program/rust/src/godot/node.rs +++ b/program/rust/src/godot/node.rs @@ -78,3 +78,15 @@ fn godot_method_call(address: usize, method: *const c_char, msize: usize, args: return result; } } + +/* Get the current node (owner of the Sandbox) */ +pub fn get_node() -> Node +{ + Node::new_from_path(".") +} + +/* Get a node relative to the current node (owner of the Sandbox) */ +pub fn get_node_from_path(path: &str) -> Node +{ + Node::new_from_path(path) +} diff --git a/src/sandbox_functions.cpp b/src/sandbox_functions.cpp index cf81ac1f..a70b9e5b 100644 --- a/src/sandbox_functions.cpp +++ b/src/sandbox_functions.cpp @@ -1159,6 +1159,10 @@ static const std::unordered_set exclude_functions{ "floor", "floorf32x", "floorf64", + + "OUTLINED_FUNCTION_0", + "OUTLINED_FUNCTION_1", + "OUTLINED_FUNCTION_2", }; PackedStringArray Sandbox::get_functions() const {