example/docs

This commit is contained in:
Robin Appelman 2024-08-30 22:54:48 +02:00
commit e38ce5b316
5 changed files with 53 additions and 1 deletions

View file

@ -49,6 +49,8 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Check semver - name: Check semver
uses: obi1kenobi/cargo-semver-checks-action@v2 uses: obi1kenobi/cargo-semver-checks-action@v2
with:
feature-group: all-features
msrv: msrv:
runs-on: ubuntu-latest runs-on: ubuntu-latest

10
README.md Normal file
View file

@ -0,0 +1,10 @@
# tf-asset-loader
Utility for loading assets from tf2 data files.
Supports loading assets like models and textures from the tf2 data directory. The tf2 data directory should be
automatically detected when installed to steam, or you can use the `TF_DIR` environment variable to overwrite the data
directory.
Supports loading both plain file data and data embedded in `vpk` files.

9
examples/open.rs Normal file
View file

@ -0,0 +1,9 @@
use tf_asset_loader::{Loader, LoaderError};
fn main() -> Result<(), LoaderError> {
let loader = Loader::new()?;
if let Some(model) = loader.load("models/props_gameplay/resupply_locker.mdl")? {
println!("resupply_locker.mdl is {} bytes large", model.len());
}
Ok(())
}

View file

@ -1,3 +1,22 @@
//! Utility for loading assets from tf2 data files.
//!
//! Supports loading assets like models and textures from the tf2 data directory. The tf2 data directory should be
//! automatically detected when installed to steam, or you can use the `TF_DIR` environment variable to overwrite the data
//! directory.
//!
//! Supports loading both plain file data and data embedded in `vpk` files.
//! ```rust,dont-run
//! # use tf_asset_loader::{Loader, LoaderError};
//! #
//! fn main() -> Result<(), LoaderError> {
//! let loader = Loader::new()?;
//! if let Some(model) = loader.load("models/props_gameplay/resupply_locker.mdl")? {
//! println!("resupply_locker.mdl is {} bytes large", model.len());
//! }
//! Ok(())
//! }
//! ```
pub mod source; pub mod source;
pub use source::AssetSource; pub use source::AssetSource;
@ -35,6 +54,7 @@ impl From<BspError> for LoaderError {
} }
} }
/// The tf2 asset loader instance
#[derive(Clone)] #[derive(Clone)]
pub struct Loader { pub struct Loader {
sources: Vec<Arc<dyn AssetSource + Send + Sync>>, sources: Vec<Arc<dyn AssetSource + Send + Sync>>,
@ -49,7 +69,7 @@ impl Debug for Loader {
} }
impl Loader { impl Loader {
/// Create the loader /// Create the loader, either auto-detecting the tf2 directory or from the `TF_DIR` environment variable.
pub fn new() -> Result<Self, LoaderError> { pub fn new() -> Result<Self, LoaderError> {
let tf2_dir = tf2_path()?; let tf2_dir = tf2_path()?;
@ -89,10 +109,14 @@ impl Loader {
Ok(Loader { sources }) Ok(Loader { sources })
} }
/// Add a new source to the loader.
///
/// This is intended to be used to add data from bsp files
pub fn add_source<S: AssetSource + Send + Sync + 'static>(&mut self, source: S) { pub fn add_source<S: AssetSource + Send + Sync + 'static>(&mut self, source: S) {
self.sources.push(Arc::new(source)) self.sources.push(Arc::new(source))
} }
/// Check if a file by path exists.
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
pub fn exists(&self, name: &str) -> Result<bool, LoaderError> { pub fn exists(&self, name: &str) -> Result<bool, LoaderError> {
for source in self.sources.iter() { for source in self.sources.iter() {
@ -103,6 +127,9 @@ impl Loader {
Ok(false) Ok(false)
} }
/// Load a file by path.
///
/// Returns the file data as `Vec<u8>` or `None` if the path doesn't exist.
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
pub fn load(&self, name: &str) -> Result<Option<Vec<u8>>, LoaderError> { pub fn load(&self, name: &str) -> Result<Option<Vec<u8>>, LoaderError> {
for source in self.sources.iter() { for source in self.sources.iter() {
@ -113,6 +140,7 @@ impl Loader {
Ok(None) Ok(None)
} }
/// Look for a file by name in one or more paths
pub fn find_in_paths(&self, name: &str, paths: &[String]) -> Option<String> { pub fn find_in_paths(&self, name: &str, paths: &[String]) -> Option<String> {
for path in paths { for path in paths {
let full_path = format!("{}{}", path, name); let full_path = format!("{}{}", path, name);

View file

@ -3,9 +3,12 @@ use std::fs::read;
use std::io::ErrorKind; use std::io::ErrorKind;
use std::path::PathBuf; use std::path::PathBuf;
/// Trait for the various sources that assets can be loaded from
pub trait AssetSource { pub trait AssetSource {
/// Check if a path exists in the source
fn has(&self, path: &str) -> Result<bool, LoaderError>; fn has(&self, path: &str) -> Result<bool, LoaderError>;
/// Load an asset from the source by path if it exists
fn load(&self, path: &str) -> Result<Option<Vec<u8>>, LoaderError>; fn load(&self, path: &str) -> Result<Option<Vec<u8>>, LoaderError>;
} }