Repository navigation
Expand file tree
/
Copy pathsketch.rs
More file actions
107 lines (90 loc) · 2.89 KB
/
Copy pathsketch.rs
File metadata and controls
107 lines (90 loc) · 2.89 KB
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
97
98
99
100
101
102
103
104
105
106
107
//! A Sketch asset represents a source file containing user code for a Processing sketch.
use bevy::{
asset::{
AssetLoader, AssetPath, LoadContext,
io::{AssetSourceId, Reader},
},
prelude::*,
};
use std::path::Path;
use processing_core::config::{Config, ConfigKey};
/// Plugin that registers the Sketch asset type and its loader.
pub struct LivecodePlugin;
impl Plugin for LivecodePlugin {
fn build(&self, app: &mut App) {
app.init_asset::<Sketch>()
.init_asset_loader::<SketchLoader>()
.add_systems(PreStartup, load_current_sketch);
}
}
// TODO: A better name is possible
pub fn sketch_update_handler(
mut events: MessageReader<AssetEvent<Sketch>>,
sketches: Res<Assets<Sketch>>,
) -> Option<Sketch> {
for event in events.read() {
if let AssetEvent::Modified { id } = event {
info!("Modified: {id}");
if let Some(sketch) = sketches.get(*id) {
let sketch = sketch.clone();
return Some(sketch);
}
}
}
None
}
fn load_current_sketch(
mut commands: Commands,
asset_server: Res<AssetServer>,
config: Res<Config>,
) {
let filename = config
.get(ConfigKey::SketchFileName)
.expect("SketchFileName not set");
let path = Path::new(filename);
let source = AssetSourceId::from("sketch_directory");
let asset_path = AssetPath::from_path(path).with_source(source);
let sketch_handle: Handle<Sketch> = asset_server.load(asset_path);
commands.spawn(SketchRoot(sketch_handle));
}
/// `SketchRoot` is what will be spawned and will contain a `Handle` to the `Sketch`
#[derive(Component)]
pub struct SketchRoot(pub Handle<Sketch>);
/// A sketch source file loaded as a Bevy asset.
///
/// The `Sketch` asset contains the raw source code as a string. It does not interpret
/// or execute the code — that responsibility belongs to language-specific crates.
#[derive(Asset, Clone, TypePath, Debug)]
pub struct Sketch {
// TODO: should this be &str ?
pub source: String,
}
/// Loads sketch files from disk.
///
/// Currently supports `.py` files, but the loader is designed to be extended
/// for other languages in the future.
#[derive(Default, TypePath)]
pub struct SketchLoader;
impl AssetLoader for SketchLoader {
type Asset = Sketch;
type Settings = ();
type Error = std::io::Error;
async fn load(
&self,
reader: &mut dyn Reader,
_settings: &Self::Settings,
_load_context: &mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let mut source = String::new();
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
if let Ok(utf8) = str::from_utf8(&bytes) {
source = utf8.to_string();
}
info!(source);
Ok(Sketch { source })
}
fn extensions(&self) -> &[&str] {
&["py"]
}
}