Skip to content

Commit

Permalink
Added add_scripting_api function to AppBuilder (#23)
Browse files Browse the repository at this point in the history
* Added `add_scripting_api` function to builder
  • Loading branch information
dansionGit authored Jul 17, 2024
1 parent f85dbcf commit be8a805
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ path = "examples/rhai/function_params.rs"
name = "hello_world_rhai"
path = "examples/rhai/hello_world.rs"

[[example]]
name = "multiple_plugins_rhai"
path = "examples/rhai/multiple_plugins.rs"

[[example]]
name = "non_closure_system_rhai"
path = "examples/rhai/non_closure_system.rs"
Expand Down Expand Up @@ -93,6 +97,10 @@ path = "examples/lua/function_params.rs"
name = "hello_world_lua"
path = "examples/lua/hello_world.rs"

[[example]]
name = "multiple_plugins_lua"
path = "examples/lua/multiple_plugins.rs"

[[example]]
name = "non_closure_system_lua"
path = "examples/lua/non_closure_system.rs"
Expand Down
1 change: 1 addition & 0 deletions assets/examples/lua/multiple_plugins_plugin_a.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello_from_plugin_a()
1 change: 1 addition & 0 deletions assets/examples/lua/multiple_plugins_plugin_b.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello_from_plugin_b_with_parameters("hello", 42)
1 change: 1 addition & 0 deletions assets/examples/rhai/multiple_plugins_plugin_a.rhai
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello_from_plugin_a();
1 change: 1 addition & 0 deletions assets/examples/rhai/multiple_plugins_plugin_b.rhai
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello_from_plugin_b_with_parameters("hello", 42);
30 changes: 30 additions & 0 deletions book/src/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,36 @@ which you can then call in your script like this:
fun_with_string_param("Hello world!")
```

It is also possible to split the definition of your callback functions up over multiple plugins. This enables you to split up your code by subject and keep the main initialization light and clean.
This can be accomplished by using `add_scripting_api`. Be careful though, `add_scripting` has to be called before adding plugins.
```rust
use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;

struct MyPlugin;
impl Plugin for MyPlugin {
fn build(&self, app: &mut App) {
app.add_scripting_api::<LuaRuntime>(|runtime| {
runtime.add_function(String::from("hello_from_my_plugin"), || {
info!("Hello from MyPlugin");
});
});
}
}

// Main
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_scripting::<LuaRuntime>(|_| {
// nice and clean
})
.add_plugins(MyPlugin)
.run();
}
```

### Usage

Add the following to your `Cargo.toml`:
Expand Down
67 changes: 67 additions & 0 deletions examples/lua/multiple_plugins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;

// Plugin A
struct PluginA;
impl Plugin for PluginA {
fn build(&self, app: &mut App) {
app.add_scripting_api::<LuaRuntime>(|runtime| {
runtime.add_function(String::from("hello_from_plugin_a"), || {
info!("Hello from Plugin A");
});
})
.add_systems(Startup, plugin_a_startup);
}
}

fn plugin_a_startup(mut commands: Commands, assets_server: Res<AssetServer>) {
commands.spawn(Script::<LuaScript>::new(
assets_server.load("examples/lua/multiple_plugins_plugin_a.lua"),
));
}

// Plugin B
struct PluginB;
impl Plugin for PluginB {
fn build(&self, app: &mut App) {
app.add_scripting_api::<LuaRuntime>(|runtime| {
runtime.add_function(
String::from("hello_from_plugin_b_with_parameters"),
hello_from_b,
);
})
.add_systems(Startup, plugin_b_startup);
}
}

fn plugin_b_startup(mut commands: Commands, assets_server: Res<AssetServer>) {
commands.spawn(Script::<LuaScript>::new(
assets_server.load("examples/lua/multiple_plugins_plugin_b.lua"),
));
}

fn hello_from_b(In((text, x)): In<(String, i32)>) {
info!("{} from Plugin B: {}", text, x);
}

// Main
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_scripting::<LuaRuntime>(|runtime| {
runtime.add_function(String::from("hello_bevy"), || {
info!("hello bevy, called from script");
});
})
.add_systems(Startup, main_startup)
.add_plugins(PluginA)
.add_plugins(PluginB)
.run();
}

fn main_startup(mut commands: Commands, assets_server: Res<AssetServer>) {
commands.spawn(Script::<LuaScript>::new(
assets_server.load("examples/lua/hello_world.lua"),
));
}
68 changes: 68 additions & 0 deletions examples/rhai/multiple_plugins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::rhai::prelude::*;
use rhai::ImmutableString;

// Plugin A
struct PluginA;
impl Plugin for PluginA {
fn build(&self, app: &mut App) {
app.add_scripting_api::<RhaiRuntime>(|runtime| {
runtime.add_function(String::from("hello_from_plugin_a"), || {
info!("Hello from Plugin A");
});
})
.add_systems(Startup, plugin_a_startup);
}
}

fn plugin_a_startup(mut commands: Commands, assets_server: Res<AssetServer>) {
commands.spawn(Script::<RhaiScript>::new(
assets_server.load("examples/rhai/multiple_plugins_plugin_a.rhai"),
));
}

// Plugin B
struct PluginB;
impl Plugin for PluginB {
fn build(&self, app: &mut App) {
app.add_scripting_api::<RhaiRuntime>(|runtime| {
runtime.add_function(
String::from("hello_from_plugin_b_with_parameters"),
hello_from_b,
);
})
.add_systems(Startup, plugin_b_startup);
}
}

fn plugin_b_startup(mut commands: Commands, assets_server: Res<AssetServer>) {
commands.spawn(Script::<RhaiScript>::new(
assets_server.load("examples/rhai/multiple_plugins_plugin_b.rhai"),
));
}

fn hello_from_b(In((text, x)): In<(ImmutableString, i64)>) {
info!("{} from Plugin B: {}", text, x);
}

// Main
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_scripting::<RhaiRuntime>(|runtime| {
runtime.add_function(String::from("hello_bevy"), || {
info!("hello bevy, called from script");
});
})
.add_systems(Startup, main_startup)
.add_plugins(PluginA)
.add_plugins(PluginB)
.run();
}

fn main_startup(mut commands: Commands, assets_server: Res<AssetServer>) {
commands.spawn(Script::<RhaiScript>::new(
assets_server.load("examples/rhai/hello_world.rhai"),
));
}
48 changes: 48 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,34 @@
//! ```lua
//! fun_with_string_param("Hello world!")
//! ```
//! It is also possible to split the definition of your callback functions up over multiple plugins. This enables you to split up your code by subject and keep the main initialization light and clean.
//! This can be accomplished by using `add_scripting_api`. Be careful though, `add_scripting` has to be called before adding plugins.
//! ```rust
//! use bevy::prelude::*;
//! use bevy_scriptum::prelude::*;
//! use bevy_scriptum::runtimes::lua::prelude::*;
//!
//! struct MyPlugin;
//! impl Plugin for MyPlugin {
//! fn build(&self, app: &mut App) {
//! app.add_scripting_api::<LuaRuntime>(|runtime| {
//! runtime.add_function(String::from("hello_from_my_plugin"), || {
//! info!("Hello from MyPlugin");
//! });
//! });
//! }
//! }
//!
//! App::new()
//! .add_plugins(DefaultPlugins)
//! .add_scripting::<LuaRuntime>(|_| {
//! // nice and clean
//! })
//! .add_plugins(MyPlugin)
//! .run();
//! ```
//!
//!
//! ## Usage
//!
//! Add the following to your `Cargo.toml`:
Expand Down Expand Up @@ -331,6 +358,12 @@ pub trait BuildScriptingRuntime {
/// Returns a "runtime" type than can be used to setup scripting runtime(
/// add scripting functions etc.).
fn add_scripting<R: Runtime>(&mut self, f: impl Fn(ScriptingRuntimeBuilder<R>)) -> &mut Self;

/// Returns a "runtime" type that can be used to add additional scripting functions from plugins etc.
fn add_scripting_api<R: Runtime>(
&mut self,
f: impl Fn(ScriptingRuntimeBuilder<R>),
) -> &mut Self;
}

pub struct ScriptingRuntimeBuilder<'a, R: Runtime> {
Expand Down Expand Up @@ -402,6 +435,21 @@ impl BuildScriptingRuntime for App {

self
}

/// Adds a way to add additional accesspoints to the scripting runtime. For example from plugins to add
/// for example additional lua functions to the runtime.
///
/// Be careful with calling this though, make sure that the `add_scripting` call is already called before calling this function.
fn add_scripting_api<R: Runtime>(
&mut self,
f: impl Fn(ScriptingRuntimeBuilder<R>),
) -> &mut Self {
let runtime = ScriptingRuntimeBuilder::<R>::new(self.world_mut());

f(runtime);

self
}
}

/// A resource that stores all the callbacks that were registered using [AddScriptFunctionAppExt::add_function].
Expand Down

0 comments on commit be8a805

Please sign in to comment.