From c9834459c731c6ef1332848fe79c7f22792d67d8 Mon Sep 17 00:00:00 2001 From: Jan Haller Date: Wed, 11 Oct 2023 22:27:11 +0200 Subject: [PATCH] Unordered lists use `-` bullets --- .github/other/.markdownlint.jsonc | 2 +- src/contribute/conventions.md | 66 +++++++++++++++---------------- src/index.md | 12 +++--- src/intro/index.md | 4 +- src/intro/setup.md | 4 +- src/toolchain/compatibility.md | 30 +++++++------- 6 files changed, 59 insertions(+), 59 deletions(-) diff --git a/.github/other/.markdownlint.jsonc b/.github/other/.markdownlint.jsonc index d178ac0..2ed5108 100644 --- a/.github/other/.markdownlint.jsonc +++ b/.github/other/.markdownlint.jsonc @@ -7,7 +7,7 @@ }, // Unordered list bullets: - + *. "ul-style": { - "style": "consistent" + "style": "dash" }, "ul-indent": { "indent": 2 diff --git a/src/contribute/conventions.md b/src/contribute/conventions.md index 0ae54c1..052c863 100644 --- a/src/contribute/conventions.md +++ b/src/contribute/conventions.md @@ -16,12 +16,12 @@ pull request reviews. In particular, we use the following tools: -* [**rustfmt**] for code formatting ([config options][rustfmt-config]). -* [**clippy**] for lints and style warnings ([list of lints][clippy-lints]). -* Clang's [**AddressSanitizer**] and [**LeakSanitizer**] for memory safety. -* Various specialized tools: - * [**skywalking-eyes**] to enforce license headers. - * [**cargo-deny**] and [**cargo-machete**] for dependency verification. +- [**rustfmt**] for code formatting ([config options][rustfmt-config]). +- [**clippy**] for lints and style warnings ([list of lints][clippy-lints]). +- Clang's [**AddressSanitizer**] and [**LeakSanitizer**] for memory safety. +- Various specialized tools: + - [**skywalking-eyes**] to enforce license headers. + - [**cargo-deny**] and [**cargo-machete**] for dependency verification. In addition, we have unit tests (`#[test]`), doctests and Godot integration tests (`#[itest]`). See [Dev tools] for more information. @@ -48,27 +48,27 @@ We envision the following core principles as a guideline for API design: 1. **Simplicity** Prefer self-explanatory, straightforward interfaces. - * Avoid abstractions that don't add value to the user. + - Avoid abstractions that don't add value to the user. Do not over-engineer prematurely just because it's possible; follow [YAGNI][wiki-yagni]. Avoid [premature optimization][wiki-premature-opt]. - * Examples to avoid: traits that are not used polymorphically, type-state pattern, many generic parameters, + - Examples to avoid: traits that are not used polymorphically, type-state pattern, many generic parameters, layers of wrapper types/functions that simply delegate logic. - * Sometimes, runtime errors are better than compile-time errors. Most users are building a game, where fast iteration is key. + - Sometimes, runtime errors are better than compile-time errors. Most users are building a game, where fast iteration is key. Use `Option`/`Result` when errors are recoverable, and panics when the user must fix their code. See also [Ergonomics and panics][lib-ergonomics-panics]. 2. **Maintainability** Every line of code added **must be maintained, potentially indefinitely**. - * Consider that it may not be you working with it in the future, but another contributor or maintainer, maybe a year from now. - * Try to see the bigger picture -- how important is a specific in the overall library? How much detail is necessary? + - Consider that it may not be you working with it in the future, but another contributor or maintainer, maybe a year from now. + - Try to see the bigger picture -- how important is a specific in the overall library? How much detail is necessary? Balance the amount of code with its real-world impact for users. - * Document non-trivial thought processes and design choices as inline `//` comments. - * Document behavior, invariants and limitations in `///` doc comments. + - Document non-trivial thought processes and design choices as inline `//` comments. + - Document behavior, invariants and limitations in `///` doc comments. 3. **Consistency** As a user, having a uniform experience when using different parts of the library is important. This reduces the cognitive load of learning and using the library, requires less doc lookup and makes users more efficient. - * Look at existing code and try to understand its patterns and conventions. - * Before doing larger refactorings or changes of existing systems, try to understand the underlying design choices. + - Look at existing code and try to understand its patterns and conventions. + - Before doing larger refactorings or changes of existing systems, try to understand the underlying design choices. See these as guidelines, not hard rules. If you are unsure, please don't hesitate to ask questions and discuss different ideas. @@ -97,16 +97,16 @@ We use separators starting with `// ---` to visually divide sections of related ### Code organization 1. Anything that is not intended to be accessible by the user, but must be `pub` for technical reasons, should be marked as `#[doc(hidden)]`. - * This does [**not** constitute part of the public API][lib-public-api]. + - This does [**not** constitute part of the public API][lib-public-api]. 2. We do not use the `prelude` inside the project, except in examples and doctests. 3. Inside `impl` blocks, we _roughly_ try to follow the order: - * Type aliases in traits (`type`) - * Constants (`const`) - * Constructors and associated functions - * Public methods - * Private methods (`pub(crate)`, private, `#[doc(hidden)]`) + - Type aliases in traits (`type`) + - Constants (`const`) + - Constructors and associated functions + - Public methods + - Private methods (`pub(crate)`, private, `#[doc(hidden)]`) 4. Inside files, there is no strict order yet, except `use` and `mod` at the top. Prefer to declare public-facing symbols before private ones. @@ -127,9 +127,9 @@ We use separators starting with `// ---` to visually divide sections of related 1. Avoid tuple-enums `enum E { Var(u32, u32) }` and tuple-structs `struct S(u32, u32)` with more than 1 field. Use named fields instead. 2. Derive order is `#[derive(GdextTrait, ExternTrait, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]`. - * `GdextTrait` is a custom derive defined by gdext itself (in any of the crates). - * `ExternTrait` is a custom derive by a third-party crate, e.g. `nanoserde`. - * The standard traits follow order _construction, comparison, hashing, debug display_. + - `GdextTrait` is a custom derive defined by gdext itself (in any of the crates). + - `ExternTrait` is a custom derive by a third-party crate, e.g. `nanoserde`. + - The standard traits follow order _construction, comparison, hashing, debug display_. More expressive ones (`Copy`, `Eq`) precede their implied counterparts (`Clone`, `PartialEq`). @@ -151,18 +151,18 @@ We use separators starting with `// ---` to visually divide sections of related Concerns both `#[proc_macro_attribute]` and the attributes attached to a `#[proc_macro_derive]`. 1. Attributes always have the same syntax: `#[attr(key = "value", key2, key_three = 20)]` - * `attr` is the outer name grouping different key-value pairs in parentheses. + - `attr` is the outer name grouping different key-value pairs in parentheses. A symbol can have multiple attributes, but they cannot share the same name. - * `key = value` is a key-value pair. just `key` is a key-value pair without a value. - * Keys are always `snake_case` identifiers. - * Values are typically strings or numbers, but can be more complex expressions. - * Multiple key-value pairs are separated by commas. Trailing commas are allowed. + - `key = value` is a key-value pair. just `key` is a key-value pair without a value. + - Keys are always `snake_case` identifiers. + - Values are typically strings or numbers, but can be more complex expressions. + - Multiple key-value pairs are separated by commas. Trailing commas are allowed. 2. In particular, avoid these forms: - * `#[attr = "value"]` (top-level assignment) - * `#[attr("value")]` (no key -- note that `#[attr(key)]` is allowed) - * `#[attr(key(value))]` - * `#[attr(key = value, key = value)]` (repeated keys) + - `#[attr = "value"]` (top-level assignment) + - `#[attr("value")]` (no key -- note that `#[attr(key)]` is allowed) + - `#[attr(key(value))]` + - `#[attr(key = value, key = value)]` (repeated keys) The reason for this choice is that each attribute maps nicely to a map, where values can have different types. This allows for a recognizable and consistent syntax across all proc-macro APIs. Implementation-wise, this pattern is diff --git a/src/index.md b/src/index.md index fd39fe8..1237816 100644 --- a/src/index.md +++ b/src/index.md @@ -18,12 +18,12 @@ To read the book about gdnative (Godot 3 binding), follow [this link](../gdnativ To avoid confusion, here is an explanation of names and technologies you may encounter over time. -* **godot-rust**: The entire project, encompassing Rust bindings for Godot 3 and 4, as well as related efforts (book, community, etc.). -* [**GDExtension**]: C API provided by Godot 4. -* [**GDNative**]: C API provided by Godot 3. -* **gdext** (lowercase): the Rust binding for GDExtension (Godot 4) -- what this book focuses on. -* **gdnative** (lowercase): the Rust binding for GDNative (Godot 3). -* **Extension**: An extension is a C library developed using gdext. It can be loaded by Godot 4. +- **godot-rust**: The entire project, encompassing Rust bindings for Godot 3 and 4, as well as related efforts (book, community, etc.). +- [**GDExtension**]: C API provided by Godot 4. +- [**GDNative**]: C API provided by Godot 3. +- **gdext** (lowercase): the Rust binding for GDExtension (Godot 4) -- what this book focuses on. +- **gdnative** (lowercase): the Rust binding for GDNative (Godot 3). +- **Extension**: An extension is a C library developed using gdext. It can be loaded by Godot 4. ## Currently supported features diff --git a/src/intro/index.md b/src/intro/index.md index 6da5a26..fcebec3 100644 --- a/src/intro/index.md +++ b/src/intro/index.md @@ -21,8 +21,8 @@ However, we won't reiterate basic Godot concepts -- so if you choose that approa In addition to this book, you can use the following resources to learn more about the project: -* The [official API documentation][api-docs]. -* A small example game [Dodge the Creeps][dodge-the-creeps]. +- The [official API documentation][api-docs]. +- A small example game [Dodge the Creeps][dodge-the-creeps]. [api-docs]: https://godot-rust.github.io/docs/gdext diff --git a/src/intro/setup.md b/src/intro/setup.md index 36da822..15444a3 100644 --- a/src/intro/setup.md +++ b/src/intro/setup.md @@ -14,8 +14,8 @@ To use gdext, we need a few technologies. While you can write Rust code without having the Godot engine, we highly recommend to install Godot for quick feedback loops. For the rest of the tutorial, we assume that you have Godot 4 installed and available either: -* in your `PATH` as `godot4`, -* or an environment variable called `GODOT4_BIN`, containing the path to the Godot executable. +- in your `PATH` as `godot4`, +- or an environment variable called `GODOT4_BIN`, containing the path to the Godot executable. Binaries of Godot 4 can be downloaded [from the official website][godot-download]. diff --git a/src/toolchain/compatibility.md b/src/toolchain/compatibility.md index b826ea7..c8f78f8 100644 --- a/src/toolchain/compatibility.md +++ b/src/toolchain/compatibility.md @@ -14,8 +14,8 @@ The gdext library supports all stable Godot releases starting from Godot 4.0. When developing extension libraries (or just "extensions"), you need to consider which engine version you want to target. There are two conceptually different versions: -* **API version** is the version of GDExtension against which gdext (and the code of your extension) is compiled. -* **Runtime version** is the version of Godot in which the library built with gdext is run. +- **API version** is the version of GDExtension against which gdext (and the code of your extension) is compiled. +- **Runtime version** is the version of Godot in which the library built with gdext is run. The two versions can be different, but there are certain constraints (see [below](#current-guarantees)). @@ -27,9 +27,9 @@ Godot versions. Nothing is more annoying than updating the engine and recompilin This is sometimes difficult, because: -* Godot may introduce subtle breaking changes of which we are not aware. -* Some changes that are non-breaking in C++ and GDScript are breaking in Rust (e.g. providing a default value for a previously required parameter). -* Using newer features needs to come with a fallback/polyfill for older Godot versions. +- Godot may introduce subtle breaking changes of which we are not aware. +- Some changes that are non-breaking in C++ and GDScript are breaking in Rust (e.g. providing a default value for a previously required parameter). +- Using newer features needs to come with a fallback/polyfill for older Godot versions. We run CI jobs against multiple Godot versions, to get a certain level of confidence that updates do not break compatibility. Nevertheless, the number of possible combinations is large and only growing, so we may miss certain issues. @@ -40,15 +40,15 @@ If you find incompatibilities or violations of the rules stated below, please le Every extension developed with API version `4.0.x` **MUST** be run with the same runtime version. -* In particular, it is not possible to run an extension compiled with API version `4.0.x` in Godot 4.1 or later. +- In particular, it is not possible to run an extension compiled with API version `4.0.x` in Godot 4.1 or later. This is due to breaking changes in Godot's GDExtension API. Starting from Godot 4.1 official release, extensions can be loaded by any Godot version, as long as _runtime version **>=** API version_. -* You can run a `4.1` extension in Godot `4.1.1` or `4.2`. -* You cannot run a `4.2` extension in Godot `4.1.1`. -* This is subject to change depending on how the GDExtension API evolves and how many breaking changes we have to deal with. +- You can run a `4.1` extension in Godot `4.1.1` or `4.2`. +- You cannot run a `4.2` extension in Godot `4.1.1`. +- This is subject to change depending on how the GDExtension API evolves and how many breaking changes we have to deal with. ### Out of scope @@ -56,13 +56,13 @@ _runtime version **>=** API version_. We do **not** invest effort in maintaining compatibility with: 1. Godot in-development versions, except for the latest `master` branch. - * Not that we may take some time to catch-up with the latest changes, so please don't report issues within a few days after + - Not that we may take some time to catch-up with the latest changes, so please don't report issues within a few days after upstream changes have landed. 2. Non-stable releases (alpha, beta, RC). 3. Third-party bindings or GDExtension APIs (C#, C++, Python, ...). - * These may have their own versioning guarantees and release cycles; and there may be specific bugs to such an integration. + - These may have their own versioning guarantees and release cycles; and there may be specific bugs to such an integration. If you find an issue with gdext and another binding, reproduce it in GDScript to make sure it's relevant for us. - * We do however maintain compatibility with Godot, so if integrations go through the engine (e.g. Rust calls a method whose + - We do however maintain compatibility with Godot, so if integrations go through the engine (e.g. Rust calls a method whose implementation is in C#), this should work. 4. Godot with non-standard build flags (e.g. disabled modules). 5. Godot forks or engines running third-party modules. @@ -76,8 +76,8 @@ The alternative would be to lock us early into a design corner. Note that many such breaking changes are externally motivated, for example: -* GDExtension changes in a way that cannot be abstracted from the user. -* There are subtleties in the type system or runtime guarantees that can be modeled in a better, safer way (e.g. typed arrays, RIDs). -* We get feedback from game developers and other users stating that certain workflows are very cumbersome. +- GDExtension changes in a way that cannot be abstracted from the user. +- There are subtleties in the type system or runtime guarantees that can be modeled in a better, safer way (e.g. typed arrays, RIDs). +- We get feedback from game developers and other users stating that certain workflows are very cumbersome. Once we get into a more stable feature set, we plan to release versions on crates.io and follow semantic versioning.