|
| 1 | +/* |
| 2 | + * Copyright (c) godot-rust; Bromeon and contributors. |
| 3 | + * This Source Code Form is subject to the terms of the Mozilla Public |
| 4 | + * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 5 | + * file, You can obtain one at https://mozilla.org/MPL/2.0/. |
| 6 | + */ |
| 7 | + |
| 8 | +//! # Extended documentation |
| 9 | +//! |
| 10 | +//! This highlights a few concepts in the public API of the `godot` crate. They complement information |
| 11 | +//! available on the main crate documentation page and the book. |
| 12 | +//! |
| 13 | +//! ## Type categories |
| 14 | +//! |
| 15 | +//! Godot is written in C++, which doesn't have the same strict guarantees about safety and |
| 16 | +//! mutability that Rust does. As a result, not everything in this crate will look and feel |
| 17 | +//! entirely "rusty". See also [Philosophy](https://godot-rust.github.io/book/contribute/philosophy.html). |
| 18 | +//! |
| 19 | +//! Traits such as `Clone`, `PartialEq` or `PartialOrd` are designed to mirror Godot semantics, |
| 20 | +//! except in cases where Rust is stricter (e.g. float ordering). Cloning a type results in the |
| 21 | +//! same observable behavior as assignment or parameter-passing of a GDScript variable. |
| 22 | +//! |
| 23 | +//! We distinguish four different kinds of types: |
| 24 | +//! |
| 25 | +//! 1. **Value types**: `i64`, `f64`, and mathematical types like |
| 26 | +//! [`Vector2`][crate::builtin::Vector2] and [`Color`][crate::builtin::Color]. |
| 27 | +//! |
| 28 | +//! These are the simplest to understand and to work with. They implement `Clone` and often |
| 29 | +//! `Copy` as well. They are implemented with the same memory layout as their counterparts in |
| 30 | +//! Godot itself, and typically have public fields. <br><br> |
| 31 | +//! |
| 32 | +//! 2. **Copy-on-write types**: [`GString`][crate::builtin::GString], |
| 33 | +//! [`StringName`][crate::builtin::StringName], and `Packed*Array` types. |
| 34 | +//! |
| 35 | +//! These mostly act like value types, similar to Rust's own `Vec`. You can `Clone` them to get |
| 36 | +//! a full copy of the entire object, as you would expect. |
| 37 | +//! |
| 38 | +//! Under the hood in Godot, these types are implemented with copy-on-write, so that data can be |
| 39 | +//! shared until one of the copies needs to be modified. However, this performance optimization |
| 40 | +//! is entirely hidden from the API and you don't normally need to worry about it. <br><br> |
| 41 | +//! |
| 42 | +//! 3. **Reference-counted types**: [`Array`][crate::builtin::Array], |
| 43 | +//! [`Dictionary`][crate::builtin::Dictionary], and [`Gd<T>`][crate::obj::Gd] where `T` inherits |
| 44 | +//! from [`RefCounted`][crate::classes::RefCounted]. |
| 45 | +//! |
| 46 | +//! These types may share their underlying data between multiple instances: changes to one |
| 47 | +//! instance are visible in another. They are conceptually similar to `Rc<RefCell<...>>`. |
| 48 | +//! |
| 49 | +//! Since there is no way to prevent or even detect this sharing from Rust, you need to be more |
| 50 | +//! careful when using such types. For example, when iterating over an `Array`, make sure that |
| 51 | +//! it isn't being modified at the same time through another reference. |
| 52 | +//! |
| 53 | +//! `Clone::clone()` on these types creates a new reference to the same instance, while |
| 54 | +//! type-specific methods such as [`Array::duplicate_deep()`][crate::builtin::Array::duplicate_deep] |
| 55 | +//! can be used to make actual copies. <br><br> |
| 56 | +//! |
| 57 | +//! 4. **Manually managed types**: [`Gd<T>`][crate::obj::Gd] where `T` inherits from |
| 58 | +//! [`Object`][crate::classes::Object] but not from [`RefCounted`][crate::classes::RefCounted]; |
| 59 | +//! most notably, this includes all `Node` classes. |
| 60 | +//! |
| 61 | +//! These also share data, but do not use reference counting to manage their memory. Instead, |
| 62 | +//! you must either hand over ownership to Godot (e.g. by adding a node to the scene tree) or |
| 63 | +//! free them manually using [`Gd::free()`][crate::obj::Gd::free]. <br><br> |
| 64 | +//! |
| 65 | +//! |
| 66 | +//! ## Ergonomics and panics |
| 67 | +//! |
| 68 | +//! gdext is designed with usage ergonomics in mind, making it viable for fast prototyping. |
| 69 | +//! Part of this design means that users should not constantly be forced to write code such as |
| 70 | +//! `obj.cast::<T>().unwrap()`. Instead, they can just write `obj.cast::<T>()`, which may panic at runtime. |
| 71 | +//! |
| 72 | +//! This approach has several advantages: |
| 73 | +//! * The code is more concise and less cluttered. |
| 74 | +//! * Methods like `cast()` provide very sophisticated panic messages when they fail (e.g. involved |
| 75 | +//! classes), immediately giving you the necessary context for debugging. This is certainly |
| 76 | +//! preferable over a generic `unwrap()`, and in most cases also over a `expect("literal")`. |
| 77 | +//! * Usually, such methods panicking indicate bugs in the application. For example, you have a static |
| 78 | +//! scene tree, and you _know_ that a node of certain type and name exists. `get_node_as::<T>("name")` |
| 79 | +//! thus _must_ succeed, or your mental concept is wrong. In other words, there is not much you can |
| 80 | +//! do at runtime to recover from such errors anyway; the code needs to be fixed. |
| 81 | +//! |
| 82 | +//! Now, there are of course cases where you _do_ want to check certain assumptions dynamically. |
| 83 | +//! Imagine a scene tree that is constructed at runtime, e.g. in a game editor. |
| 84 | +//! This is why the library provides "overloads" for most of these methods that return `Option` or `Result`. |
| 85 | +//! Such methods have more verbose names and highlight the attempt, e.g. `try_cast()`. |
| 86 | +//! |
| 87 | +//! To help you identify panicking methods, we use the symbol "⚠️" at the beginning of the documentation; |
| 88 | +//! this should also appear immediately in the auto-completion of your IDE. Note that this warning sign is |
| 89 | +//! not used as a general panic indicator, but particularly for methods which have a `Option`/`Result`-based |
| 90 | +//! overload. If you want to know whether and how a method can panic, check if its documentation has a |
| 91 | +//! _Panics_ section. |
| 92 | +//! <br><br> |
| 93 | +//! |
| 94 | +//! ## Thread safety |
| 95 | +//! |
| 96 | +//! [Godot's own thread safety |
| 97 | +//! rules](https://docs.godotengine.org/en/latest/tutorials/performance/thread_safe_apis.html) |
| 98 | +//! apply. Types in this crate implement (or don't implement) `Send` and `Sync` wherever |
| 99 | +//! appropriate, but the Rust compiler cannot check what happens to an object through C++ or |
| 100 | +//! GDScript. |
| 101 | +//! |
| 102 | +//! As a rule of thumb, if you must use threading, prefer to use [Rust threads](https://doc.rust-lang.org/std/thread) |
| 103 | +//! over Godot threads. |
| 104 | +//! |
| 105 | +//! The Cargo feature `experimental-threads` provides experimental support for multithreading. The underlying safety |
| 106 | +//! rules are still being worked out, as such you may encounter unsoundness and an unstable API. |
| 107 | +//! |
0 commit comments