From d15bc3f9a0fc7e7d6a87ae80595be4289788df12 Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Wed, 21 Feb 2024 13:20:49 -0500 Subject: [PATCH 1/6] feat: document all members of `bevy_dynamic_plugin` --- crates/bevy_dynamic_plugin/src/lib.rs | 22 ++++++++++++++++++++-- crates/bevy_dynamic_plugin/src/loader.rs | 23 +++++++++++++++-------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/crates/bevy_dynamic_plugin/src/lib.rs b/crates/bevy_dynamic_plugin/src/lib.rs index 961ae5a19f5b2..fd7cb30e326cc 100644 --- a/crates/bevy_dynamic_plugin/src/lib.rs +++ b/crates/bevy_dynamic_plugin/src/lib.rs @@ -1,5 +1,23 @@ -// FIXME(3492): remove once docs are ready -#![allow(missing_docs)] +//! Bevy's dynamic plugin loading functionality. +//! +//! This crate allows loading dynamic libraries (`.dylib`, `.so`) that export a single +//! [`Plugin`](bevy_app::Plugin). For usage, see [`dynamically_load_plugin`]. +//! +//! Note that dynamic linking and loading is inheritly unsafe because it allows executing foreign +//! code. Additionally, Rust does not have a stable ABI and may produce +//! incompatible libraries across Rust versions, or even subsequent compilations. This will not work +//! well in scenarios such as modding, but can work if the dynamic plugins and the main app are +//! built at the same time, such as with DLCs. +//! +//! You may be interested in these safer alternatives: +//! +//! - [Bevy Assets - Scripting]: Scripting and modding libraries for Bevy +//! - [`dextrous_developer`]: Hot reloading system +//! - [`stabby`]: Stable Rust ABI +//! +//! [Bevy Assets - Scripting]: https://bevyengine.org/assets/#scripting +//! [`dextrous_developer`]: https://github.com/lee-orr/dexterous_developer +//! [`stabby`]: https://github.com/ZettaScaleLabs/stabby mod loader; diff --git a/crates/bevy_dynamic_plugin/src/loader.rs b/crates/bevy_dynamic_plugin/src/loader.rs index 656e3778490e3..8d9b5a7ea45c4 100644 --- a/crates/bevy_dynamic_plugin/src/loader.rs +++ b/crates/bevy_dynamic_plugin/src/loader.rs @@ -7,8 +7,10 @@ use bevy_app::{App, CreatePlugin, Plugin}; /// Errors that can occur when loading a dynamic plugin #[derive(Debug, Error)] pub enum DynamicPluginLoadError { + /// An error when loading a dynamic library. #[error("cannot load library for dynamic plugin: {0}")] Library(#[source] libloading::Error), + /// An error when loading a library without a valid Bevy plugin. #[error("dynamic library does not contain a valid Bevy dynamic plugin")] Plugin(#[source] libloading::Error), } @@ -18,22 +20,22 @@ pub enum DynamicPluginLoadError { /// /// # Safety /// -/// The specified plugin must be linked against the exact same libbevy.so as this program. +/// The specified plugin must be linked against the exact same `libbevy.so` as this program. /// In addition the `_bevy_create_plugin` symbol must not be manually created, but instead created /// by deriving `DynamicPlugin` on a unit struct implementing [`Plugin`]. /// -/// Dynamically loading plugins is orchestrated through dynamic linking. When linking against foreign -/// code, initialization routines may be run (as well as termination routines when the program exits). -/// The caller of this function is responsible for ensuring these routines are sound. For more -/// information, please see the safety section of [`libloading::Library::new`]. +/// Dynamically loading plugins is orchestrated through dynamic linking. When linking against +/// foreign code, initialization routines may be run (as well as termination routines when the +/// program exits). The caller of this function is responsible for ensuring these routines are +/// sound. For more information, please see the safety section of [`libloading::Library::new`]. pub unsafe fn dynamically_load_plugin>( path: P, ) -> Result<(Library, Box), DynamicPluginLoadError> { // SAFETY: Caller must follow the safety requirements of Library::new. let lib = unsafe { Library::new(path).map_err(DynamicPluginLoadError::Library)? }; - // SAFETY: Loaded plugins are not allowed to specify `_bevy_create_plugin` symbol manually, but must - // instead automatically generate it through `DynamicPlugin`. + // SAFETY: Loaded plugins are not allowed to specify `_bevy_create_plugin` symbol manually, but + // must instead automatically generate it through `DynamicPlugin`. let func: Symbol = unsafe { lib.get(b"_bevy_create_plugin") .map_err(DynamicPluginLoadError::Plugin)? @@ -46,10 +48,15 @@ pub unsafe fn dynamically_load_plugin>( Ok((lib, plugin)) } +/// An extension trait for [`App`] that allows loading dynamic plugins. pub trait DynamicPluginExt { + /// Dynamically links a plugin at the given path, registering the plugin. + /// + /// For more details, see [`dynamically_load_plugin`]. + /// /// # Safety /// - /// Same as [`dynamically_load_plugin`]. + /// See [`dynamically_load_plugin`]'s safety section. unsafe fn load_plugin>(&mut self, path: P) -> &mut Self; } From fe71a0d434707c8d7ff6728c7b0d4b92348925ba Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Wed, 21 Feb 2024 13:51:52 -0500 Subject: [PATCH 2/6] fix: typo "inheritly" -> "inherently" Co-authored-by: Alice Cecile --- crates/bevy_dynamic_plugin/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_dynamic_plugin/src/lib.rs b/crates/bevy_dynamic_plugin/src/lib.rs index fd7cb30e326cc..490e8185ac247 100644 --- a/crates/bevy_dynamic_plugin/src/lib.rs +++ b/crates/bevy_dynamic_plugin/src/lib.rs @@ -3,7 +3,7 @@ //! This crate allows loading dynamic libraries (`.dylib`, `.so`) that export a single //! [`Plugin`](bevy_app::Plugin). For usage, see [`dynamically_load_plugin`]. //! -//! Note that dynamic linking and loading is inheritly unsafe because it allows executing foreign +//! Note that dynamic linking and loading is inherently unsafe because it allows executing foreign //! code. Additionally, Rust does not have a stable ABI and may produce //! incompatible libraries across Rust versions, or even subsequent compilations. This will not work //! well in scenarios such as modding, but can work if the dynamic plugins and the main app are From cf79d8806eb39233aab00ba58fdfefcb55dac94d Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Wed, 21 Feb 2024 13:52:30 -0500 Subject: [PATCH 3/6] feat: expand "DLC" -> "Downloadable Content" Co-authored-by: Alice Cecile --- crates/bevy_dynamic_plugin/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_dynamic_plugin/src/lib.rs b/crates/bevy_dynamic_plugin/src/lib.rs index 490e8185ac247..a34630209531b 100644 --- a/crates/bevy_dynamic_plugin/src/lib.rs +++ b/crates/bevy_dynamic_plugin/src/lib.rs @@ -7,7 +7,7 @@ //! code. Additionally, Rust does not have a stable ABI and may produce //! incompatible libraries across Rust versions, or even subsequent compilations. This will not work //! well in scenarios such as modding, but can work if the dynamic plugins and the main app are -//! built at the same time, such as with DLCs. +//! built at the same time, such as with Downloadable Content (DLC) packs. //! //! You may be interested in these safer alternatives: //! From 74b871eac28a4504c3a65125e907536fbeb70075 Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Wed, 21 Feb 2024 14:40:28 -0500 Subject: [PATCH 4/6] fix: change comment on `DynamicPluginLoadError::Library` Co-authored-by: James Liu --- crates/bevy_dynamic_plugin/src/loader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_dynamic_plugin/src/loader.rs b/crates/bevy_dynamic_plugin/src/loader.rs index 8d9b5a7ea45c4..bf008332e3215 100644 --- a/crates/bevy_dynamic_plugin/src/loader.rs +++ b/crates/bevy_dynamic_plugin/src/loader.rs @@ -7,7 +7,7 @@ use bevy_app::{App, CreatePlugin, Plugin}; /// Errors that can occur when loading a dynamic plugin #[derive(Debug, Error)] pub enum DynamicPluginLoadError { - /// An error when loading a dynamic library. + /// An error occurred when loading a dynamic library. #[error("cannot load library for dynamic plugin: {0}")] Library(#[source] libloading::Error), /// An error when loading a library without a valid Bevy plugin. From 3c1c8083cbc3d297233c3181e6024b2fc9288dce Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Wed, 21 Feb 2024 14:41:15 -0500 Subject: [PATCH 5/6] fix: change comment on `DynamicPluginLoadError::Plugin` Co-authored-by: James Liu --- crates/bevy_dynamic_plugin/src/loader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_dynamic_plugin/src/loader.rs b/crates/bevy_dynamic_plugin/src/loader.rs index bf008332e3215..94c283a886e78 100644 --- a/crates/bevy_dynamic_plugin/src/loader.rs +++ b/crates/bevy_dynamic_plugin/src/loader.rs @@ -10,7 +10,7 @@ pub enum DynamicPluginLoadError { /// An error occurred when loading a dynamic library. #[error("cannot load library for dynamic plugin: {0}")] Library(#[source] libloading::Error), - /// An error when loading a library without a valid Bevy plugin. + /// An error occurred when loading a library without a valid Bevy plugin. #[error("dynamic library does not contain a valid Bevy dynamic plugin")] Plugin(#[source] libloading::Error), } From cc6e05922a11333b08db056a97400fe83765b8a4 Mon Sep 17 00:00:00 2001 From: BD103 <59022059+BD103@users.noreply.github.com> Date: Wed, 21 Feb 2024 20:04:54 -0500 Subject: [PATCH 6/6] fix: don't explicitly mention `dextrous_developer` --- crates/bevy_dynamic_plugin/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_dynamic_plugin/src/lib.rs b/crates/bevy_dynamic_plugin/src/lib.rs index a34630209531b..3a620cee1f6be 100644 --- a/crates/bevy_dynamic_plugin/src/lib.rs +++ b/crates/bevy_dynamic_plugin/src/lib.rs @@ -12,11 +12,11 @@ //! You may be interested in these safer alternatives: //! //! - [Bevy Assets - Scripting]: Scripting and modding libraries for Bevy -//! - [`dextrous_developer`]: Hot reloading system +//! - [Bevy Assets - Development tools]: Hot reloading and other development functionality //! - [`stabby`]: Stable Rust ABI //! //! [Bevy Assets - Scripting]: https://bevyengine.org/assets/#scripting -//! [`dextrous_developer`]: https://github.com/lee-orr/dexterous_developer +//! [Bevy Assets - Development tools]: https://bevyengine.org/assets/#development-tools //! [`stabby`]: https://github.com/ZettaScaleLabs/stabby mod loader;