pub struct AssetServer { /* private fields */ }Expand description
Background-thread plumbing and content cache for the asset pipeline.
- Caches are keyed by source path; entities sharing a path share one decoded
LoadedImageorLoadedSvg(Arc-cheap clones). - Successful decodes populate the LRU image / SVG caches; decode failures populate the LRU failure cache.
- Entities requesting an in-flight path are appended to
pendingand receive the result via the drain. - What a path decodes into comes from the
AssetLoadersregistry, and where its bytes come from comes from the registeredAssetSourcelist; both are replaceable per app. - Decode jobs run on a bounded N-worker
crossbeam-channelpool (N = available_parallelism().min(4)). - A
notify::RecommendedWatcherinvalidates cache entries whose backing file changes on disk and firesAssetReloadRequested.
Implementations§
Source§impl AssetServer
impl AssetServer
Sourcepub fn with_max_bytes(max_bytes: usize) -> Self
pub fn with_max_bytes(max_bytes: usize) -> Self
Constructs an AssetServer with max_bytes as the soft cap on the combined image + SVG caches.
Self::default() calls this with DEFAULT_MAX_BYTES (256 MiB).
Sourcepub fn register_loader(&mut self, loader: impl AssetLoader)
pub fn register_loader(&mut self, loader: impl AssetLoader)
Teach the pipeline a format. The loader claims the extensions it names, replacing whatever held them before, so an app can override a built-in decoder as well as add one.
From a plugin’s build, prefer register_asset_loader, which
installs the server first if it is not there yet.
Sourcepub fn loaders(&self) -> &AssetLoaders
pub fn loaders(&self) -> &AssetLoaders
The loader registry, for inspecting which loader handles a path.
Sourcepub fn loaders_mut(&mut self) -> &mut AssetLoaders
pub fn loaders_mut(&mut self) -> &mut AssetLoaders
The loader registry, for registering an already shared loader or changing the fallback that handles unclaimed extensions.
Sourcepub fn register_source(&mut self, source: impl AssetSource)
pub fn register_source(&mut self, source: impl AssetSource)
Add a byte source. Sources are consulted in registration order after the bundles; a path none of them claims is read from disk.
Sourcepub fn register_bundle(&mut self, bundle: LumenBundle)
pub fn register_bundle(&mut self, bundle: LumenBundle)
Register a .lpak bundle with the server. Subsequent decode
lookups for lumen://app/<path> URIs route through every
registered bundle in insertion order. Bundles are cheap to
clone (one Arc<[u8]> bump) so the same instance can be
shared with lumen-text-cosmic’s font_db registration pass.
Set Self::set_bundle_root as well to serve plain filesystem
paths (<app_dir>/icons/sun.png) out of the archive.
Sourcepub fn set_bundle_root(&mut self, root: impl Into<PathBuf>)
pub fn set_bundle_root(&mut self, root: impl Into<PathBuf>)
Declare the directory registered bundles were packed from. A lookup for a path under this root is tried against the bundles first, using the remainder of the path as the key; the entry wins over the file on disk, so an app can ship the archive and leave the loose files behind.
Sourcepub fn bundles(&self) -> &[LumenBundle]
pub fn bundles(&self) -> &[LumenBundle]
Iterate the currently registered bundles. Used by the
font-registration helper in lumen-text-cosmic.
Sourcepub fn resolve_uri(&self, uri: &str) -> Option<Vec<u8>>
pub fn resolve_uri(&self, uri: &str) -> Option<Vec<u8>>
Resolve lumen://app/<rel> URI strings to bundled bytes. Returns
None when no bundle satisfies the URI or when the URI uses an
unknown scheme (callers fall back to disk in that case).
Sourcepub fn resolve_bundled(&self, path: &Path) -> Option<Vec<u8>>
pub fn resolve_bundled(&self, path: &Path) -> Option<Vec<u8>>
Resolve an ImageSource-shaped path out of the registered
bundles: either a lumen://app/<key> URI, or a filesystem path
under Self::set_bundle_root whose remainder is the key.
None means “not bundled”, and the caller reads from disk.
Sourcepub fn source_reader(&self) -> SourceReader
pub fn source_reader(&self) -> SourceReader
A SourceReader snapshot of the current source chain, for reading
raw bytes off the main thread. See the type’s docs for the contract;
take a fresh one per request, because a snapshot does not see sources
registered after it.
Sourcepub fn bytes_used(&self) -> usize
pub fn bytes_used(&self) -> usize
Returns the approximate CPU bytes held by the image and SVG content caches. O(1): returns the running counter maintained on insert / evict.
Sourcepub fn max_bytes(&self) -> usize
pub fn max_bytes(&self) -> usize
Returns the current size cap. Inserts that would push bytes_used past this number evict LRU entries
before completing.
Sourcepub fn set_max_bytes(&mut self, max_bytes: usize)
pub fn set_max_bytes(&mut self, max_bytes: usize)
Resets the size cap and immediately evicts down to the new bound.
Sourcepub fn evict_until(&mut self, target_bytes: usize)
pub fn evict_until(&mut self, target_bytes: usize)
Evicts the least-recently-used cached entries until bytes_used <= target_bytes.
Images are evicted before SVGs (image RGBA buffers dominate the budget by an order of magnitude).
Entities holding strong Handle<...> clones keep their decoded data alive via the Arc refcount.
Sourcepub fn bump_request_id(&mut self, entity: Entity) -> u64
pub fn bump_request_id(&mut self, entity: Entity) -> u64
Bumps the per-entity monotonic request id and returns the new value.
The runtime’s ScriptCommand::SetSrc handler (in lumen-runtime) calls this before
re-inserting ImageSource on the entity. Any in-flight decode for the prior path will then be
identified as stale on completion via the snapshot id stored on its waiter entry, and either
dropped from the per-entity insert step (if some other waiter still wants the path) or discarded
entirely (no cache write) if every waiter has moved on.
Skipping this call leaves the stale-decode race in place: the runtime swaps ImageSource while a
decode for the old bytes is in flight, then drain_completed_decodes attaches the old image.
Sourcepub fn current_request_id(&self, entity: Entity) -> u64
pub fn current_request_id(&self, entity: Entity) -> u64
Returns the entity’s current request id (or 0 if it has never been bumped).
Sourcepub fn shutdown(&mut self)
pub fn shutdown(&mut self)
Drains the dispatcher channel, joins every worker, clears all caches, and detaches the watcher. Idempotent - calling shutdown twice is a no-op after the first.
Takes &mut self rather than &self. The audit spec suggested &self for ergonomics; the
in-place mutation of caches + the watcher option + the join-handle vec makes the &mut self
signature the natural choice once interior Mutex-wrapping is avoided. AssetServer is a
Resource, so consumers can reach it via ResMut<AssetServer>::shutdown().
impl Drop for AssetServer calls this automatically, so App tear-down (and any test or
benchmark that builds + drops the server) joins workers cleanly without an explicit shutdown call.
Trait Implementations§
Source§impl Component for AssetServer
impl Component for AssetServer
Source§const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::SparseSet
const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::SparseSet
Source§type Mutability = Mutable
type Mutability = Mutable
Component<Mutability = Mutable>],
while immutable components will instead have [Component<Mutability = Immutable>]. Read moreSource§fn register_required_components(
_requiree: ComponentId,
required_components: &mut RequiredComponentsRegistrator<'_, '_>,
)
fn register_required_components( _requiree: ComponentId, required_components: &mut RequiredComponentsRegistrator<'_, '_>, )
Source§fn clone_behavior() -> ComponentCloneBehavior
fn clone_behavior() -> ComponentCloneBehavior
Source§fn relationship_accessor() -> Option<ComponentRelationshipAccessor<Self>>
fn relationship_accessor() -> Option<ComponentRelationshipAccessor<Self>>
ComponentRelationshipAccessor] required for working with relationships in dynamic contexts. Read more§fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_add [ComponentHook] for this [Component] if one is defined.§fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_insert [ComponentHook] for this [Component] if one is defined.§fn on_discard() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_discard() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_discard [ComponentHook] for this [Component] if one is defined.§fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_remove [ComponentHook] for this [Component] if one is defined.§fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_despawn [ComponentHook] for this [Component] if one is defined.§fn map_entities<E>(_this: &mut Self, _mapper: &mut E)where
E: EntityMapper,
fn map_entities<E>(_this: &mut Self, _mapper: &mut E)where
E: EntityMapper,
EntityMapper]. This is used to remap entities in contexts like scenes and entity cloning.
When deriving [Component], this is populated by annotating fields containing entities with #[entities] Read moreSource§impl Default for AssetServer
impl Default for AssetServer
Source§impl Drop for AssetServer
impl Drop for AssetServer
impl Resource for AssetServer
Auto Trait Implementations§
impl Freeze for AssetServer
impl !RefUnwindSafe for AssetServer
impl Send for AssetServer
impl Sync for AssetServer
impl Unpin for AssetServer
impl UnsafeUnpin for AssetServer
impl !UnwindSafe for AssetServer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<C> Bundle for Cwhere
C: Component,
impl<C> Bundle for Cwhere
C: Component,
fn component_ids( components: &mut ComponentsRegistrator<'_>, ) -> impl Iterator<Item = ComponentId> + use<C>
§fn get_component_ids(
components: &Components,
) -> impl Iterator<Item = Option<ComponentId>>
fn get_component_ids( components: &Components, ) -> impl Iterator<Item = Option<ComponentId>>
Bundle]’s component ids. This will be None if the component has not been registered.§impl<C> BundleFromComponents for Cwhere
C: Component,
impl<C> BundleFromComponents for Cwhere
C: Component,
§impl<C> DynamicBundle for Cwhere
C: Component,
impl<C> DynamicBundle for Cwhere
C: Component,
§unsafe fn get_components(
ptr: MovingPtr<'_, C>,
func: &mut impl FnMut(StorageType, OwningPtr<'_>),
) -> <C as DynamicBundle>::Effect
unsafe fn get_components( ptr: MovingPtr<'_, C>, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect
§unsafe fn apply_effect(
_ptr: MovingPtr<'_, MaybeUninit<C>>,
_entity: &mut EntityWorldMut<'_>,
)
unsafe fn apply_effect( _ptr: MovingPtr<'_, MaybeUninit<C>>, _entity: &mut EntityWorldMut<'_>, )
§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self using default().