2022-06-20 17:18:58 +00:00
|
|
|
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
2020-10-18 20:48:15 +00:00
|
|
|
use bevy_utils::AHasher;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use std::{
|
|
|
|
borrow::Cow,
|
|
|
|
hash::{Hash, Hasher},
|
|
|
|
path::{Path, PathBuf},
|
|
|
|
};
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// Represents a path to an asset in the file system.
|
2022-10-17 14:01:53 +00:00
|
|
|
#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
|
2020-10-18 20:48:15 +00:00
|
|
|
pub struct AssetPath<'a> {
|
|
|
|
path: Cow<'a, Path>,
|
|
|
|
label: Option<Cow<'a, str>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> AssetPath<'a> {
|
2022-07-12 15:44:09 +00:00
|
|
|
/// Creates a new asset path using borrowed information.
|
2020-10-18 20:48:15 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn new_ref(path: &'a Path, label: Option<&'a str>) -> AssetPath<'a> {
|
|
|
|
AssetPath {
|
|
|
|
path: Cow::Borrowed(path),
|
2021-12-02 23:40:37 +00:00
|
|
|
label: label.map(Cow::Borrowed),
|
2020-10-18 20:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// Creates a new asset path.
|
2020-10-18 20:48:15 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn new(path: PathBuf, label: Option<String>) -> AssetPath<'a> {
|
|
|
|
AssetPath {
|
|
|
|
path: Cow::Owned(path),
|
|
|
|
label: label.map(Cow::Owned),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// Constructs an identifier from this asset path.
|
2020-10-18 20:48:15 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn get_id(&self) -> AssetPathId {
|
|
|
|
AssetPathId::from(self)
|
|
|
|
}
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// Gets the sub-asset label.
|
2020-10-18 20:48:15 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn label(&self) -> Option<&str> {
|
|
|
|
self.label.as_ref().map(|label| label.as_ref())
|
|
|
|
}
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// Gets the path to the asset in the filesystem.
|
2020-10-18 20:48:15 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn path(&self) -> &Path {
|
|
|
|
&self.path
|
|
|
|
}
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// Converts the borrowed path data to owned.
|
2020-10-18 20:48:15 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn to_owned(&self) -> AssetPath<'static> {
|
|
|
|
AssetPath {
|
|
|
|
path: Cow::Owned(self.path.to_path_buf()),
|
|
|
|
label: self
|
|
|
|
.label
|
|
|
|
.as_ref()
|
|
|
|
.map(|value| Cow::Owned(value.to_string())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// An unique identifier to an asset path.
|
2020-10-18 20:48:15 +00:00
|
|
|
#[derive(
|
2020-11-28 00:39:59 +00:00
|
|
|
Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect,
|
2020-10-18 20:48:15 +00:00
|
|
|
)]
|
2020-11-28 00:39:59 +00:00
|
|
|
#[reflect_value(PartialEq, Hash, Serialize, Deserialize)]
|
2020-10-18 20:48:15 +00:00
|
|
|
pub struct AssetPathId(SourcePathId, LabelId);
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// An unique identifier to the source path of an asset.
|
2020-10-18 20:48:15 +00:00
|
|
|
#[derive(
|
2020-11-28 00:39:59 +00:00
|
|
|
Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect,
|
2020-10-18 20:48:15 +00:00
|
|
|
)]
|
2020-11-28 00:39:59 +00:00
|
|
|
#[reflect_value(PartialEq, Hash, Serialize, Deserialize)]
|
2020-10-18 20:48:15 +00:00
|
|
|
pub struct SourcePathId(u64);
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// An unique identifier to a sub-asset label.
|
2020-10-18 20:48:15 +00:00
|
|
|
#[derive(
|
2020-11-28 00:39:59 +00:00
|
|
|
Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect,
|
2020-10-18 20:48:15 +00:00
|
|
|
)]
|
2020-11-28 00:39:59 +00:00
|
|
|
#[reflect_value(PartialEq, Hash, Serialize, Deserialize)]
|
2020-10-18 20:48:15 +00:00
|
|
|
pub struct LabelId(u64);
|
|
|
|
|
|
|
|
impl<'a> From<&'a Path> for SourcePathId {
|
|
|
|
fn from(value: &'a Path) -> Self {
|
|
|
|
let mut hasher = get_hasher();
|
|
|
|
value.hash(&mut hasher);
|
|
|
|
SourcePathId(hasher.finish())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<AssetPathId> for SourcePathId {
|
|
|
|
fn from(id: AssetPathId) -> Self {
|
|
|
|
id.source_path_id()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> From<AssetPath<'a>> for SourcePathId {
|
|
|
|
fn from(path: AssetPath) -> Self {
|
|
|
|
AssetPathId::from(path).source_path_id()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> From<Option<&'a str>> for LabelId {
|
|
|
|
fn from(value: Option<&'a str>) -> Self {
|
|
|
|
let mut hasher = get_hasher();
|
|
|
|
value.hash(&mut hasher);
|
|
|
|
LabelId(hasher.finish())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AssetPathId {
|
2022-07-12 15:44:09 +00:00
|
|
|
/// Gets the id of the source path.
|
2020-10-18 20:48:15 +00:00
|
|
|
pub fn source_path_id(&self) -> SourcePathId {
|
|
|
|
self.0
|
|
|
|
}
|
|
|
|
|
2022-07-12 15:44:09 +00:00
|
|
|
/// Gets the id of the sub-asset label.
|
2020-10-18 20:48:15 +00:00
|
|
|
pub fn label_id(&self) -> LabelId {
|
|
|
|
self.1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// this hasher provides consistent results across runs
|
|
|
|
pub(crate) fn get_hasher() -> AHasher {
|
|
|
|
AHasher::new_with_keys(42, 23)
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T> From<T> for AssetPathId
|
|
|
|
where
|
|
|
|
T: Into<AssetPath<'a>>,
|
|
|
|
{
|
|
|
|
fn from(value: T) -> Self {
|
|
|
|
let asset_path: AssetPath = value.into();
|
|
|
|
AssetPathId(
|
|
|
|
SourcePathId::from(asset_path.path()),
|
|
|
|
LabelId::from(asset_path.label()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'b> From<&'a AssetPath<'b>> for AssetPathId {
|
|
|
|
fn from(asset_path: &'a AssetPath<'b>) -> Self {
|
|
|
|
AssetPathId(
|
|
|
|
SourcePathId::from(asset_path.path()),
|
|
|
|
LabelId::from(asset_path.label()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> From<&'a str> for AssetPath<'a> {
|
|
|
|
fn from(asset_path: &'a str) -> Self {
|
2022-08-18 18:53:09 +00:00
|
|
|
let mut parts = asset_path.splitn(2, '#');
|
2020-12-02 19:31:16 +00:00
|
|
|
let path = Path::new(parts.next().expect("Path must be set."));
|
2020-10-18 20:48:15 +00:00
|
|
|
let label = parts.next();
|
|
|
|
AssetPath {
|
|
|
|
path: Cow::Borrowed(path),
|
2021-12-02 23:40:37 +00:00
|
|
|
label: label.map(Cow::Borrowed),
|
2020-10-18 20:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-09 22:40:15 +00:00
|
|
|
impl<'a> From<&'a String> for AssetPath<'a> {
|
|
|
|
fn from(asset_path: &'a String) -> Self {
|
|
|
|
asset_path.as_str().into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-18 20:48:15 +00:00
|
|
|
impl<'a> From<&'a Path> for AssetPath<'a> {
|
|
|
|
fn from(path: &'a Path) -> Self {
|
|
|
|
AssetPath {
|
|
|
|
path: Cow::Borrowed(path),
|
|
|
|
label: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> From<PathBuf> for AssetPath<'a> {
|
|
|
|
fn from(path: PathBuf) -> Self {
|
|
|
|
AssetPath {
|
|
|
|
path: Cow::Owned(path),
|
|
|
|
label: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|