viewport_lib/resources/scivis/curve_store.rs
1//! Slot-based storage for pre-uploaded curve GPU data.
2//!
3//! Each store holds GPU data produced by the per-frame upload helpers, keyed
4//! by a typed handle. Per-frame ref items (`PolylineRefItem` and friends) name
5//! a store entry by handle and supply per-frame overrides (model matrix, etc.)
6//! instead of resubmitting the geometry every frame.
7
8use crate::resources::{
9 GlyphGpuData, PointCloudGpuData, PolylineGpuData, SpriteGpuData, StreamtubeGpuData,
10 TensorGlyphGpuData,
11};
12
13macro_rules! curve_store {
14 ($(#[$id_doc:meta])* $id:ident, $store:ident, $data:ty) => {
15 $(#[$id_doc])*
16 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17 pub struct $id(pub(crate) usize);
18
19 impl $id {
20 /// Build an id from a raw slot index.
21 pub fn from_index(index: usize) -> Self { Self(index) }
22 /// The raw slot index.
23 pub fn index(&self) -> usize { self.0 }
24 }
25
26 pub(crate) struct $store {
27 slots: Vec<Option<$data>>,
28 free_list: Vec<usize>,
29 }
30
31 impl $store {
32 pub fn new() -> Self {
33 Self { slots: Vec::new(), free_list: Vec::new() }
34 }
35
36 pub fn insert(&mut self, data: $data) -> $id {
37 if let Some(idx) = self.free_list.pop() {
38 self.slots[idx] = Some(data);
39 $id(idx)
40 } else {
41 let idx = self.slots.len();
42 self.slots.push(Some(data));
43 $id(idx)
44 }
45 }
46
47 pub fn get(&self, id: $id) -> Option<&$data> {
48 self.slots.get(id.0)?.as_ref()
49 }
50
51 pub fn replace(&mut self, id: $id, data: $data) -> bool {
52 match self.slots.get_mut(id.0) {
53 Some(slot) if slot.is_some() => { *slot = Some(data); true }
54 _ => false,
55 }
56 }
57
58 pub fn remove(&mut self, id: $id) -> bool {
59 if let Some(slot) = self.slots.get_mut(id.0) {
60 if slot.is_some() {
61 *slot = None;
62 self.free_list.push(id.0);
63 return true;
64 }
65 }
66 false
67 }
68
69 pub fn contains(&self, id: $id) -> bool {
70 self.get(id).is_some()
71 }
72
73 pub fn len(&self) -> usize {
74 self.slots.iter().filter(|s| s.is_some()).count()
75 }
76 }
77 };
78}
79
80curve_store!(
81 /// Handle to a pre-uploaded polyline produced by
82 /// [`ViewportGpuResources::upload_polyline`](crate::resources::ViewportGpuResources::upload_polyline).
83 PolylineId,
84 PolylineStore,
85 PolylineGpuData
86);
87
88curve_store!(
89 /// Handle to a pre-uploaded streamtube produced by
90 /// [`ViewportGpuResources::upload_streamtube`](crate::resources::ViewportGpuResources::upload_streamtube).
91 StreamtubeId,
92 StreamtubeStore,
93 StreamtubeGpuData
94);
95
96curve_store!(
97 /// Handle to a pre-uploaded tube produced by
98 /// [`ViewportGpuResources::upload_tube`](crate::resources::ViewportGpuResources::upload_tube).
99 TubeId,
100 TubeStore,
101 StreamtubeGpuData
102);
103
104curve_store!(
105 /// Handle to a pre-uploaded ribbon produced by
106 /// [`ViewportGpuResources::upload_ribbon`](crate::resources::ViewportGpuResources::upload_ribbon).
107 RibbonId,
108 RibbonStore,
109 StreamtubeGpuData
110);
111
112curve_store!(
113 /// Handle to a pre-uploaded point cloud produced by
114 /// [`ViewportGpuResources::upload_point_cloud`](crate::resources::ViewportGpuResources::upload_point_cloud).
115 PointCloudId,
116 PointCloudStore,
117 PointCloudGpuData
118);
119
120curve_store!(
121 /// Handle to a pre-uploaded glyph set produced by
122 /// [`ViewportGpuResources::upload_glyph_set`](crate::resources::ViewportGpuResources::upload_glyph_set).
123 GlyphSetId,
124 GlyphSetStore,
125 GlyphGpuData
126);
127
128curve_store!(
129 /// Handle to a pre-uploaded tensor glyph set produced by
130 /// [`ViewportGpuResources::upload_tensor_glyph_set`](crate::resources::ViewportGpuResources::upload_tensor_glyph_set).
131 TensorGlyphSetId,
132 TensorGlyphSetStore,
133 TensorGlyphGpuData
134);
135
136curve_store!(
137 /// Handle to a pre-uploaded sprite set produced by
138 /// [`ViewportGpuResources::upload_sprite_set`](crate::resources::ViewportGpuResources::upload_sprite_set).
139 /// Backs static billboards such as foliage, signage, and light flares.
140 SpriteSetId,
141 SpriteSetStore,
142 SpriteGpuData
143);
144
145curve_store!(
146 /// Handle to a pre-uploaded sprite instance set produced by
147 /// [`ViewportGpuResources::upload_sprite_instance_set`](crate::resources::ViewportGpuResources::upload_sprite_instance_set).
148 /// Backs entity sprites such as NPCs, item drops, and damage numbers.
149 SpriteInstanceSetId,
150 SpriteInstanceSetStore,
151 SpriteGpuData
152);