asset handles now use uuids instead of ascending ints
This commit is contained in:
		
							parent
							
								
									71a4503df1
								
							
						
					
					
						commit
						24e5238e75
					
				| @ -6,3 +6,5 @@ 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 New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson