Crate micro_games_macros

source ·
Expand description

A collection of complimentary utility macros for building games

Use the [asset_system] macro to create a set of types that manage loading assets, and then derive JsonLoader for any asset type to create a flexible resource loader that links in to the generated asset system

use bevy::prelude::{App, DefaultPlugins, Image, Plugin, Res, ResMut, Resource, Assets, Asset, TextureAtlasLayout};
use bevy::reflect::{TypePath};
use micro_games_macros::{asset_system, JsonLoader};
use serde::{Deserialize, Serialize};

// We can customise the properties on the "asset loader" type that the
// macro generates by adding "loader_property" annotations. The parameter
// to this macro is simple any property declaration that could be added to
// a regular type that derives SystemParam (including lifetimes)

#[asset_system]
#[loader_property(pub sheets: ResMut<'w, Assets<TextureAtlasLayout>>)]
pub struct AssetHandles {
    // For non-JsonLoader assets, you just need to specify a name -> AssetType property.
    // The generated asset handles type will contain a hashmap of name -> Handle<AssetType>
    // under the property name specified. Loading functions such as load_asset_name will
    // be created on the loading type, where the first parameter is the path and the second
    // parameter is the asset name that will be used in the hashmap for later retrieval of
    // the asset
    images: Image,
    // To use an asset_system with a JsonLoader, you will need to add entries for both the
    // asset itself and its index type (generated by JsonLoader). Specific instances of
    // an asset are stored under the Item type (no suffix), keyed in the handle map by their
    // ID property. The index generated from each file (a map of ID -> Item) is stored under
    // the Index type (type name: AssetName + Index), keyed by the name provided when loading
    // the asset
    some_resource: MyCoolResource,
    // The property names generate load functions, but don't have to match the name of the
    // resource being loaded. Index & Item types for a JsonLoader resource can have their
    // names specified as part of the JsonLoader derive
    some_index_of_resources: MyCoolResourceIndex,
}

#[derive(JsonLoader, TypePath, Serialize, Deserialize, Asset)]
#[loader(extension = "mcr", uuid = "00000000-0000-0000-0000-000000000000",
     asset_name = some_resource, index_name = some_index_of_resources)]
pub struct MyCoolResource {
    // You must include exactly one of either a property named "id", or another property annotated
    // with the "asset_id" attribute.
    #[asset_id]
    some_identifier: String,
    foo: usize,
    bar: bool,
}

// The asset system generates a system param for scheduling the load of an asset. It uses bevy's
// asset server, which makes the system compatible with plugins such as bevy_embedded_assets
pub fn loading_system(mut loader: AssetHandlesLoader) {
    // The loader contains a number of functions for loading either individual assets
    // (two parameters, path and id), or a series of assets (a single parameter, a vector
    // of tuples each denoting path and id)
    loader.load_images("path/to/my_image.png", "my_image");

    // JsonLoader assets require the use of the Index type to correctly load them, even for
    // files that only contain one object instance. The identifier (either id or asset_id)
    // will be used to add each instance of an asset to the Item type map
    loader.load_some_index_of_resources("path/to/my_asset.mcr", "my_asset");
}

pub fn use_asset_system(assets: Res<AssetHandles>) {
    // JsonLoader assets can be accessed through the item type functions. These functions
    // provide a weak handle to the asset, meaning that the assets will usually unload
    // if removed from the AssetHandles type unless another strong handle was created externally
    let some_resource_handle = assets.some_resource("the_asset_id");

    // The handle functions exactly match the name of the asset property in the originally
    // defined struct
    let image_handle = assets.images("my_image");
}

pub struct AssetSystemPlugin;
impl Plugin for AssetSystemPlugin {
    fn build(&self, app: &mut App) {
        app.init_resource::<AssetHandles>()
            // JsonLoader will create a plugin that wraps all of the functionality for a single
            // asset type, including loaders and hot reload support
            .add_plugins(MyCoolResourcePlugin);
    }
}

fn main() {
    let app = App::new()
        .add_plugins((DefaultPlugins, AssetSystemPlugin));
}

Attribute Macros§

Derive Macros§

  • Derive std::convert::From for single property tuple or named struct types
  • Generate loader and handler implementations for keyed JSON resources. The asset must implement bevy::asset::Asset, as well as serde::Deserialize and serde::Serialize