@@ -8,8 +8,10 @@ use crate::io::{
8
8
memory:: { Dir , MemoryAssetReader , Value } ,
9
9
AssetSource , AssetSourceBuilders ,
10
10
} ;
11
+ use crate :: AssetServer ;
11
12
use alloc:: boxed:: Box ;
12
- use bevy_ecs:: resource:: Resource ;
13
+ use bevy_app:: App ;
14
+ use bevy_ecs:: { resource:: Resource , world:: World } ;
13
15
use std:: path:: { Path , PathBuf } ;
14
16
15
17
#[ cfg( feature = "embedded_watcher" ) ]
@@ -132,6 +134,71 @@ impl EmbeddedAssetRegistry {
132
134
}
133
135
}
134
136
137
+ /// Trait for the [`load_embedded_asset!`] macro, to access [`AssetServer`]
138
+ /// from arbitrary things.
139
+ ///
140
+ /// [`load_embedded_asset!`]: crate::load_embedded_asset
141
+ pub trait GetAssetServer {
142
+ fn get_asset_server ( & self ) -> & AssetServer ;
143
+ }
144
+ impl GetAssetServer for App {
145
+ fn get_asset_server ( & self ) -> & AssetServer {
146
+ self . world ( ) . get_asset_server ( )
147
+ }
148
+ }
149
+ impl GetAssetServer for World {
150
+ fn get_asset_server ( & self ) -> & AssetServer {
151
+ self . resource ( )
152
+ }
153
+ }
154
+ impl GetAssetServer for AssetServer {
155
+ fn get_asset_server ( & self ) -> & AssetServer {
156
+ self
157
+ }
158
+ }
159
+
160
+ /// Load an [embedded asset](crate::embedded_asset).
161
+ ///
162
+ /// This is useful if the embedded asset in question is not publicly exposed, but
163
+ /// you need to use it internally.
164
+ ///
165
+ /// # Syntax
166
+ ///
167
+ /// This macro takes two arguments and an optional third one:
168
+ /// 1. The asset source. It may be `AssetServer`, `World` or `App`.
169
+ /// 2. The path to the asset to embed, as a string literal.
170
+ /// 3. Optionally, a closure of the same type as in [`AssetServer::load_with_settings`].
171
+ /// Consider explicitly typing the closure argument in case of type error.
172
+ ///
173
+ /// # Usage
174
+ ///
175
+ /// The advantage compared to using directly [`AssetServer::load`] is:
176
+ /// - This also accepts [`World`] and [`App`] arguments.
177
+ /// - This uses the exact same path as `embedded_asset!`, so you can keep it
178
+ /// consistent.
179
+ ///
180
+ /// As a rule of thumb:
181
+ /// - If the asset in used in the same module as it is declared using `embedded_asset!`,
182
+ /// use this macro.
183
+ /// - Otherwise, use `AssetServer::load`.
184
+ #[ macro_export]
185
+ macro_rules! load_embedded_asset {
186
+ ( @get: $path: literal, $provider: expr) => { {
187
+ let path = $crate:: embedded_path!( $path) ;
188
+ let path = $crate:: AssetPath :: from_path_buf( path) . with_source( "embedded" ) ;
189
+ let asset_server = $crate:: io:: embedded:: GetAssetServer :: get_asset_server( $provider) ;
190
+ ( path, asset_server)
191
+ } } ;
192
+ ( $provider: expr, $path: literal, $settings: expr) => { {
193
+ let ( path, asset_server) = $crate:: load_embedded_asset!( @get: $path, $provider) ;
194
+ asset_server. load_with_settings( path, $settings)
195
+ } } ;
196
+ ( $provider: expr, $path: literal) => { {
197
+ let ( path, asset_server) = $crate:: load_embedded_asset!( @get: $path, $provider) ;
198
+ asset_server. load( path)
199
+ } } ;
200
+ }
201
+
135
202
/// Returns the [`Path`] for a given `embedded` asset.
136
203
/// This is used internally by [`embedded_asset`] and can be used to get a [`Path`]
137
204
/// that matches the [`AssetPath`](crate::AssetPath) used by that asset.
@@ -140,7 +207,7 @@ impl EmbeddedAssetRegistry {
140
207
#[ macro_export]
141
208
macro_rules! embedded_path {
142
209
( $path_str: expr) => { {
143
- embedded_path!( "src" , $path_str)
210
+ $crate :: embedded_path!( "src" , $path_str)
144
211
} } ;
145
212
146
213
( $source_path: expr, $path_str: expr) => { {
@@ -185,7 +252,7 @@ pub fn _embedded_asset_path(
185
252
/// Creates a new `embedded` asset by embedding the bytes of the given path into the current binary
186
253
/// and registering those bytes with the `embedded` [`AssetSource`].
187
254
///
188
- /// This accepts the current [`App`](bevy_app::App) as the first parameter and a path `&str` (relative to the current file) as the second.
255
+ /// This accepts the current [`App`] as the first parameter and a path `&str` (relative to the current file) as the second.
189
256
///
190
257
/// By default this will generate an [`AssetPath`] using the following rules:
191
258
///
@@ -210,14 +277,19 @@ pub fn _embedded_asset_path(
210
277
///
211
278
/// `embedded_asset!(app, "rock.wgsl")`
212
279
///
213
- /// `rock.wgsl` can now be loaded by the [`AssetServer`](crate::AssetServer) with the following path :
280
+ /// `rock.wgsl` can now be loaded by the [`AssetServer`] as follows :
214
281
///
215
282
/// ```no_run
216
- /// # use bevy_asset::{Asset, AssetServer};
283
+ /// # use bevy_asset::{Asset, AssetServer, load_embedded_asset };
217
284
/// # use bevy_reflect::TypePath;
218
285
/// # let asset_server: AssetServer = panic!();
219
286
/// # #[derive(Asset, TypePath)]
220
287
/// # struct Shader;
288
+ /// // If we are loading the shader in the same module we used `embedded_asset!`:
289
+ /// let shader = load_embedded_asset!(&asset_server, "rock.wgsl");
290
+ /// # let _: bevy_asset::Handle<Shader> = shader;
291
+ ///
292
+ /// // If the goal is to expose the asset **to the end user**:
221
293
/// let shader = asset_server.load::<Shader>("embedded://bevy_rock/render/rock.wgsl");
222
294
/// ```
223
295
///
@@ -251,11 +323,11 @@ pub fn _embedded_asset_path(
251
323
/// [`embedded_path`]: crate::embedded_path
252
324
#[ macro_export]
253
325
macro_rules! embedded_asset {
254
- ( $app: ident , $path: expr) => { {
326
+ ( $app: expr , $path: expr) => { {
255
327
$crate:: embedded_asset!( $app, "src" , $path)
256
328
} } ;
257
329
258
- ( $app: ident , $source_path: expr, $path: expr) => { {
330
+ ( $app: expr , $source_path: expr, $path: expr) => { {
259
331
let mut embedded = $app
260
332
. world_mut( )
261
333
. resource_mut:: <$crate:: io:: embedded:: EmbeddedAssetRegistry >( ) ;
0 commit comments