Skip to content

Commit 37b43be

Browse files
committed
feat!: Add BMSPlugin group, feature flag for bindings per bevy crate & global registration options
1 parent 7e2e970 commit 37b43be

File tree

12 files changed

+215
-121
lines changed

12 files changed

+215
-121
lines changed

Cargo.toml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,18 @@ bench = false
2121
features = ["lua54", "rhai"]
2222

2323
[features]
24-
default = ["core_functions", "bevy_bindings"]
24+
default = [
25+
"core_functions",
26+
"bevy_bindings",
27+
"bevy_core_bindings",
28+
"bevy_ecs_bindings",
29+
"bevy_hierarchy_bindings",
30+
"bevy_input_bindings",
31+
"bevy_math_bindings",
32+
"bevy_reflect_bindings",
33+
"bevy_time_bindings",
34+
"bevy_transform_bindings",
35+
]
2536

2637
lua = [
2738
"bevy_mod_scripting_lua",
@@ -40,6 +51,15 @@ luau = ["bevy_mod_scripting_lua/luau", "lua"]
4051
core_functions = ["bevy_mod_scripting_functions/core_functions"]
4152
bevy_bindings = ["bevy_mod_scripting_functions/bevy_bindings"]
4253

54+
bevy_core_bindings = ["bevy_mod_scripting_functions/bevy_core"]
55+
bevy_ecs_bindings = ["bevy_mod_scripting_functions/bevy_ecs"]
56+
bevy_hierarchy_bindings = ["bevy_mod_scripting_functions/bevy_hierarchy"]
57+
bevy_input_bindings = ["bevy_mod_scripting_functions/bevy_input"]
58+
bevy_math_bindings = ["bevy_mod_scripting_functions/bevy_math"]
59+
bevy_reflect_bindings = ["bevy_mod_scripting_functions/bevy_reflect"]
60+
bevy_time_bindings = ["bevy_mod_scripting_functions/bevy_time"]
61+
bevy_transform_bindings = ["bevy_mod_scripting_functions/bevy_transform"]
62+
4363
# optional
4464
unsafe_lua_modules = ["bevy_mod_scripting_lua?/unsafe_lua_modules"]
4565
mlua_serialize = ["bevy_mod_scripting_lua?/mlua_serialize"]

crates/bevy_api_gen/templates/mod.tera

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,8 @@
44
#![cfg_attr(rustfmt, rustfmt_skip)]
55
{% filter prettyplease %}
66
{%- for crate in crates %}
7+
#[cfg(feature="{{crate.name}}")]
78
pub mod {{ crate.name }};
89
{% endfor -%}
910

10-
pub struct {{ api_name }};
11-
12-
impl ::bevy::app::Plugin for {{ api_name }} {
13-
fn build(&self, app: &mut ::bevy::prelude::App) {
14-
{% for crate in crates %}
15-
{% set crate_name = crate.name %}
16-
{{ crate_name }}::{{ "ScriptingPlugin" | prefix(val=crate_name) | convert_case(case="upper_camel")}}.build(app);
17-
{% endfor %}
18-
}
19-
}
2011
{% endfilter %}

crates/bevy_mod_scripting_core/src/bindings/globals/core.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{collections::HashMap, sync::Arc};
55
use bevy::{
66
app::Plugin,
77
ecs::{entity::Entity, reflect::AppTypeRegistry, world::World},
8+
reflect::TypeRegistration,
89
};
910
use bevy_mod_scripting_derive::script_globals;
1011

@@ -20,14 +21,37 @@ use crate::{
2021

2122
use super::AppScriptGlobalsRegistry;
2223

23-
/// A plugin introducing core globals for the BMS framework
24-
pub struct CoreScriptGlobalsPlugin;
24+
/// A plugin introducing core globals for the BMS framework.
25+
///
26+
/// By default all types added to the type registry are present as globals, you can customize this behavior
27+
/// by providing a filter function
28+
pub struct CoreScriptGlobalsPlugin {
29+
/// the filter function used to determine which types are registered as globals
30+
/// When `true` for the given type registration, the type will be registered as a global.
31+
_filter: fn(&TypeRegistration) -> bool,
32+
33+
/// Whether to register static references to types
34+
/// By default static type references such as `Vec3` or `Mat3` are accessible directly from the global namespace.
35+
register_static_references: bool,
36+
}
37+
38+
impl Default for CoreScriptGlobalsPlugin {
39+
fn default() -> Self {
40+
Self {
41+
_filter: |_| true,
42+
register_static_references: true,
43+
}
44+
}
45+
}
2546

2647
impl Plugin for CoreScriptGlobalsPlugin {
2748
fn build(&self, _app: &mut bevy::app::App) {}
2849
fn finish(&self, app: &mut bevy::app::App) {
2950
profiling::function_scope!("app finish");
30-
register_static_core_globals(app.world_mut());
51+
52+
if self.register_static_references {
53+
register_static_core_globals(app.world_mut());
54+
}
3155
register_core_globals(app.world_mut());
3256
}
3357
}

crates/bevy_mod_scripting_core/src/lib.rs

Lines changed: 50 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@ use asset::{
99
};
1010
use bevy::prelude::*;
1111
use bindings::{
12-
function::script_function::AppScriptFunctionRegistry,
13-
garbage_collector,
14-
globals::{core::CoreScriptGlobalsPlugin, AppScriptGlobalsRegistry},
15-
schedule::AppScheduleRegistry,
16-
script_value::ScriptValue,
12+
function::script_function::AppScriptFunctionRegistry, garbage_collector,
13+
globals::AppScriptGlobalsRegistry, schedule::AppScheduleRegistry, script_value::ScriptValue,
1714
AppReflectAllocator, DynamicScriptComponentPlugin, ReflectAllocator, ReflectReference,
1815
ScriptTypeRegistration,
1916
};
@@ -137,9 +134,6 @@ impl<P: IntoScriptPluginParams> Plugin for ScriptingPlugin<P> {
137134

138135
register_script_plugin_systems::<P>(app);
139136

140-
// add extension for the language to the asset loader
141-
once_per_app_init(app);
142-
143137
if !self.additional_supported_extensions.is_empty() {
144138
app.add_supported_script_extensions(
145139
self.additional_supported_extensions,
@@ -149,10 +143,6 @@ impl<P: IntoScriptPluginParams> Plugin for ScriptingPlugin<P> {
149143

150144
register_types(app);
151145
}
152-
153-
fn finish(&self, app: &mut App) {
154-
once_per_app_finalize(app);
155-
}
156146
}
157147

158148
impl<P: IntoScriptPluginParams> ScriptingPlugin<P> {
@@ -246,36 +236,6 @@ impl<P: IntoScriptPluginParams + AsMut<ScriptingPlugin<P>>> ConfigureScriptPlugi
246236
}
247237
}
248238

249-
fn once_per_app_finalize(app: &mut App) {
250-
#[derive(Resource)]
251-
struct BMSFinalized;
252-
253-
if app.world().contains_resource::<BMSFinalized>() {
254-
return;
255-
}
256-
app.insert_resource(BMSFinalized);
257-
258-
// read extensions from asset settings
259-
let asset_settings_extensions = app
260-
.world_mut()
261-
.get_resource_or_init::<ScriptAssetSettings>()
262-
.supported_extensions;
263-
264-
// convert extensions to static array
265-
bevy::log::info!(
266-
"Initializing BMS with Supported extensions: {:?}",
267-
asset_settings_extensions
268-
);
269-
270-
app.register_asset_loader(ScriptAssetLoader {
271-
extensions: asset_settings_extensions,
272-
preprocessor: None,
273-
});
274-
275-
// pre-register component id's
276-
pre_register_componnents(app);
277-
}
278-
279239
/// Ensures all types with `ReflectComponent` type data are pre-registered with component ID's
280240
fn pre_register_componnents(app: &mut App) {
281241
let type_registry = app
@@ -290,34 +250,54 @@ fn pre_register_componnents(app: &mut App) {
290250
}
291251
}
292252

293-
// One of registration of things that need to be done only once per app
294-
fn once_per_app_init(app: &mut App) {
295-
#[derive(Resource)]
296-
struct BMSInitialized;
297-
298-
if app.world().contains_resource::<BMSInitialized>() {
299-
return;
253+
/// A plugin defining shared settings between various scripting plugins
254+
/// It is necessary to register this plugin for any of them to work
255+
pub struct BMSScriptingInfrastructurePlugin;
256+
257+
impl Plugin for BMSScriptingInfrastructurePlugin {
258+
fn build(&self, app: &mut App) {
259+
app.add_event::<ScriptErrorEvent>()
260+
.add_event::<ScriptCallbackEvent>()
261+
.add_event::<ScriptCallbackResponseEvent>()
262+
.init_resource::<AppReflectAllocator>()
263+
.init_resource::<StaticScripts>()
264+
.init_asset::<ScriptAsset>()
265+
.init_resource::<AppScriptFunctionRegistry>()
266+
.init_resource::<AppScriptGlobalsRegistry>()
267+
.insert_resource(AppScheduleRegistry::new());
268+
269+
app.add_systems(
270+
PostUpdate,
271+
((garbage_collector).in_set(ScriptingSystemSet::GarbageCollection),),
272+
);
273+
274+
configure_asset_systems(app);
275+
276+
DynamicScriptComponentPlugin.build(app);
300277
}
301-
app.insert_resource(BMSInitialized);
302-
303-
app.add_event::<ScriptErrorEvent>()
304-
.add_event::<ScriptCallbackEvent>()
305-
.add_event::<ScriptCallbackResponseEvent>()
306-
.init_resource::<AppReflectAllocator>()
307-
.init_resource::<StaticScripts>()
308-
.init_asset::<ScriptAsset>()
309-
.init_resource::<AppScriptFunctionRegistry>()
310-
.init_resource::<AppScriptGlobalsRegistry>()
311-
.insert_resource(AppScheduleRegistry::new());
312278

313-
app.add_systems(
314-
PostUpdate,
315-
((garbage_collector).in_set(ScriptingSystemSet::GarbageCollection),),
316-
);
317-
318-
app.add_plugins((CoreScriptGlobalsPlugin, DynamicScriptComponentPlugin));
319-
320-
configure_asset_systems(app);
279+
fn finish(&self, app: &mut App) {
280+
// read extensions from asset settings
281+
let asset_settings_extensions = app
282+
.world_mut()
283+
.get_resource_or_init::<ScriptAssetSettings>()
284+
.supported_extensions;
285+
286+
// convert extensions to static array
287+
bevy::log::info!(
288+
"Initializing BMS with Supported extensions: {:?}",
289+
asset_settings_extensions
290+
);
291+
292+
app.register_asset_loader(ScriptAssetLoader {
293+
extensions: asset_settings_extensions,
294+
preprocessor: None,
295+
});
296+
297+
// pre-register component id's
298+
pre_register_componnents(app);
299+
DynamicScriptComponentPlugin.finish(app);
300+
}
321301
}
322302

323303
/// Systems registered per-language
@@ -450,7 +430,7 @@ mod test {
450430
.resource_mut::<ScriptAssetSettings>()
451431
.supported_extensions = &["lua", "rhai"];
452432

453-
once_per_app_finalize(&mut app);
433+
BMSScriptingInfrastructurePlugin.finish(&mut app);
454434

455435
let asset_loader = app
456436
.world()
@@ -482,7 +462,7 @@ mod test {
482462

483463
assert!(app.world_mut().component_id::<Comp>().is_none());
484464

485-
once_per_app_finalize(&mut app);
465+
BMSScriptingInfrastructurePlugin.finish(&mut app);
486466

487467
assert!(app.world_mut().component_id::<Comp>().is_some());
488468
}

crates/bevy_mod_scripting_functions/Cargo.toml

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,23 @@ categories = ["game-development"]
1212
readme = "readme.md"
1313

1414
[features]
15+
bevy_core = ["bevy_bindings"]
16+
bevy_ecs = ["bevy_bindings"]
17+
bevy_hierarchy = ["bevy_bindings"]
18+
bevy_input = ["bevy_bindings"]
19+
bevy_math = ["bevy_bindings"]
20+
bevy_reflect = ["bevy_bindings"]
21+
bevy_time = ["bevy_bindings"]
22+
bevy_transform = ["bevy_bindings"]
23+
1524
core_functions = []
1625
bevy_bindings = []
1726
lua_bindings = ["bevy_mod_scripting_lua"]
1827
rhai_bindings = ["bevy_mod_scripting_rhai"]
1928

2029

2130
[dependencies]
22-
bevy = { workspace = true, features = [
23-
"bevy_asset",
24-
"bevy_animation",
25-
"bevy_core_pipeline",
26-
"bevy_ui",
27-
"bevy_pbr",
28-
"bevy_render",
29-
"bevy_text",
30-
"bevy_sprite",
31-
"multi_threaded",
32-
] }
31+
bevy = { workspace = true }
3332
profiling = { workspace = true }
3433
uuid = "1.11"
3534
smol_str = "0.2.2"

crates/bevy_mod_scripting_functions/src/bevy_bindings/mod.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,19 @@
22
#![allow(clippy::all)]
33
#![allow(unused, deprecated, dead_code)]
44
#![cfg_attr(rustfmt, rustfmt_skip)]
5+
#[cfg(feature = "bevy_core")]
56
pub mod bevy_core;
7+
#[cfg(feature = "bevy_ecs")]
68
pub mod bevy_ecs;
9+
#[cfg(feature = "bevy_hierarchy")]
710
pub mod bevy_hierarchy;
11+
#[cfg(feature = "bevy_input")]
812
pub mod bevy_input;
13+
#[cfg(feature = "bevy_math")]
914
pub mod bevy_math;
15+
#[cfg(feature = "bevy_reflect")]
1016
pub mod bevy_reflect;
17+
#[cfg(feature = "bevy_time")]
1118
pub mod bevy_time;
19+
#[cfg(feature = "bevy_transform")]
1220
pub mod bevy_transform;
13-
pub struct LuaBevyScriptingPlugin;
14-
impl ::bevy::app::Plugin for LuaBevyScriptingPlugin {
15-
fn build(&self, app: &mut ::bevy::prelude::App) {
16-
bevy_core::BevyCoreScriptingPlugin.build(app);
17-
bevy_ecs::BevyEcsScriptingPlugin.build(app);
18-
bevy_hierarchy::BevyHierarchyScriptingPlugin.build(app);
19-
bevy_input::BevyInputScriptingPlugin.build(app);
20-
bevy_math::BevyMathScriptingPlugin.build(app);
21-
bevy_reflect::BevyReflectScriptingPlugin.build(app);
22-
bevy_time::BevyTimeScriptingPlugin.build(app);
23-
bevy_transform::BevyTransformScriptingPlugin.build(app);
24-
}
25-
}

crates/bevy_mod_scripting_functions/src/core.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,27 @@ use bindings::{
3030
use error::InteropError;
3131
use reflection_extensions::{PartialReflectExt, TypeIdExtensions};
3232

33+
#[allow(unused_variables, reason = "feature flags")]
3334
pub fn register_bevy_bindings(app: &mut App) {
3435
#[cfg(feature = "bevy_bindings")]
35-
app.add_plugins(crate::bevy_bindings::LuaBevyScriptingPlugin);
36+
{
37+
#[cfg(feature = "bevy_core")]
38+
app.add_plugins(crate::bevy_bindings::bevy_core::BevyCoreScriptingPlugin);
39+
#[cfg(feature = "bevy_ecs")]
40+
app.add_plugins(crate::bevy_bindings::bevy_ecs::BevyEcsScriptingPlugin);
41+
#[cfg(feature = "bevy_hierarchy")]
42+
app.add_plugins(crate::bevy_bindings::bevy_hierarchy::BevyHierarchyScriptingPlugin);
43+
#[cfg(feature = "bevy_input")]
44+
app.add_plugins(crate::bevy_bindings::bevy_input::BevyInputScriptingPlugin);
45+
#[cfg(feature = "bevy_math")]
46+
app.add_plugins(crate::bevy_bindings::bevy_math::BevyMathScriptingPlugin);
47+
#[cfg(feature = "bevy_reflect")]
48+
app.add_plugins(crate::bevy_bindings::bevy_reflect::BevyReflectScriptingPlugin);
49+
#[cfg(feature = "bevy_time")]
50+
app.add_plugins(crate::bevy_bindings::bevy_time::BevyTimeScriptingPlugin);
51+
#[cfg(feature = "bevy_transform")]
52+
app.add_plugins(crate::bevy_bindings::bevy_transform::BevyTransformScriptingPlugin);
53+
}
3654
}
3755

3856
#[script_bindings(

crates/bevy_mod_scripting_functions/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod core;
77
pub use core::*;
88

99
/// A plugin that registers the core scripting functions.
10+
#[derive(Default)]
1011
pub struct ScriptFunctionsPlugin;
1112

1213
impl Plugin for ScriptFunctionsPlugin {

0 commit comments

Comments
 (0)