Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion benches/benches/bevy_render/extract_render_asset.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use bevy_app::{App, AppLabel};
use bevy_asset::{Asset, AssetApp, AssetEvent, AssetId, Assets, RenderAssetUsages};
use bevy_asset::{
Asset, AssetApp, AssetEvent, AssetId, Assets, EmptyRetainedAsset, RenderAssetUsages,
};
use bevy_ecs::prelude::*;
use bevy_reflect::TypePath;
use bevy_render::{
Expand All @@ -17,12 +19,17 @@ struct DummyRenderAsset;

impl RenderAsset for DummyRenderAsset {
type SourceAsset = DummyAsset;
type RetainedAsset = EmptyRetainedAsset;
type Param = ();

fn asset_usage(_: &Self::SourceAsset) -> RenderAssetUsages {
RenderAssetUsages::RENDER_WORLD
}

fn retain_main_world_asset(_source: &Self::SourceAsset) -> Self::RetainedAsset {
EmptyRetainedAsset
}

fn prepare_asset(
_source_asset: Self::SourceAsset,
_asset_id: AssetId<Self::SourceAsset>,
Expand Down
49 changes: 47 additions & 2 deletions crates/bevy_asset/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,38 @@ pub(crate) fn bevy_asset_path() -> Path {
BevyManifest::shared(|manifest| manifest.get_path("bevy_asset"))
}

const ASSET_ATTRIBUTE: &str = "asset";
const DEPENDENCY_ATTRIBUTE: &str = "dependency";

mod kw {
syn::custom_keyword!(extractable);
}

struct AssetAttributes {
extractable: bool,
}

impl syn::parse::Parse for AssetAttributes {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut extractable: bool = false;

while !input.is_empty() {
let lookahead = input.lookahead1();
if lookahead.peek(kw::extractable) {
input.parse::<kw::extractable>()?;
extractable = true;
} else {
return Err(lookahead.error());
}
}
Ok(AssetAttributes { extractable })
}
}

/// Implement the `Asset` trait.
#[proc_macro_derive(Asset, attributes(dependency))]
///
/// Add `#[asset(extractable)]` to make the asset stored in `Extracable<T>`.
#[proc_macro_derive(Asset, attributes(dependency, asset))]
pub fn derive_asset(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let bevy_asset_path: Path = bevy_asset_path();
Expand All @@ -26,8 +54,25 @@ pub fn derive_asset(input: TokenStream) -> TokenStream {
Err(err) => return err.into_compile_error().into(),
};

let mut storage_type = quote! {
type Storage = #struct_name #type_generics;
};
if let Some(attr) = ast
.attrs
.iter()
.find(|attr| attr.path().is_ident(ASSET_ATTRIBUTE))
&& let Ok(attr) = attr.parse_args::<AssetAttributes>()
&& attr.extractable
{
storage_type = quote! {
type Storage = #bevy_asset_path::Extractable<#struct_name #type_generics>;
};
}

TokenStream::from(quote! {
impl #impl_generics #bevy_asset_path::Asset for #struct_name #type_generics #where_clause { }
impl #impl_generics #bevy_asset_path::Asset for #struct_name #type_generics #where_clause {
#storage_type
}
#dependency_visitor
})
}
Expand Down
Loading