1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use std::{collections::BTreeMap, sync::RwLock};
use bevy::prelude::{
default, AssetEvent, Assets, CoreSet, Deref, DerefMut, EventReader, Handle, IntoSystemConfig,
Plugin, Res, ResMut, Shader,
};
use once_cell::sync::Lazy;
use rust_gpu_builder_shared::RustGpuBuilderOutput;
pub static RUST_GPU_ARTIFACTS: Lazy<RwLock<RustGpuArtifacts>> = Lazy::new(default);
pub struct BuilderOutputPlugin;
impl Plugin for BuilderOutputPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
#[cfg(feature = "json")]
app.add_plugin(bevy_common_assets::json::JsonAssetPlugin::<
RustGpuBuilderOutput,
>::new(&["rust-gpu.json"]));
#[cfg(feature = "msgpack")]
app.add_plugin(bevy_common_assets::msgpack::MsgPackAssetPlugin::<
RustGpuBuilderOutput,
>::new(&["rust-gpu.msgpack"]));
app.add_system(builder_output_events.in_base_set(CoreSet::PreUpdate));
}
}
#[derive(Debug, Clone)]
pub enum RustGpuModules {
Single(Handle<Shader>),
Multi(BTreeMap<String, Handle<Shader>>),
}
#[derive(Debug, Clone)]
pub struct RustGpuArtifact {
pub entry_points: Vec<String>,
pub modules: RustGpuModules,
}
#[derive(Debug, Default, Clone, Deref, DerefMut)]
pub struct RustGpuArtifacts {
pub artifacts: BTreeMap<Handle<RustGpuBuilderOutput>, RustGpuArtifact>,
}
pub fn builder_output_events(
mut builder_output_events: EventReader<AssetEvent<RustGpuBuilderOutput>>,
builder_outputs: Res<Assets<RustGpuBuilderOutput>>,
mut shaders: ResMut<Assets<Shader>>,
) {
for event in builder_output_events.iter() {
if let AssetEvent::Created { handle } | AssetEvent::Modified { handle } = event {
let asset = builder_outputs.get(handle).unwrap().clone();
let artifact = match asset.modules {
rust_gpu_builder_shared::RustGpuBuilderModules::Single(ref single) => {
let shader = shaders.add(Shader::from_spirv(single.clone()));
RustGpuArtifact {
entry_points: asset.entry_points,
modules: RustGpuModules::Single(shader),
}
}
rust_gpu_builder_shared::RustGpuBuilderModules::Multi(multi) => RustGpuArtifact {
entry_points: asset.entry_points,
modules: RustGpuModules::Multi(
multi
.into_iter()
.map(|(k, module)| (k.clone(), shaders.add(Shader::from_spirv(module))))
.collect(),
),
},
};
RUST_GPU_ARTIFACTS
.write()
.unwrap()
.insert(handle.clone_weak(), artifact);
}
if let AssetEvent::Removed { handle } = event {
RUST_GPU_ARTIFACTS.write().unwrap().remove(handle);
}
}
}