Skip to content

Commit 2d796fd

Browse files
committed
fix: fix missing extensions in the asset loader
1 parent b9d92df commit 2d796fd

File tree

5 files changed

+104
-6
lines changed

5 files changed

+104
-6
lines changed

crates/bevy_mod_scripting_core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ derivative = "2.2"
4343
profiling = { workspace = true }
4444
[dev-dependencies]
4545
test_utils = { workspace = true }
46+
tokio = { version = "1", features = ["rt", "macros"] }
4647

4748
[lints]
4849
workspace = true

crates/bevy_mod_scripting_core/src/asset.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ pub struct ScriptAssetSettings {
112112
pub script_id_mapper: AssetPathToScriptIdMapper,
113113
/// Strategies for mapping asset paths to languages
114114
pub script_language_mappers: Vec<AssetPathToLanguageMapper>,
115+
116+
/// The currently supported asset extensions
117+
/// Should be updated by each scripting plugin to include the extensions it supports.
118+
///
119+
/// Will be used to populate the script asset loader with the supported extensions
120+
pub supported_extensions: &'static [&'static str],
115121
}
116122

117123
impl ScriptAssetSettings {
@@ -136,6 +142,7 @@ impl Default for ScriptAssetSettings {
136142
map: (|path: &AssetPath| path.path().to_string_lossy().into_owned().into()),
137143
},
138144
script_language_mappers: vec![],
145+
supported_extensions: &[],
139146
}
140147
}
141148
}
@@ -374,6 +381,7 @@ mod tests {
374381

375382
fn make_test_settings() -> ScriptAssetSettings {
376383
ScriptAssetSettings {
384+
supported_extensions: &[],
377385
script_id_mapper: AssetPathToScriptIdMapper {
378386
map: |path| path.path().to_string_lossy().into_owned().into(),
379387
},

crates/bevy_mod_scripting_core/src/lib.rs

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ pub struct ScriptingPlugin<P: IntoScriptPluginParams> {
8585
pub context_initializers: Vec<ContextInitializer<P>>,
8686
/// initializers for the contexts run every time before handling events
8787
pub context_pre_handling_initializers: Vec<ContextPreHandlingInitializer<P>>,
88+
89+
/// Supported extensions to be added to the asset settings without the dot
90+
pub supported_extensions: &'static [&'static str],
8891
}
8992

9093
impl<P: IntoScriptPluginParams> Plugin for ScriptingPlugin<P> {
@@ -107,6 +110,8 @@ impl<P: IntoScriptPluginParams> Plugin for ScriptingPlugin<P> {
107110
register_script_plugin_systems::<P>(app);
108111
once_per_app_init(app);
109112

113+
app.add_supported_script_extensions(self.supported_extensions);
114+
110115
app.world_mut()
111116
.resource_mut::<ScriptAssetSettings>()
112117
.as_mut()
@@ -115,6 +120,10 @@ impl<P: IntoScriptPluginParams> Plugin for ScriptingPlugin<P> {
115120

116121
register_types(app);
117122
}
123+
124+
fn finish(&self, app: &mut App) {
125+
once_per_app_finalize(app);
126+
}
118127
}
119128

120129
impl<P: IntoScriptPluginParams> ScriptingPlugin<P> {
@@ -197,6 +206,29 @@ impl<P: IntoScriptPluginParams + AsMut<ScriptingPlugin<P>>> ConfigureScriptPlugi
197206
}
198207
}
199208

209+
fn once_per_app_finalize(app: &mut App) {
210+
#[derive(Resource)]
211+
struct BMSFinalized;
212+
213+
if app.world().contains_resource::<BMSFinalized>() {
214+
return;
215+
}
216+
app.insert_resource(BMSFinalized);
217+
218+
// read extensions from asset settings
219+
let asset_settings_extensions = app
220+
.world_mut()
221+
.get_resource_or_init::<ScriptAssetSettings>()
222+
.supported_extensions;
223+
224+
// convert extensions to static array
225+
226+
app.register_asset_loader(ScriptAssetLoader {
227+
extensions: asset_settings_extensions,
228+
preprocessor: None,
229+
});
230+
}
231+
200232
// One of registration of things that need to be done only once per app
201233
fn once_per_app_init(app: &mut App) {
202234
#[derive(Resource)]
@@ -205,19 +237,14 @@ fn once_per_app_init(app: &mut App) {
205237
if app.world().contains_resource::<BMSInitialized>() {
206238
return;
207239
}
208-
209240
app.insert_resource(BMSInitialized);
210241

211242
app.add_event::<ScriptErrorEvent>()
212243
.add_event::<ScriptCallbackEvent>()
213244
.init_resource::<AppReflectAllocator>()
214245
.init_resource::<Scripts>()
215246
.init_asset::<ScriptAsset>()
216-
.init_resource::<AppScriptFunctionRegistry>()
217-
.register_asset_loader(ScriptAssetLoader {
218-
extensions: &[],
219-
preprocessor: None,
220-
});
247+
.init_resource::<AppScriptFunctionRegistry>();
221248

222249
app.add_systems(
223250
PostUpdate,
@@ -274,3 +301,63 @@ impl AddRuntimeInitializer for App {
274301
self
275302
}
276303
}
304+
305+
/// Trait for adding a supported extension to the script asset settings.
306+
///
307+
/// This is only valid in the plugin building phase, as the asset loader will be created in the `finalize` phase.
308+
/// Any changes to the asset settings after that will not be reflected in the asset loader.
309+
pub trait ConfigureScriptAssetSettings {
310+
/// Adds a supported extension to the asset settings
311+
fn add_supported_script_extensions(&mut self, extensions: &[&'static str]) -> &mut Self;
312+
}
313+
314+
impl ConfigureScriptAssetSettings for App {
315+
fn add_supported_script_extensions(&mut self, extensions: &[&'static str]) -> &mut Self {
316+
let mut asset_settings = self
317+
.world_mut()
318+
.get_resource_or_init::<ScriptAssetSettings>();
319+
320+
let mut new_arr = Vec::from(asset_settings.supported_extensions);
321+
322+
new_arr.extend(extensions);
323+
324+
let new_arr_static = Vec::leak(new_arr);
325+
326+
asset_settings.supported_extensions = new_arr_static;
327+
328+
self
329+
}
330+
}
331+
332+
#[cfg(test)]
333+
mod test {
334+
use super::*;
335+
336+
#[tokio::test]
337+
async fn test_asset_extensions_correctly_accumulate() {
338+
let mut app = App::new();
339+
app.init_resource::<ScriptAssetSettings>();
340+
app.add_plugins(AssetPlugin::default());
341+
342+
app.world_mut()
343+
.resource_mut::<ScriptAssetSettings>()
344+
.supported_extensions = &["lua", "rhai"];
345+
346+
once_per_app_finalize(&mut app);
347+
348+
let asset_loader = app
349+
.world()
350+
.get_resource::<AssetServer>()
351+
.expect("Asset loader not found");
352+
353+
asset_loader
354+
.get_asset_loader_with_extension("lua")
355+
.await
356+
.expect("Lua loader not found");
357+
358+
asset_loader
359+
.get_asset_loader_with_extension("rhai")
360+
.await
361+
.expect("Rhai loader not found");
362+
}
363+
}

crates/languages/bevy_mod_scripting_lua/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ impl Default for LuaScriptingPlugin {
134134
.map_err(ScriptError::from_mlua_error)?;
135135
Ok(())
136136
}],
137+
supported_extensions: &["lua"],
137138
},
138139
}
139140
}

crates/languages/bevy_mod_scripting_rhai/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ impl Default for RhaiScriptingPlugin {
155155
context.scope.set_or_push("script_id", script.to_owned());
156156
Ok(())
157157
}],
158+
supported_extensions: &["rhai"],
158159
},
159160
}
160161
}

0 commit comments

Comments
 (0)