makepad_platform/
geometry.rs1use {
2 std::{
3 rc::Rc,
4 hash::{Hash, Hasher},
5 },
6 crate::{
7 id_pool::*,
8 makepad_live_compiler::{
9 LiveType,
10 LiveId,
11 },
12 makepad_shader_compiler::ShaderTy,
13 os::CxOsGeometry,
14 cx::Cx,
15 }
16};
17
18
19#[derive(Debug)]
20pub struct Geometry(PoolId);
21
22#[derive(Clone, Copy, Debug, PartialEq)]
23pub struct GeometryId(usize, u64);
24
25impl Geometry{
26 pub fn geometry_id(&self)->GeometryId{GeometryId(self.0.id, self.0.generation)}
27}
28
29#[derive(Default)]
30pub struct CxGeometryPool(pub (crate) IdPool<CxGeometry>);
31
32impl CxGeometryPool{
33 pub fn alloc(&mut self)->Geometry{
34 Geometry(self.0.alloc())
35 }
36}
37
38impl std::ops::Index<GeometryId> for CxGeometryPool{
39 type Output = CxGeometry;
40 fn index(&self, index: GeometryId) -> &Self::Output{
41 let d = &self.0.pool[index.0];
42 if d.generation != index.1{
43 error!("Drawlist id generation wrong {} {} {}", index.0, d.generation, index.1)
44 }
45 &d.item
46 }
47}
48
49impl std::ops::IndexMut<GeometryId> for CxGeometryPool{
50 fn index_mut(&mut self, index: GeometryId) -> &mut Self::Output{
51 let d = &mut self.0.pool[index.0];
52 if d.generation != index.1{
53 error!("Drawlist id generation wrong {} {} {}", index.0, d.generation, index.1)
54 }
55 &mut d.item
56 }
57}
58
59#[derive(Clone, Debug)]
60pub struct GeometryRef(pub Rc<Geometry>);
61
62
63const MAX_GEOM_FINGERPRINT:usize = 16;
64#[derive(Clone, Debug)]
65pub struct GeometryFingerprint {
66 pub live_type: LiveType,
67 pub inputs_stored:usize,
68 pub inputs: [f32;MAX_GEOM_FINGERPRINT]
69}
70
71impl GeometryFingerprint{
72 pub fn new(live_type:LiveType)->Self{Self{live_type, inputs_stored:0, inputs:[0f32;MAX_GEOM_FINGERPRINT]}}
73 pub fn push(&mut self, f:f32){self.inputs[self.inputs_stored] = f;self.inputs_stored += 1;}
74}
75
76impl Hash for GeometryFingerprint {
77 fn hash<H: Hasher>(&self, state: &mut H) {
78 self.live_type.hash(state);
79 for i in 0..self.inputs_stored{
80 self.inputs[i].to_bits().hash(state);
81 }
82 }
83}
84
85impl PartialEq for GeometryFingerprint {
86 fn eq(&self, other: &Self) -> bool {
87 if self.inputs_stored != other.inputs_stored{
88 return false
89 }
90 for i in 0..self.inputs_stored{
91 if self.inputs[i] != other.inputs[i]{
92 return false
93 }
94 }
95 self.live_type == other.live_type
96 }
97}
98impl Eq for GeometryFingerprint {}
99
100impl Cx{
101
102 pub fn get_geometry_ref(&mut self, fingerprint:GeometryFingerprint)->GeometryRef{
103 if let Some(gr) = self.geometries_refs.get(&fingerprint){
105 if let Some(gr) = gr.upgrade(){
106 return GeometryRef(gr)
107 }
108 }
109 let geometry = Rc::new(Geometry::new(self));
110 let weak = Rc::downgrade(&geometry);
111 self.geometries_refs.insert(fingerprint, weak);
112 GeometryRef(geometry)
113 }
114}
115
116impl Geometry{
117 pub fn new(cx: &mut Cx) -> Self {
118 let geometry = cx.geometries.alloc();
119 cx.geometries[geometry.geometry_id()].indices.clear();
120 cx.geometries[geometry.geometry_id()].vertices.clear();
121 cx.geometries[geometry.geometry_id()].dirty = true;
122 geometry
123 }
124
125 pub fn update(&self, cx:&mut Cx, indices: Vec<u32>, vertices: Vec<f32>){
126 let cxgeom = &mut cx.geometries[self.geometry_id()];
127 cxgeom.indices = indices;
128 cxgeom.vertices = vertices;
129 cxgeom.dirty = true;
130 }
131}
132
133#[derive(Default)]
134pub struct CxGeometry{
135 pub indices: Vec<u32>,
136 pub vertices: Vec<f32>,
137 pub dirty: bool,
138 pub os: CxOsGeometry
139}
140
141
142#[derive(Debug)]
143pub struct GeometryField {
144 pub id: LiveId,
145 pub ty: ShaderTy
146}
147
148pub trait GeometryFields{
149 fn geometry_fields(&self, fields: &mut Vec<GeometryField>);
150 fn live_type_check(&self)->LiveType;
151 fn get_geometry_id(&self)->Option<GeometryId>;
152}
153
154