Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
garyttierney committed Mar 11, 2024
1 parent e2c7029 commit e72c254
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 66 deletions.
120 changes: 119 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ members = [
"crates/formats",
"crates/cli",
"crates/viewer",
"crates/dvdbnd",
"crates/dvdbnd", "crates/asset-server",
]

[workspace.package]
Expand All @@ -51,4 +51,4 @@ fstools_formats = { path = "crates/formats", version = "0.1.0" }
fstools_dvdbnd = { path = "crates/dvdbnd", version = "0.1.0" }
memmap2 = "0.7"
rayon = "1"
thiserror = "1"
thiserror = "1"
15 changes: 15 additions & 0 deletions crates/asset-server/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "fstools_asset_server"
version.workspace = true
license.workspace = true
edition.workspace = true

[dependencies]
bevy_app = "0.13"
bevy_asset = { version = "0.13", features = ["multi-threaded", "asset_processor", "file_watcher"] }
fstools_dvdbnd.workspace = true
fstools_formats.workspace = true
futures-lite = "2"

[lints]
workspace = true
75 changes: 75 additions & 0 deletions crates/asset-server/src/archive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
mod bnd4;

use std::{
collections::{HashMap, HashSet},
path::Path,
};

use bevy_asset::{
io::{AssetReader, AssetReaderError, PathStream, Reader}, BoxedFuture, UntypedHandle,
};
use futures_lite::io::Cursor;

pub struct ArchiveEntry {
data: Vec<u8>,
}

pub struct ArchiveAssetSource {
mounted_archives: HashSet<UntypedHandle>,
entries: HashMap<String, ArchiveEntry>,
}

pub trait IntoArchive {
fn files(&self) -> impl Iterator<Item = (String, Vec<u8>)>;
}

impl ArchiveAssetSource {
pub fn mount<A: IntoArchive>(&mut self, archive: A) {
self.entries.extend(archive.files().map(|(name, data)| {
(
name,
ArchiveEntry {
data,
},
)
}));
}
}

impl AssetReader for ArchiveAssetSource {
fn read<'a>(
&'a self,
path: &'a Path,
) -> BoxedFuture<'a, Result<Box<Reader<'a>>, AssetReaderError>> {
Box::pin(async move {
let data = self
.entries
.get(&path.to_string_lossy().to_string())
.map(|entry| Box::new(Cursor::new(&entry.data )) as Box<Reader<'a>>)
.ok_or_else(|| AssetReaderError::NotFound(path.to_path_buf()))?;

Ok(data)
})
}

fn read_meta<'a>(
&'a self,
path: &'a Path,
) -> BoxedFuture<'a, Result<Box<Reader<'a>>, AssetReaderError>> {
todo!()
}

fn read_directory<'a>(
&'a self,
path: &'a Path,
) -> BoxedFuture<'a, Result<Box<PathStream>, AssetReaderError>> {
todo!()
}

fn is_directory<'a>(
&'a self,
path: &'a Path,
) -> BoxedFuture<'a, Result<bool, AssetReaderError>> {
todo!()
}
}
14 changes: 14 additions & 0 deletions crates/asset-server/src/archive/bnd4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use fstools_formats::bnd4::BND4;

use crate::archive::IntoArchive;

impl IntoArchive for BND4 {
fn files(&self) -> impl Iterator<Item = (String, Vec<u8>)> {
self.files.iter().map(|file| {
let start = file.data_offset as usize;
let size = file.compressed_size as usize;

(file.path.clone(), self.data[start..start + size].to_vec())
})
}
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,27 @@
use std::{
io::{self, Read},
path::Path,
pin::Pin,
sync::Arc,
task::Poll,
};
use std::{io, io::Read, path::Path, pin::Pin, sync::Arc, task::Poll};

use bevy::{
asset::{
io::{AssetReader, AssetReaderError, PathStream, Reader},
BoxedFuture,
},
prelude::{Deref, DerefMut, Resource},
tasks::futures_lite::{io::Cursor, AsyncRead},
use bevy_asset::{
io::{AssetReader, AssetReaderError, PathStream, Reader},
BoxedFuture,
};
use fstools_dvdbnd::{DvdBnd, DvdBndEntryError, DvdBndEntryReader as VfsEntryReaderImpl};
use fstools_dvdbnd::{DvdBnd, DvdBndEntryError, DvdBndEntryReader};
use futures_lite::AsyncRead;

#[derive(Clone, Deref, DerefMut, Resource)]
pub struct VfsAssetRepository(pub(crate) Arc<DvdBnd>);
#[derive(Clone)]
pub struct DvdBndAssetSource(pub(crate) Arc<DvdBnd>);

impl AssetReader for VfsAssetRepository {
impl AssetReader for DvdBndAssetSource {
fn read<'a>(
&'a self,
path: &'a Path,
) -> BoxedFuture<'a, Result<Box<Reader<'a>>, AssetReaderError>> {
Box::pin(async move {
let path_str = path.to_string_lossy();
let dvd_bnd = &self.0;

self.open(&*path_str)
.map(|r| Box::new(VfsEntryReader(r)) as Box<Reader>)
.or_else(|_| {
Ok(self
.open_from_mounts(&path_str)
.map(|r| Box::new(Cursor::new(r)))?)
})
dvd_bnd
.open(&*path_str)
.map(|r| Box::new(AsyncDvdBndEntryReader(r)) as Box<Reader>)
.map_err(|e| match e {
DvdBndEntryError::NotFound => AssetReaderError::NotFound(path.to_path_buf()),
_ => AssetReaderError::Io(Arc::new(io::Error::other(
Expand Down Expand Up @@ -65,9 +53,9 @@ impl AssetReader for VfsAssetRepository {
}
}

struct VfsEntryReader(VfsEntryReaderImpl);
struct AsyncDvdBndEntryReader(DvdBndEntryReader);

impl AsyncRead for VfsEntryReader {
impl AsyncRead for AsyncDvdBndEntryReader {
fn poll_read(
mut self: Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
Expand Down
Loading

0 comments on commit e72c254

Please sign in to comment.