Skip to content

Commit 6eae3f5

Browse files
bors[bot]Bromeon
andauthored
Merge #941 #942
941: Simplify module setup around gdnative::globalscope + docs r=Bromeon a=Bromeon Changes: * Add load() to prelude * Rename internal module gdscript -> globalscope * Module documentation for globalscope now visible again (moved from gdnative_core::globalscope) * Smaller doc tweaks 942: Compatibility warning between godot-rust and Godot r=Bromeon a=Bromeon Adds a warning on startup, if godot-rust is used with a Godot engine version that ships a partially incompatible GDNative API version. Currently only a warning and not a hard error; we need to see how it goes. Co-authored-by: Jan Haller <[email protected]>
3 parents 6f4279d + 648d585 + 7999e6a commit 6eae3f5

File tree

11 files changed

+111
-82
lines changed

11 files changed

+111
-82
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88

9+
## [0.10.2] - unreleased
10+
11+
Last maintenance release for Godot 3.4.
12+
13+
# Added
14+
15+
- `globalscope::load` method ([#940](https://github.com/godot-rust/godot-rust/pull/940), [#941](https://github.com/godot-rust/godot-rust/pull/941))
16+
- `Color` constructors from HTML string and integers ([#939](https://github.com/godot-rust/godot-rust/pull/939))
17+
- Version check to warn if Godot is not 3.4 ([#942](https://github.com/godot-rust/godot-rust/pull/942))
18+
919
## [0.10.1] - 2022-09-03
1020

1121
This is a backwards-compatible release; thus no removals or breaking changes.

examples/native-plugin/src/lib.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Rust GDNative implementation of this Godot tutorial:
22
// https://docs.godotengine.org/en/stable/tutorials/plugins/editor/making_plugins.html#a-custom-node
33

4-
use gdnative::api::{EditorPlugin, Resource, Script, Texture};
4+
use gdnative::api::{EditorPlugin, Script, Texture};
55
use gdnative::prelude::*;
66

77
#[derive(NativeClass)]
@@ -18,10 +18,8 @@ impl CustomNode {
1818
fn _enter_tree(&self, #[base] owner: TRef<EditorPlugin>) {
1919
// Initialization of the plugin goes here.
2020
// Add the new type with a name, a parent type, a script and an icon.
21-
let script = unsafe { load::<Script>("res://my_button.gdns", "Script").unwrap() };
22-
let texture = unsafe {
23-
load::<Texture>("res://making_plugins-custom_node_icon.png", "Texture").unwrap()
24-
};
21+
let script = load::<Script>("res://my_button.gdns").unwrap();
22+
let texture = load::<Texture>("res://making_plugins-custom_node_icon.png").unwrap();
2523
owner.add_custom_type("MyButton", "Button", script, texture);
2624
}
2725

@@ -56,15 +54,6 @@ impl MyButton {
5654
}
5755
}
5856

59-
unsafe fn load<T>(path: &str, hint: &str) -> Option<Ref<T, Shared>>
60-
where
61-
T: GodotObject<Memory = RefCounted> + SubClass<Resource>,
62-
{
63-
let resource = ResourceLoader::godot_singleton().load(path, hint, false)?;
64-
let resource = resource.assume_safe().claim();
65-
resource.cast::<T>()
66-
}
67-
6857
fn init(handle: InitHandle) {
6958
handle.add_tool_class::<CustomNode>();
7059
handle.add_tool_class::<MyButton>();

examples/scene-create/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,9 @@ fn init(handle: InitHandle) {
105105
}
106106

107107
pub fn load_scene(path: &str) -> Option<Ref<PackedScene, ThreadLocal>> {
108-
let scene = ResourceLoader::godot_singleton().load(path, "PackedScene", false)?;
109-
108+
let scene = load::<PackedScene>(path)?;
110109
let scene = unsafe { scene.assume_thread_local() };
111-
112-
scene.cast::<PackedScene>()
110+
Some(scene)
113111
}
114112

115113
/// Root here is needs to be the same type (or a parent type) of the node that you put in the child

gdnative-bindings/src/utils.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use gdnative_core::object::{SubClass, TInstance, TRef};
77
use super::generated::{Engine, Node, SceneTree};
88

99
/// Convenience method to obtain a reference to an "auto-load" node, that is a child of the root
10-
/// node. Returns `None` if the node does not exist or is not of the correct type.
10+
/// node.
11+
///
12+
/// Returns `None` if the node does not exist or is not of the correct type.
1113
///
1214
/// # Safety
1315
///

gdnative-core/src/core_types/color.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use crate::sys;
33
use std::mem::transmute;
44

55
use crate::core_types::GodotString;
6-
/// RGBA color with 32 bits floating point components.
6+
7+
/// RGBA color with 32-bit floating point components.
78
#[repr(C)]
89
#[derive(Copy, Clone, Debug, PartialEq)]
910
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -43,20 +44,22 @@ impl Color {
4344

4445
/// Parses from a HTML color code, or `None` on parse error.
4546
///
47+
/// Note that unlike most other constructors, this has `ARGB` and not `RGBA` format.
48+
/// In particular, `from_html("AB123456")` would correspond to `from_rgba_u32(0x123456AB)`.
49+
///
4650
/// ```
4751
/// use gdnative::prelude::Color;
4852
///
49-
/// // Each of the following creates the same color RGBA(178, 217, 10, 255).
5053
/// let c1 = Color::from_html("#9eb2d90a"); // ARGB format with "#".
5154
/// let c2 = Color::from_html("9eb2d90a"); // ARGB format.
5255
/// let c3 = Color::from_html("#b2d90a"); // RGB format with "#".
5356
/// let c4 = Color::from_html("b2d90a"); // RGB format.
5457
///
55-
/// let expected = Color::from_rgba_u8(178, 217, 10, 158);
58+
/// let expected = Color::from_rgba_u8(0xb2, 0xd9, 0x0a, 0x9e);
5659
/// assert_eq!(c1, Some(expected));
5760
/// assert_eq!(c2, Some(expected));
5861
///
59-
/// let expected = Color::from_rgba_u8(178, 217, 10, 255);
62+
/// let expected = Color::from_rgba_u8(0xb2, 0xd9, 0x0a, 0xff);
6063
/// assert_eq!(c3, Some(expected));
6164
/// assert_eq!(c4, Some(expected));
6265
/// ```
@@ -112,7 +115,8 @@ impl Color {
112115

113116
/// Constructs a color from four integer channels, each in range 0-255.
114117
///
115-
/// This corresponds to the [GDScript method `Color8`](https://docs.godotengine.org/en/stable/classes/class_%40gdscript.html#class-gdscript-method-color8)
118+
/// This corresponds to the
119+
/// [GDScript method `Color8`](https://docs.godotengine.org/en/stable/classes/class_%40gdscript.html#class-gdscript-method-color8).
116120
#[inline]
117121
pub fn from_rgba_u8(r: u8, g: u8, b: u8, a: u8) -> Self {
118122
Self::from_rgba(

gdnative-core/src/globalscope.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,3 @@
1-
//! Port of selected GDScript built-in functions.
2-
//!
3-
//! This module contains _some_ of the functions available in the [@GDScript] documentation.
4-
//!
5-
//! Reasons why a GDScript function may _not_ be ported to Rust include:
6-
//! * they are in the Rust standard library (`abs`, `sin`, `floor`, `assert`, ...)
7-
//! * they are already part of a godot-rust API
8-
//! * `print` -> [`godot_print!`][crate::log::godot_print!]
9-
//! * `instance_from_id` -> [`GodotObject::from_instance_id()`][crate::object::GodotObject::from_instance_id]
10-
//! * ...
11-
//! * they have a private implementation, i.e. a Rust port would have different semantics
12-
//! * `randi`, `randf` etc. -- users should use `rand` crate
13-
//! * `str2var`, `bytes2var`, `hash` etc -- to be verified
14-
//!
15-
//! This above list is not a definitive inclusion/exclusion criterion, just a rough guideline.
16-
//!
17-
//! Other noteworthy special cases:
18-
//! * GDScript `fmod` corresponds to Rust's `%` operator on `f32` (also known as the `Rem` trait).
19-
//!
20-
//! [@GDScript]: https://docs.godotengine.org/en/stable/classes/[email protected]
21-
221
use std::f32::consts::TAU;
232
use std::ops::Rem;
243
use std::ops::{Range, RangeInclusive};

gdnative-core/src/init/macros.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,24 @@ macro_rules! godot_nativescript_init {
3535
return;
3636
}
3737

38+
// Compatibility warning if using in-house Godot version (not applicable for custom ones)
39+
#[cfg(not(feature = "custom-godot"))]
40+
{
41+
let engine = gdnative::api::Engine::godot_singleton();
42+
let info = engine.get_version_info();
43+
44+
if info.get("major").expect("major version") != Variant::new(3)
45+
|| info.get("minor").expect("minor version") != Variant::new(4) {
46+
let string = info.get("string").expect("version str").to::<String>().expect("version str type");
47+
gdnative::log::godot_warn!(
48+
"This godot-rust version is only compatible with Godot 3.4.x; detected version {}.\n\
49+
GDNative mismatches may lead to subtle bugs, undefined behavior or crashes at runtime.\n\
50+
Apply the 'custom-godot' feature if you want to use current godot-rust with another Godot engine version.",
51+
string
52+
);
53+
}
54+
}
55+
3856
let __result = ::std::panic::catch_unwind(|| {
3957
$callback($crate::init::InitHandle::new(handle));
4058
});

gdnative/src/gdscript.rs

Lines changed: 0 additions & 31 deletions
This file was deleted.

gdnative/src/globalscope.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//! Port of selected GDScript built-in functions.
2+
//!
3+
//! This module contains _some_ of the functions available in the [@GDScript] documentation.
4+
//!
5+
//! Reasons why a GDScript function may _not_ be ported to Rust include:
6+
//! * they are in the Rust standard library (`abs`, `sin`, `floor`, `assert`, ...)
7+
//! * they are already part of a godot-rust API
8+
//! * `print` -> [`godot_print!`][crate::log::godot_print!]
9+
//! * `instance_from_id` -> [`GodotObject::from_instance_id()`][crate::object::GodotObject::from_instance_id]
10+
//! * ...
11+
//! * they have a private implementation, i.e. a Rust port would have different semantics
12+
//! * `randi`, `randf` etc. -- users should use `rand` crate
13+
//! * `str2var`, `bytes2var`, `hash` etc -- to be verified
14+
//!
15+
//! This above list is not a definitive inclusion/exclusion criterion, just a rough guideline.
16+
//!
17+
//! Other noteworthy special cases:
18+
//! * GDScript `fmod` corresponds to Rust's `%` operator on `f32` (also known as the `Rem` trait).
19+
//!
20+
//! [@GDScript]: https://docs.godotengine.org/en/stable/classes/[email protected]
21+
22+
use crate::api::{Resource, ResourceLoader};
23+
use crate::object::{memory::RefCounted, GodotObject, Ref, SubClass};
24+
25+
#[doc(inline)]
26+
pub use gdnative_core::globalscope::*;
27+
28+
/// Loads a resource from the filesystem located at `path`.
29+
///
30+
/// The resource is loaded on the method call (unless it's referenced already elsewhere, e.g. in another script or in the scene),
31+
/// which might cause slight delay, especially when loading scenes.
32+
///
33+
/// If the resource cannot be loaded, or is not of type `T` or inherited, this method returns `None`.
34+
///
35+
/// This method is a simplified version of [`ResourceLoader::load()`][crate::api::ResourceLoader::load],
36+
/// which can be used for more advanced scenarios.
37+
///
38+
/// # Note:
39+
/// Resource paths can be obtained by right-clicking on a resource in the Godot editor (_FileSystem_ dock) and choosing "Copy Path",
40+
/// or by dragging the file from the _FileSystem_ dock into the script.
41+
///
42+
/// The path must be absolute (typically starting with `res://`), a local path will fail.
43+
///
44+
/// # Example:
45+
/// Loads a scene called `Main` located in the `path/to` subdirectory of the Godot project and caches it in a variable.
46+
/// The resource is directly stored with type `PackedScene`.
47+
///
48+
/// ```no_run
49+
/// use gdnative::prelude::*;
50+
///
51+
/// let scene = load::<PackedScene>("res://path/to/Main.tscn").unwrap();
52+
/// ```
53+
// TODO generalize parameter to `impl Into<NodePath>` once MSRV >= 1.63
54+
#[inline]
55+
pub fn load<T>(path: &str) -> Option<Ref<T>>
56+
where
57+
T: SubClass<Resource> + GodotObject<Memory = RefCounted>,
58+
{
59+
let type_hint = T::class_name();
60+
ResourceLoader::godot_singleton()
61+
.load(path, type_hint, false)
62+
.and_then(|res| res.cast::<T>())
63+
}

gdnative/src/lib.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,7 @@
8383
#[doc(inline)]
8484
pub use gdnative_core::{core_types, export, init, log, object, profiler};
8585

86-
mod gdscript; // new methods from `@GDscript`, so far only `load`
87-
pub mod globalscope {
88-
pub use crate::gdscript::*;
89-
#[doc(inline)]
90-
pub use gdnative_core::globalscope::*;
91-
}
86+
pub mod globalscope;
9287

9388
// Implementation details (e.g. used by macros).
9489
// However, do not re-export macros (on crate level), thus no wildcard

0 commit comments

Comments
 (0)