1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#![feature(doc_cfg)]
/*
 * Copyright (c) godot-rust; Bromeon and contributors.
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

//! The **gdext** library implements Rust bindings for GDExtension, the C API of [Godot 4](https://godotengine.org).
//!
//! This documentation is a work in progress.
//!
//! # Type categories
//!
//! Godot is written in C++, which doesn't have the same strict guarantees about safety and
//! mutability that Rust does. As a result, not everything in this crate will look and feel
//! entirely "rusty". See also [Philosophy](https://godot-rust.github.io/book/contribute/philosophy.html).
//!
//! Traits such as `Clone`, `PartialEq` or `PartialOrd` are designed to mirror Godot semantics,
//! except in cases where Rust is stricter (e.g. float ordering). Cloning a type results in the
//! same observable behavior as assignment or parameter-passing of a GDScript variable.
//!
//! We distinguish four different kinds of types:
//!
//! 1. **Value types**: `i64`, `f64`, and mathematical types like
//!    [`Vector2`][crate::builtin::Vector2] and [`Color`][crate::builtin::Color].
//!
//!    These are the simplest to understand and to work with. They implement `Clone` and often
//!    `Copy` as well. They are implemented with the same memory layout as their counterparts in
//!    Godot itself, and typically have public fields. <br><br>
//!
//! 2. **Copy-on-write types**: [`GString`][crate::builtin::GString],
//!    [`StringName`][crate::builtin::StringName], and `Packed*Array` types.
//!
//!    These mostly act like value types, similar to Rust's own `Vec`. You can `Clone` them to get
//!    a full copy of the entire object, as you would expect.
//!
//!    Under the hood in Godot, these types are implemented with copy-on-write, so that data can be
//!    shared until one of the copies needs to be modified. However, this performance optimization
//!    is entirely hidden from the API and you don't normally need to worry about it. <br><br>
//!
//! 3. **Reference-counted types**: [`Array`][crate::builtin::Array],
//!    [`Dictionary`][crate::builtin::Dictionary], and [`Gd<T>`][crate::obj::Gd] where `T` inherits
//!    from [`RefCounted`][crate::engine::RefCounted].
//!
//!    These types may share their underlying data between multiple instances: changes to one
//!    instance are visible in another. They are conceptually similar to `Rc<RefCell<...>>`.
//!
//!    Since there is no way to prevent or even detect this sharing from Rust, you need to be more
//!    careful when using such types. For example, when iterating over an `Array`, make sure that
//!    it isn't being modified at the same time through another reference.
//!
//!    `Clone::clone()` on these types creates a new reference to the same instance, while
//!    type-specific methods such as [`Array::duplicate_deep()`][crate::builtin::Array::duplicate_deep]
//!    can be used to make actual copies. <br><br>
//!
//! 4. **Manually managed types**: [`Gd<T>`][crate::obj::Gd] where `T` inherits from
//!    [`Object`][crate::engine::Object] but not from [`RefCounted`][crate::engine::RefCounted];
//!    most notably, this includes all `Node` classes.
//!
//!    These also share data, but do not use reference counting to manage their memory. Instead,
//!    you must either hand over ownership to Godot (e.g. by adding a node to the scene tree) or
//!    free them manually using [`Gd::free()`][crate::obj::Gd::free]. <br><br>
//!
//! # Ergonomics and panics
//!
//! gdext is designed with usage ergonomics in mind, making it viable for fast prototyping.
//! Part of this design means that users should not constantly be forced to write code such as
//! `obj.cast::<T>().unwrap()`. Instead, they can just write `obj.cast::<T>()`, which may panic at runtime.
//!
//! This approach has several advantages:
//! * The code is more concise and less cluttered.
//! * Methods like `cast()` provide very sophisticated panic messages when they fail (e.g. involved
//!   classes), immediately giving you the necessary context for debugging. This is certainly
//!   preferable over a generic `unwrap()`, and in most cases also over a `expect("literal")`.
//! * Usually, such methods panicking indicate bugs in the application. For example, you have a static
//!   scene tree, and you _know_ that a node of certain type and name exists. `get_node_as::<T>("name")`
//!   thus _must_ succeed, or your mental concept is wrong. In other words, there is not much you can
//!   do at runtime to recover from such errors anyway; the code needs to be fixed.
//!
//! Now, there are of course cases where you _do_ want to check certain assumptions dynamically.
//! Imagine a scene tree that is constructed at runtime, e.g. in a game editor.
//! This is why the library provides "overloads" for most of these methods that return `Option` or `Result`.
//! Such methods have more verbose names and highlight the attempt, e.g. `try_cast()`.
//!
//! To help you identify panicking methods, we use the symbol "⚠️" at the beginning of the documentation;
//! this should also appear immediately in the auto-completion of your IDE. Note that this warning sign is
//! not used as a general panic indicator, but particularly for methods which have a `Option`/`Result`-based
//! overload. If you want to know whether and how a method can panic, check if its documentation has a
//! _Panics_ section.
//!
//! # Thread safety
//!
//! [Godot's own thread safety
//! rules](https://docs.godotengine.org/en/latest/tutorials/performance/thread_safe_apis.html)
//! apply. Types in this crate implement (or don't implement) `Send` and `Sync` wherever
//! appropriate, but the Rust compiler cannot check what happens to an object through C++ or
//! GDScript.
//!
//! As a rule of thumb, if you must use threading, prefer to use [Rust threads](https://doc.rust-lang.org/std/thread)
//! over Godot threads.
//!
//! The Cargo feature `experimental-threads` provides experimental support for multithreading. The underlying safety
//! rules are still being worked out, as such you may encounter unsoundness and an unstable API.
//!
//! # Cargo features
//!
//! The following features can be enabled for this crate. All off them are off by default.
//!
//! Avoid `default-features = false` unless you know exactly what you are doing; it will disable some required internal features.
//!
//! * **`double-precision`**
//!
//!   Use `f64` instead of `f32` for the floating-point type [`real`][type@builtin::real]. Requires Godot to be compiled with the
//!   scons flag `precision=double`.<br><br>
//!
//! * **`api-4-{minor}`**
//!
//!   Sets the [API level](https://godot-rust.github.io/book/toolchain/compatibility.html) to the specified Godot version, e.g. `api-4-1`.
//!   You can use at most one `api-*` feature. By default, a recent stable Godot release is used.
//!
//!   The API level determines the lowest possible Godot version under which the extension can run. We support latest patch releases of each
//!   Godot minor version, down to `4.0`. From `4.1` onwards, the API is forward-compatible (you can use `api-4-1` under a Godot 4.3 binary).
//!   Level `4.0` is not compatible with newer versions.
//!
//!   If you want to share your extension with others, we recommend setting the level as low as possible. This can however mean you cannot
//!   use newer Godot features. In certain cases, we provide polyfills for newer features on older versions.
//!
//!   The gdext-built extension will check compatibility on startup and refuse to load if it detects a mismatch.<br><br>
//!
//! * **`api-custom`**
//!
//!   Use a custom Godot build instead of the latest official release. This is useful when you like to use a
//!   version compiled yourself, with custom flags.
//!
//!   This feature is mutually exclusive with `api-4-*` features.<br><br>
//!
//! * **`serde`**
//!
//!   Implement the [serde](https://serde.rs/) traits `Serialize` and `Deserialize` traits for certain built-in types.
//!   The serialized representation underlies **no stability guarantees** and may change at any time, even without a SemVer-breaking change.
//!   <br><br>
//!
//! * **`lazy-function-tables`**
//!
//!   Instead of loading all engine function pointers at startup, load them lazily on first use. This reduces startup time and RAM usage, but
//!   incurs additional overhead in each FFI call. Also, you lose the guarantee that once the library has booted, all function pointers are
//!   truly available. Function calls may thus panic only at runtime, possibly in deeply nested code paths.
//!   This feature is not yet thread-safe and can thus not be combined with `experimental-threads`.<br><br>
//!
//! * **`formatted`**
//!
//!   Format the generated binding code with a custom-built formatter, which aims to strike a balance between runtime and human readability.
//!   rustfmt generates nice output, but it is unfortunately excessively slow across hundreds of Godot classes.<br><br>
//!
//! * **`experimental-threads`**
//!
//!   Experimental threading support. This enables `Send`/`Sync` traits for `Gd<T>` and makes the guard types `Gd`/`GdMut` aware of
//!   multi-threaded references. There safety aspects are not ironed out yet; there is a high risk of unsoundness at the moment.
//!   As this evolves, it is very likely that the API becomes more strict.<br><br>
//!
//! * **`experimental-godot-api`**
//!
//!   Access to `godot::engine` APIs that Godot marks "experimental". These are under heavy development and may change at any time.
//!   If you opt in to this feature, expect breaking changes at compile and runtime.<br><br>
//!
//! * **`experimental-wasm`**
//!
//!   Support for WebAssembly exports is still a work-in-progress and is not yet well tested. This feature is in place for users
//!   to explicitly opt-in to any instabilities or rough edges that may result. Due to a limitation in Godot, it might currently not
//!   work Firefox browser.<br><br>
//!
//! # Public API
//!
//! Some symbols in the API are not intended for users, however Rust's visibility feature is not strong enough to express that in all cases
//! (for example, proc-macros and separated crates may need access to internals).
//!
//! The following API symbols are considered private:
//!
//! * Symbols annotated with `#[doc(hidden)]`.
//! * Any of the dependency crates (crate `godot` is the only public interface).
//! * Modules named `private` and all their contents.
//!
//! Being private means a workflow is not supported. As such, there are **no guarantees** regarding API stability, robustness or correctness.
//! Problems arising from using such APIs are not considered bugs, and anything relying on them may stop working without announcement.
//! Please refrain from using undocumented and private features; if you are missing certain functionality, bring it up for discussion instead.
//! This allows us to decide whether it fits the scope of the library and to design proper APIs for it.

// ----------------------------------------------------------------------------------------------------------------------------------------------
// Validations

#[cfg(all(feature = "lazy-function-tables", feature = "experimental-threads"))]
compile_error!("Thread safety for lazy function pointers is not yet implemented.");

#[cfg(all(target_family = "wasm", not(feature = "experimental-wasm")))]
compile_error!("Must opt-in using `experimental-wasm` Cargo feature; keep in mind that this is work in progress");

// See also https://github.com/godotengine/godot/issues/86346.
#[cfg(all(feature = "double-precision", not(feature = "api-custom")))]
compile_error!("The feature `double-precision` currently requires `api-custom` due to incompatibilities in the GDExtension API JSON.");

#[cfg(feature = "custom-godot")]
__deprecated::emit_deprecated_warning!(feature_custom_godot);

const fn _validate_features() {
    let mut count = 0;

    if cfg!(feature = "api-4-0") {
        count += 1;
    }
    if cfg!(feature = "api-4-1") {
        count += 1;
    }
    if cfg!(feature = "api-custom") {
        count += 1;
    }

    assert!(count <= 1, "at most one `api-*` feature can be enabled");
}

const _: () = _validate_features();

// ----------------------------------------------------------------------------------------------------------------------------------------------
// Modules

#[doc(inline)]
pub use godot_core::{builtin, engine, log, obj};

#[doc(hidden)]
pub use godot_core::sys;

/// Entry point and global init/shutdown of the library.
pub mod init {
    pub use godot_core::init::*;

    // Re-exports
    pub use godot_macros::gdextension;
}

/// Register/export Rust symbols to Godot: classes, methods, enums...
pub mod register {
    pub use godot_core::property;
    pub use godot_macros::{godot_api, Export, GodotClass, GodotConvert, Var};
}

/// Testing facilities (unstable).
#[doc(hidden)]
pub mod test {
    pub use godot_macros::{bench, itest};
}

#[doc(hidden)]
pub use godot_core::__deprecated;
#[doc(hidden)]
pub use godot_core::private;

/// Often-imported symbols.
pub mod prelude;