1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
//! Conveniently load, store and cache external resources. //! //! //! It has multiple goals //! - Easy to use: Rusty API //! - Light: Pay for what you take, no dependencies bloat //! - Fast: Share your resources between threads without using expensive `Arc::clone` //! //! ## Cargo features //! //! No features are enabled by default. //! //! ### Additionnal loaders //! - `bincode`: Bincode deserialization //! - `cbor`: CBOR deserialization //! - `json`: JSON deserialization //! - `msgpack`: MessagePack deserialization //! - `ron`: RON deserialization //! - `toml`: TOML deserialization //! - `yaml`: YAML deserialization //! //! ### Internal features //! //! These features change inner data structures implementations. //! //! - `hashbrown`: Use *hashbrown* crate's HashMap //! - `parking_lot`: Use *parking_lot* crate's synchronisation primitives //! //! ## Example //! //! If the file `assets/common/position.ron` contains this: //! //! ```text //! Point( //! x: 5, //! y: -6, //! ) //! ``` //! //! Then you can load it this way (with feature `ron` enabled): //! //! ``` //! # cfg_if::cfg_if! { if #[cfg(feature = "ron")] { //! use assets_manager::{Asset, AssetCache, loader}; //! use serde::Deserialize; //! //! // The struct you want to load //! #[derive(Deserialize)] //! struct Point { //! x: i32, //! y: i32, //! } //! //! // Specify how you want the structure to be loaded //! impl Asset for Point { //! // The extension of the files to look into //! const EXT: &'static str = "ron"; //! //! // The serialization format //! type Loader = loader::RonLoader; //! } //! //! //! // Create a new cache to load assets under the "./assets" folder //! let cache = AssetCache::new("assets"); //! //! // Get a lock on the asset //! let asset_lock = cache.load::<Point>("common.position")?; //! //! // Lock the asset for reading //! // Any number of read locks can exist at the same time, //! // but none can exist when the asset is reloaded //! let point = asset_lock.read(); //! //! // The asset is now ready to be used //! assert_eq!(point.x, 5); //! assert_eq!(point.y, -6); //! //! // Loading the same asset retreives it from the cache //! let other_lock = cache.load("common.position")?; //! assert!(asset_lock.ptr_eq(&other_lock)); //! //! # }} //! # Ok::<(), assets_manager::AssetError>(()) //! ``` #![doc(html_root_url = "https://docs.rs/assets_manager/0.1")] #![warn( missing_docs, missing_debug_implementations, )] mod cache; #[doc(inline)] pub use cache::AssetCache; pub mod loader; #[doc(inline)] pub use loader::Loader; mod lock; #[doc(inline)] pub use lock::{AssetRefLock, AssetRef}; mod error; #[doc(inline)] pub use error::AssetError; #[cfg(test)] mod tests; /// An asset is a type loadable from a file. /// /// `Asset`s can loaded and retreived by an [`AssetCache`]. /// /// ## Example /// /// Suppose you make a physics simulutation, and you positions and speeds in /// a Bincode-encoded files, with extension ".data" /// /// ```no_run /// # cfg_if::cfg_if! { if #[cfg(feature = "bincode")] { /// use assets_manager::{Asset, loader}; /// use serde::Deserialize; /// /// #[derive(Deserialize)] /// struct Vector { /// x: f32, /// y: f32, /// z: f32, /// } /// /// #[derive(Deserialize)] /// struct World { /// pos: Vec<Vector>, /// speed: Vec<Vector>, /// } /// /// impl Asset for World { /// const EXT: &'static str = "data"; /// type Loader = loader::BincodeLoader; /// } /// # }} /// ``` /// [`AssetCache`]: struct.AssetCache.html pub trait Asset: Sized + Send + Sync + 'static { /// The extension used by the asset files from the given asset type. /// /// Use `""` for no extension. const EXT: &'static str; /// Specifies a way to to convert raw bytes into the asset. /// /// See module [`loader`] for implementations of common conversions. /// /// [`loader`]: loader/index.html type Loader: Loader<Self>; /// Create an asset value from raw parts. /// /// This function is not meant to be used directly, but rather to /// be overriden if you don't want or need to implement [`Loader`]. /// In that case, you should use [`CustomLoader`] as [`Loader`] /// /// [`Loader`]: loader/trait.Loader.html /// [`CustomLoader`]: loader/struct.CustomLoader.html #[inline] fn load_from_raw(content: Vec<u8>) -> Result<Self, AssetError> { Self::Loader::load(content).map_err(|e| AssetError::LoadError(e)) } }