Skip to main content

limnus_assets/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/limnus
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5pub mod prelude;
6
7use crate::prelude::*;
8use limnus_resource::prelude::*;
9use sparse_slot::SparseSlot;
10use std::fmt::{Debug, Formatter};
11use tracing::{debug, trace};
12
13#[derive(Resource)]
14pub struct Assets<A: Asset> {
15    storage: SparseSlot<A>,
16}
17
18impl<A: Asset> Debug for Assets<A> {
19    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
20        write!(f, "Assets capacity: {}", self.storage.len())
21    }
22}
23
24impl<A: Asset> Default for Assets<A> {
25    fn default() -> Self {
26        Self {
27            storage: SparseSlot::<A>::new(1024),
28        }
29    }
30}
31
32impl<A: Asset> Assets<A> {
33    #[must_use]
34    pub fn new(capacity: usize) -> Self {
35        Self {
36            storage: SparseSlot::new(capacity),
37        }
38    }
39
40    /// # Panics
41    pub fn set(&mut self, id: &Id<A>, asset: A) {
42        debug!(id=%id,asset=?asset, "set");
43        self.storage
44            .try_set(to_slot_map_id(id), asset)
45            .expect("internal error");
46    }
47
48    pub fn set_raw(&mut self, id: RawWeakId, asset: A) {
49        debug!(id=%id,asset=?asset, "set_raw");
50        self.storage
51            .try_set(to_slot_map_id_from_raw(id), asset)
52            .expect("internal error");
53    }
54
55    pub fn remove(&mut self, id: &Id<A>) {
56        trace!(id=%id, "remove");
57        self.storage.remove(to_slot_map_id(id));
58    }
59
60    #[must_use]
61    pub fn get(&self, id: &Id<A>) -> Option<&A> {
62        //     trace!(id=%id, "get");
63        self.storage.get(to_slot_map_id(id))
64    }
65
66    #[must_use]
67    pub fn get_weak(&self, weak_id: WeakId<A>) -> Option<&A> {
68        //      trace!(id=%weak_id, "get_weak");
69        self.storage.get(to_slot_map_id_from_weak(weak_id))
70    }
71
72    /// # Panics
73    /// if id is missing
74    #[must_use]
75    pub fn fetch(&self, id: &Id<A>) -> &A {
76        //        trace!(id=%id, "fetch asset");
77        self.storage.get(to_slot_map_id(id)).unwrap()
78    }
79
80    #[must_use]
81    pub fn get_mut(&mut self, id: &Id<A>) -> Option<&mut A> {
82        //      trace!(id=%id, "get_mut asset");
83        self.storage.get_mut(to_slot_map_id(id))
84    }
85
86    #[must_use]
87    pub fn contains(&self, id: &Id<A>) -> bool {
88        //    trace!(id=%id, "contains");
89        self.get(id).is_some()
90    }
91
92    // TODO:
93    /*
94        pub fn iter(&self) -> impl Iterator<Item=(Id<A>, &A)> {
95            self.storage.iter().map(|(id, asset)| {
96                (
97                    Id {
98                        raw_id: RawAssetId {
99                            generation: id.generation,
100                            index: id.index as u16,
101                        },
102
103                        _phantom_data: PhantomData,
104                    },
105                    asset,
106                )
107            })
108        }
109    */
110    #[must_use]
111    pub fn len(&self) -> usize {
112        self.storage.len()
113    }
114
115    #[must_use]
116    pub fn is_empty(&self) -> bool {
117        self.storage.is_empty()
118    }
119}
120
121fn to_slot_map_id<A: Asset>(typed_id: &Id<A>) -> sparse_slot::Id {
122    let raw_id_type: RawWeakId = typed_id.into();
123
124    to_slot_map_id_from_raw(raw_id_type)
125}
126
127fn to_slot_map_id_from_weak<A: Asset>(raw_id_type: WeakId<A>) -> sparse_slot::Id {
128    let raw_id: RawWeakId = raw_id_type.into();
129
130    to_slot_map_id_from_raw(raw_id)
131}
132
133fn to_slot_map_id_from_raw(raw_id_type: RawWeakId) -> sparse_slot::Id {
134    let raw_id: RawAssetId = raw_id_type.into();
135
136    sparse_slot::Id::new(raw_id.index as usize, raw_id.generation)
137}