mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 22:20:20 +00:00
asset handles now use uuids instead of ascending ints
This commit is contained in:
parent
71a4503df1
commit
24e5238e75
4 changed files with 137 additions and 124 deletions
|
@ -5,4 +5,6 @@ authors = ["Carter Anderson <mcanders1@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy_core = { path = "../bevy_core" }
|
bevy_core = { path = "../bevy_core" }
|
||||||
|
|
||||||
|
uuid = { version = "0.8", features = ["v4"] }
|
118
crates/bevy_asset/src/handle.rs
Normal file
118
crates/bevy_asset/src/handle.rs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
use std::{
|
||||||
|
fmt::Debug,
|
||||||
|
hash::{Hash, Hasher},
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::{any::TypeId, marker::PhantomData};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
|
pub struct HandleId(Uuid);
|
||||||
|
pub const DEFAULT_HANDLE_ID: HandleId = HandleId(Uuid::from_bytes([
|
||||||
|
238, 232, 56, 216, 245, 246, 77, 29, 165, 188, 211, 202, 249, 248, 15, 4,
|
||||||
|
]));
|
||||||
|
|
||||||
|
impl HandleId {
|
||||||
|
pub fn new() -> HandleId {
|
||||||
|
HandleId(Uuid::new_v4())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Handle<T> {
|
||||||
|
pub id: HandleId,
|
||||||
|
marker: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Handle<T> {
|
||||||
|
pub fn new(id: HandleId) -> Self {
|
||||||
|
Handle {
|
||||||
|
id,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_untyped(untyped_handle: HandleUntyped) -> Option<Handle<T>>
|
||||||
|
where
|
||||||
|
T: 'static,
|
||||||
|
{
|
||||||
|
if TypeId::of::<T>() == untyped_handle.type_id {
|
||||||
|
Some(Handle::new(untyped_handle.id))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Hash for Handle<T> {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.id.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PartialEq for Handle<T> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.id == other.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Eq for Handle<T> {}
|
||||||
|
|
||||||
|
impl<T> Debug for Handle<T> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||||
|
let name = std::any::type_name::<T>().split("::").last().unwrap();
|
||||||
|
write!(f, "Handle<{}>({:?})", name, self.id.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Default for Handle<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Handle {
|
||||||
|
id: DEFAULT_HANDLE_ID,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Clone for Handle<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Handle {
|
||||||
|
id: self.id.clone(),
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T> Copy for Handle<T> {}
|
||||||
|
|
||||||
|
#[derive(Hash, Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
|
pub struct HandleUntyped {
|
||||||
|
pub id: HandleId,
|
||||||
|
pub type_id: TypeId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HandleUntyped {
|
||||||
|
pub fn is_handle<T: 'static>(untyped: &HandleUntyped) -> bool {
|
||||||
|
TypeId::of::<T>() == untyped.type_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<Handle<T>> for HandleUntyped
|
||||||
|
where
|
||||||
|
T: 'static,
|
||||||
|
{
|
||||||
|
fn from(handle: Handle<T>) -> Self {
|
||||||
|
HandleUntyped {
|
||||||
|
id: handle.id,
|
||||||
|
type_id: TypeId::of::<T>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<HandleUntyped> for Handle<T>
|
||||||
|
where
|
||||||
|
T: 'static,
|
||||||
|
{
|
||||||
|
fn from(handle: HandleUntyped) -> Self {
|
||||||
|
Handle::from_untyped(handle)
|
||||||
|
.expect("attempted to convert untyped handle to incorrect typed handle")
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,113 +1,8 @@
|
||||||
|
mod handle;
|
||||||
|
pub use handle::*;
|
||||||
|
|
||||||
use bevy_core::bytes::GetBytes;
|
use bevy_core::bytes::GetBytes;
|
||||||
use std::{
|
use std::collections::HashMap;
|
||||||
fmt::Debug,
|
|
||||||
hash::{Hash, Hasher},
|
|
||||||
};
|
|
||||||
|
|
||||||
use std::{any::TypeId, collections::HashMap, marker::PhantomData};
|
|
||||||
|
|
||||||
// TODO: move these types to their own files
|
|
||||||
pub type HandleId = usize;
|
|
||||||
pub const DEFAULT_HANDLE_ID: HandleId = 0;
|
|
||||||
|
|
||||||
pub struct Handle<T> {
|
|
||||||
pub id: HandleId,
|
|
||||||
marker: PhantomData<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Handle<T> {
|
|
||||||
pub fn new(id: HandleId) -> Self {
|
|
||||||
Handle {
|
|
||||||
id,
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_untyped(untyped_handle: HandleUntyped) -> Option<Handle<T>>
|
|
||||||
where
|
|
||||||
T: 'static,
|
|
||||||
{
|
|
||||||
if TypeId::of::<T>() == untyped_handle.type_id {
|
|
||||||
Some(Handle::new(untyped_handle.id))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Hash for Handle<T> {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
self.id.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PartialEq for Handle<T> {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.id == other.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Eq for Handle<T> {}
|
|
||||||
|
|
||||||
impl<T> Debug for Handle<T> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
|
||||||
let name = std::any::type_name::<T>().split("::").last().unwrap();
|
|
||||||
write!(f, "Handle<{}>({})", name, self.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Default for Handle<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Handle {
|
|
||||||
id: DEFAULT_HANDLE_ID,
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Copy for Handle<T> {}
|
|
||||||
impl<T> Clone for Handle<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Handle {
|
|
||||||
id: self.id.clone(),
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Hash, Copy, Clone, Eq, PartialEq, Debug)]
|
|
||||||
pub struct HandleUntyped {
|
|
||||||
pub id: HandleId,
|
|
||||||
pub type_id: TypeId,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HandleUntyped {
|
|
||||||
pub fn is_handle<T: 'static>(untyped: &HandleUntyped) -> bool {
|
|
||||||
TypeId::of::<T>() == untyped.type_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> From<Handle<T>> for HandleUntyped
|
|
||||||
where
|
|
||||||
T: 'static,
|
|
||||||
{
|
|
||||||
fn from(handle: Handle<T>) -> Self {
|
|
||||||
HandleUntyped {
|
|
||||||
id: handle.id,
|
|
||||||
type_id: TypeId::of::<T>(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> From<HandleUntyped> for Handle<T>
|
|
||||||
where
|
|
||||||
T: 'static,
|
|
||||||
{
|
|
||||||
fn from(handle: HandleUntyped) -> Self {
|
|
||||||
Handle::from_untyped(handle)
|
|
||||||
.expect("attempted to convert untyped handle to incorrect typed handle")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Asset<D> {
|
pub trait Asset<D> {
|
||||||
fn load(descriptor: D) -> Self;
|
fn load(descriptor: D) -> Self;
|
||||||
|
@ -116,7 +11,6 @@ pub trait Asset<D> {
|
||||||
pub struct AssetStorage<T> {
|
pub struct AssetStorage<T> {
|
||||||
assets: HashMap<HandleId, T>,
|
assets: HashMap<HandleId, T>,
|
||||||
names: HashMap<String, Handle<T>>,
|
names: HashMap<String, Handle<T>>,
|
||||||
current_index: HandleId,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AssetStorage<T> {
|
impl<T> AssetStorage<T> {
|
||||||
|
@ -124,7 +18,6 @@ impl<T> AssetStorage<T> {
|
||||||
AssetStorage {
|
AssetStorage {
|
||||||
assets: HashMap::new(),
|
assets: HashMap::new(),
|
||||||
names: HashMap::new(),
|
names: HashMap::new(),
|
||||||
current_index: DEFAULT_HANDLE_ID + 1, // ensure we don't start on the default handle id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,13 +26,13 @@ impl<T> AssetStorage<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, asset: T) -> Handle<T> {
|
pub fn add(&mut self, asset: T) -> Handle<T> {
|
||||||
let id = self.current_index;
|
let id = HandleId::new();
|
||||||
self.current_index += 1;
|
|
||||||
self.assets.insert(id, asset);
|
self.assets.insert(id, asset);
|
||||||
Handle {
|
Handle::new(id)
|
||||||
id,
|
}
|
||||||
marker: PhantomData,
|
|
||||||
}
|
pub fn add_with_handle(&mut self, handle: Handle<T>, asset: T) {
|
||||||
|
self.assets.insert(handle.id, asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_default(&mut self, asset: T) -> Handle<T> {
|
pub fn add_default(&mut self, asset: T) -> Handle<T> {
|
||||||
|
|
|
@ -154,7 +154,7 @@ where
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Batch, BatchKey, Batcher};
|
use super::{Batch, BatchKey, Batcher};
|
||||||
use bevy_asset::{Handle, HandleUntyped};
|
use bevy_asset::{Handle, HandleUntyped, HandleId};
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
struct A;
|
struct A;
|
||||||
|
@ -177,12 +177,12 @@ mod tests {
|
||||||
let e2 = Entity(2);
|
let e2 = Entity(2);
|
||||||
let e3 = Entity(3);
|
let e3 = Entity(3);
|
||||||
|
|
||||||
let a1: HandleUntyped = Handle::<A>::new(1).into();
|
let a1: HandleUntyped = Handle::<A>::new(HandleId::new()).into();
|
||||||
let b1: HandleUntyped = Handle::<B>::new(1).into();
|
let b1: HandleUntyped = Handle::<B>::new(HandleId::new()).into();
|
||||||
let c1: HandleUntyped = Handle::<C>::new(1).into();
|
let c1: HandleUntyped = Handle::<C>::new(HandleId::new()).into();
|
||||||
|
|
||||||
let a2: HandleUntyped = Handle::<A>::new(2).into();
|
let a2: HandleUntyped = Handle::<A>::new(HandleId::new()).into();
|
||||||
let b2: HandleUntyped = Handle::<B>::new(2).into();
|
let b2: HandleUntyped = Handle::<B>::new(HandleId::new()).into();
|
||||||
|
|
||||||
let a1_b1 = BatchKey::key2(a1, b1);
|
let a1_b1 = BatchKey::key2(a1, b1);
|
||||||
let a2_b2 = BatchKey::key2(a2, b2);
|
let a2_b2 = BatchKey::key2(a2, b2);
|
||||||
|
|
Loading…
Reference in a new issue