Skip to main content

pebble/assets/
handle.rs

1use crate::assets::storage::RawAssetHandle;
2
3/// A typed wrapper around a [`RawAssetHandle`].
4///
5/// `Handle<T>` is cheap to copy and store. It does not keep the underlying
6/// asset alive — the asset lives in [`Assets<T::Source>`](crate::assets::storage::Assets)
7/// and can be removed independently.
8///
9/// `Handle<T>::default()` is the null handle — the same sentinel every
10/// lookup method already treats as "definitely not present" (see
11/// [`Assets::get`](crate::assets::storage::Assets::get)'s null-handle
12/// check), useful as a placeholder before an asset has been inserted.
13pub struct Handle<T> {
14    pub id: RawAssetHandle,
15    // `fn() -> T` rather than `T` directly: this handle never actually
16    // stores a `T`, only a small `Copy` key, so it should be `Send`/`Sync`
17    // regardless of whether `T` is — `PhantomData<T>` would incorrectly tie
18    // those auto-traits (and variance) to `T`.
19    _marker: std::marker::PhantomData<fn() -> T>,
20}
21
22impl<T> Handle<T> {
23    /// Create a new typed handle from a raw slot-map key.
24    pub fn new(id: RawAssetHandle) -> Self {
25        Self {
26            id,
27            _marker: std::marker::PhantomData,
28        }
29    }
30}
31
32impl<T> Clone for Handle<T> {
33    fn clone(&self) -> Self {
34        *self
35    }
36}
37impl<T> Copy for Handle<T> {}
38
39impl<T> Default for Handle<T> {
40    fn default() -> Self {
41        Self::new(RawAssetHandle::default())
42    }
43}
44
45impl<T> PartialEq for Handle<T> {
46    fn eq(&self, other: &Self) -> bool {
47        self.id == other.id
48    }
49}
50impl<T> Eq for Handle<T> {}
51
52impl<T> std::hash::Hash for Handle<T> {
53    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
54        self.id.hash(state);
55    }
56}
57
58impl<T> std::fmt::Debug for Handle<T> {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        f.debug_tuple("Handle").field(&self.id).finish()
61    }
62}