1use std::any::TypeId;
4use std::fmt::Debug;
5use std::hash::{Hash, Hasher};
6use std::sync::Arc;
7
8use crate::asset::FullAssetKey;
9
10pub trait Key: Hash + Eq + Clone + Send + Sync + Debug + 'static {}
14
15impl<T> Key for T where T: Hash + Eq + Clone + Send + Sync + Debug + 'static {}
17
18struct AssetKeyMarker;
20
21struct QuerySetMarker;
23
24struct AssetKeySetMarker;
26
27#[derive(Clone)]
35pub struct FullCacheKey {
36 query_type: TypeId,
38 key_hash: u64,
40 debug_repr: Arc<str>,
42}
43
44impl FullCacheKey {
45 pub fn new<Q: 'static, K: Key>(key: &K) -> Self {
47 let mut hasher = ahash::AHasher::default();
48 key.hash(&mut hasher);
49 let key_hash = hasher.finish();
50
51 Self {
52 query_type: TypeId::of::<Q>(),
53 key_hash,
54 debug_repr: Arc::from(format!("{}({:?})", std::any::type_name::<Q>(), key)),
55 }
56 }
57
58 pub(crate) fn from_asset_key(asset_key: &FullAssetKey) -> Self {
63 let mut hasher = ahash::AHasher::default();
65 asset_key.key_type().hash(&mut hasher);
66 asset_key.key_hash().hash(&mut hasher);
67 let key_hash = hasher.finish();
68
69 Self {
70 query_type: TypeId::of::<AssetKeyMarker>(),
71 key_hash,
72 debug_repr: Arc::from(asset_key.debug_repr()),
73 }
74 }
75
76 pub fn debug_repr(&self) -> &str {
78 &self.debug_repr
79 }
80
81 pub fn query_set_sentinel<Q: 'static>() -> Self {
86 let mut hasher = ahash::AHasher::default();
87 TypeId::of::<Q>().hash(&mut hasher);
88 let type_hash = hasher.finish();
89
90 Self {
91 query_type: TypeId::of::<QuerySetMarker>(),
92 key_hash: type_hash,
93 debug_repr: Arc::from(format!("QuerySet<{}>", std::any::type_name::<Q>())),
94 }
95 }
96
97 pub fn asset_key_set_sentinel<K: 'static>() -> Self {
102 let mut hasher = ahash::AHasher::default();
103 TypeId::of::<K>().hash(&mut hasher);
104 let type_hash = hasher.finish();
105
106 Self {
107 query_type: TypeId::of::<AssetKeySetMarker>(),
108 key_hash: type_hash,
109 debug_repr: Arc::from(format!("AssetKeySet<{}>", std::any::type_name::<K>())),
110 }
111 }
112}
113
114impl Debug for FullCacheKey {
115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 write!(f, "{}", self.debug_repr)
117 }
118}
119
120impl Hash for FullCacheKey {
121 fn hash<H: Hasher>(&self, state: &mut H) {
122 self.query_type.hash(state);
123 self.key_hash.hash(state);
124 }
125}
126
127impl PartialEq for FullCacheKey {
128 fn eq(&self, other: &Self) -> bool {
129 self.query_type == other.query_type && self.key_hash == other.key_hash
130 }
131}
132
133impl Eq for FullCacheKey {}