Skip to content

Commit 7871b99

Browse files
committed
Add Sketch asset, and a LivecodePlugin
1 parent 2022308 commit 7871b99

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//! A Sketch asset represents a source file containing user code for a Processing sketch.
2+
//!
3+
//! Sketches are loaded through Bevy's asset system, which provides automatic file watching
4+
//! and change detection. This enables hot-reloading workflows where artists can edit their
5+
//! sketch code and see changes reflected immediately without restarting.
6+
//!
7+
//! This module is intentionally language-agnostic — it only handles loading source text from
8+
//! disk. Language-specific crates (like `processing_pyo3`) are responsible for executing the
9+
//! source and binding it to the Processing API.
10+
11+
use bevy::{
12+
asset::{AssetLoader, LoadContext, io::Reader},
13+
prelude::*,
14+
};
15+
use std::path::PathBuf;
16+
17+
/// Plugin that registers the Sketch asset type and its loader.
18+
pub struct LivecodePlugin;
19+
20+
impl Plugin for LivecodePlugin {
21+
fn build(&self, app: &mut App) {
22+
app.init_asset::<Sketch>()
23+
.init_asset_loader::<SketchLoader>();
24+
}
25+
}
26+
27+
/// A sketch source file loaded as a Bevy asset.
28+
///
29+
/// The `Sketch` asset contains the raw source code as a string. It does not interpret
30+
/// or execute the code — that responsibility belongs to language-specific crates.
31+
#[derive(Asset, TypePath, Debug)]
32+
pub struct Sketch {
33+
/// The source code contents of the sketch file.
34+
pub source: String,
35+
36+
/// The original file path.
37+
pub path: PathBuf,
38+
}
39+
40+
/// Loads sketch files from disk.
41+
///
42+
/// Currently supports `.py` files, but the loader is designed to be extended
43+
/// for other languages in the future.
44+
#[derive(Default)]
45+
pub struct SketchLoader;
46+
47+
impl AssetLoader for SketchLoader {
48+
type Asset = Sketch;
49+
type Settings = ();
50+
type Error = std::io::Error;
51+
52+
async fn load(
53+
&self,
54+
reader: &mut dyn Reader,
55+
_settings: &Self::Settings,
56+
load_context: &mut LoadContext<'_>,
57+
) -> Result<Self::Asset, Self::Error> {
58+
let mut source = String::new();
59+
60+
let mut bytes = Vec::new();
61+
reader.read_to_end(&mut bytes).await?;
62+
63+
if let Ok(utf8) = str::from_utf8(&bytes) {
64+
source = utf8.to_string();
65+
}
66+
67+
let asset_path = load_context.path();
68+
let path: PathBuf = asset_path.path().to_path_buf();
69+
70+
Ok(Sketch { source, path })
71+
}
72+
73+
fn extensions(&self) -> &[&str] {
74+
&["py"]
75+
}
76+
}

0 commit comments

Comments
 (0)