1use std::{marker::PhantomData, ops::Deref, rc::Rc};
2
3pub use process_vector::*;
4pub use transferables::{
5 DefaultVectorTransferables, LayerIndexed, LayerMissing, LayerTessellated,
6 SymbolLayerTessellated, TileTessellated, VectorTransferables,
7};
8
9use crate::{
10 coords::WorldTileCoords,
11 environment::Environment,
12 kernel::Kernel,
13 plugin::Plugin,
14 render::{
15 eventually::Eventually,
16 graph::RenderGraph,
17 shaders::{FillShaderFeatureMetadata, ShaderLayerMetadata},
18 tile_view_pattern::{HasTile, ViewTileSources},
19 RenderStageLabel, ShaderVertex,
20 },
21 schedule::Schedule,
22 tcs::{system::SystemContainer, tiles::TileComponent, world::World},
23 vector::{
24 populate_world_system::PopulateWorldSystem,
25 queue_system::queue_system,
26 request_system::RequestSystem,
27 resource::BufferPool,
28 resource_system::resource_system,
29 tessellation::{IndexDataType, OverAlignedVertexBuffer},
30 upload_system::upload_system,
31 },
32};
33
34mod populate_world_system;
35mod process_vector;
36mod queue_system;
37mod render_commands;
38mod request_system;
39pub(crate) mod resource;
40mod resource_system;
41pub(crate) mod transferables;
42mod upload_system;
43
44pub mod tessellation;
46
47struct VectorPipeline(wgpu::RenderPipeline);
48impl Deref for VectorPipeline {
49 type Target = wgpu::RenderPipeline;
50
51 fn deref(&self) -> &Self::Target {
52 &self.0
53 }
54}
55
56struct LinePipeline(wgpu::RenderPipeline);
57impl Deref for LinePipeline {
58 type Target = wgpu::RenderPipeline;
59
60 fn deref(&self) -> &Self::Target {
61 &self.0
62 }
63}
64
65pub type VectorBufferPool = BufferPool<
66 wgpu::Queue,
67 wgpu::Buffer,
68 ShaderVertex,
69 IndexDataType,
70 ShaderLayerMetadata,
71 FillShaderFeatureMetadata,
72>;
73
74pub struct VectorPlugin<T>(PhantomData<T>);
75
76impl<T: VectorTransferables> Default for VectorPlugin<T> {
77 fn default() -> Self {
78 Self(Default::default())
79 }
80}
81
82#[derive(Default)]
84struct VectorTilesDone;
85
86impl HasTile for VectorTilesDone {
87 fn has_tile(&self, coords: WorldTileCoords, world: &World) -> bool {
88 let Some(vector_layers_indices) = world.tiles.query::<&VectorLayerBucketComponent>(coords)
89 else {
90 return false;
91 };
92
93 vector_layers_indices.done
94 }
95}
96
97impl<E: Environment, T: VectorTransferables> Plugin<E> for VectorPlugin<T> {
98 fn build(
99 &self,
100 schedule: &mut Schedule,
101 kernel: Rc<Kernel<E>>,
102 world: &mut World,
103 _graph: &mut RenderGraph,
104 ) {
105 let resources = &mut world.resources;
106
107 resources.insert(Eventually::<VectorBufferPool>::Uninitialized);
108 resources.insert(Eventually::<VectorPipeline>::Uninitialized);
109 resources.insert(Eventually::<LinePipeline>::Uninitialized);
110
111 resources
112 .get_or_init_mut::<ViewTileSources>()
113 .add_resource_query::<&Eventually<VectorBufferPool>>()
114 .add::<VectorTilesDone>();
115
116 schedule.add_system_to_stage(
117 RenderStageLabel::Extract,
118 SystemContainer::new(RequestSystem::<E, T>::new(&kernel)),
119 );
120 schedule.add_system_to_stage(
121 RenderStageLabel::Extract,
122 SystemContainer::new(PopulateWorldSystem::<E, T>::new(&kernel)),
123 );
124
125 schedule.add_system_to_stage(RenderStageLabel::Prepare, resource_system);
126 schedule.add_system_to_stage(RenderStageLabel::Queue, upload_system); schedule.add_system_to_stage(RenderStageLabel::Queue, queue_system);
128 }
129}
130
131pub struct AvailableVectorLayerBucket {
132 pub coords: WorldTileCoords,
133 pub source_layer: String,
134 pub style_layer_id: String,
135 pub buffer: OverAlignedVertexBuffer<ShaderVertex, IndexDataType>,
136 pub feature_indices: Vec<u32>,
138 pub feature_colors: Vec<[f32; 4]>,
139}
140
141pub struct MissingVectorLayerBucket {
142 pub coords: WorldTileCoords,
143 pub source_layer: String,
144}
145
146pub enum VectorLayerBucket {
147 AvailableLayer(AvailableVectorLayerBucket),
148 Missing(MissingVectorLayerBucket),
149}
150
151#[derive(Default)]
152pub struct VectorLayerBucketComponent {
153 pub done: bool,
154 pub layers: Vec<VectorLayerBucket>,
155}
156
157impl TileComponent for VectorLayerBucketComponent {}