Skip to content

Commit

Permalink
handle wasm clipboard
Browse files Browse the repository at this point in the history
so that was.. a bit of work!
first i did the copying which went really well and took no time. then
tried handling pasting.. and oh boy! first of all "Promise"? really? the
works of evil witchcraft! i tried handling it by giving the whole thing
as a callback, but world can't escape the system. then tried converting
it to a future using wasm_bindgen_futures and that was its own deal. i
still don't feel comortable with async stuff. i tried using the bevy
compute task to spawn the future and get its value inside the system,
but JsFuture are not Send and i couldn't figure out how to use the
spawn_local with the compute. tried wasm_bindgen_futures' spawn_local()
but that only takes futures with result () so i didn't know how to get
the string out of there. lots of closures where the compiler yells
because something moved... aaaa i'm so happy this is done!
and after i did it like this it still didn't work because the callback
was being dropped.. i couldn't stick the callback in a bevy resource
(because not Send) so i just said fuck it and mem::forget it. i doubt
anyone can abuse this to cause any serious leak (famous last words?)
  • Loading branch information
tomara-x committed Jun 23, 2024
1 parent d89be61 commit 1185a2d
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 13 deletions.
10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,25 @@ features = [
"bevy_pbr",
]


[dependencies]
bevy_pancam = {version = "0.11.1", git = "https://github.com/tomara-x/bevy_pancam"}
fundsp = {version = "0.18.1", default-features = false}
#cpal = {version = "0.15.3", features = ["jack", "wasm-bindgen"]}
cpal = {version = "0.15.3", features = ["jack"]}
copypasta = "0.10.1"
serde = "1"
rosc = "0.10.1"
crossbeam-channel = "0.5"

# wasm stuff
#cpal = {version = "0.15.3", features = ["jack", "wasm-bindgen"]}
#wasm-bindgen = "0.2.92"
#web-sys = {version = "0.3.69", features = ["Clipboard"]}

# inspector
bevy-inspector-egui = {version = "0.24", default-features = false, optional = true}


# smol amount of optimization for our stuff
[profile.dev]
opt-level = 1
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,22 @@ development happens on the `main` branch
alternatively you can download stable releases from: https://github.com/tomara-x/quartz/releases

there's an experimental wasm build here: https://tomara-x.github.io/quartz/
(no audio input, no file loading/saving, and no copy/pasing)
(no audio input, no file loading/saving)

<details><summary>wasm building</summary>
<p>

uncomment the commented out dependencies in cargo.toml, then:
```
RUSTFLAGS=--cfg=web_sys_unstable_apis cargo build --profile wasm-release --target wasm32-unknown-unknown
wasm-bindgen --out-name quartz --out-dir target --target web target/wasm32-unknown-unknown/wasm-release/quartz.wasm
```
more details: https://github.com/bevyengine/bevy/tree/main/examples#wasm

</p>
</details>


---
### modes
Expand Down Expand Up @@ -874,6 +889,7 @@ i hope that everyone will become friends
- serde https://github.com/serde-rs/serde
- rosc https://github.com/klingtnet/rosc
- crossbeam https://github.com/crossbeam-rs/crossbeam
- wasm-bindgen https://github.com/rustwasm/wasm-bindgen
- bevy_github_ci_template https://github.com/bevyengine/bevy_github_ci_template
- tracy https://github.com/wolfpld/tracy
- vim https://github.com/vim/vim
Expand Down
24 changes: 22 additions & 2 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use crate::{

use fundsp::audiounit::AudioUnit;

use copypasta::ClipboardProvider;

use cpal::traits::{HostTrait, DeviceTrait};

#[derive(SystemParam)]
Expand All @@ -32,7 +34,6 @@ pub struct Access<'w, 's> {
vertices_query: Query<'w, 's, &'static mut Vertices>,
save_event: EventWriter<'w, SaveCommand>,
copy_event: EventWriter<'w, CopyCommand>,
paste_event: EventWriter<'w, PasteCommand>,
delete_event: EventWriter<'w, DeleteCommand>,
targets_query: Query<'w, 's, &'static mut Targets>,
gained_wh_query: Query<'w, 's, &'static mut GainedWH>,
Expand All @@ -53,6 +54,8 @@ pub struct Access<'w, 's> {
in_device_event: EventWriter<'w, InDeviceCommand>,
node_limit: ResMut<'w, NodeLimit>,
op_num_query: Query<'w, 's, &'static mut OpNum>,
clipboard: ResMut<'w, SystemClipboard>,
paste_chan: Res<'w, PasteChannel>,
}

pub fn command_parser(
Expand Down Expand Up @@ -1438,7 +1441,24 @@ pub fn command_parser(
text.clear();
}
Some("p") | Some("\"+p") => {
access.paste_event.send_default();
#[cfg(not(target_arch = "wasm32"))]
if let Ok(string) = access.clipboard.0.get_contents() {
let _ = access.paste_chan.0.0.try_send(string);
}
#[cfg(target_arch = "wasm32")]
if let Some(win) = web_sys::window() {
if let Some(clip) = win.navigator().clipboard() {
let sender = access.paste_chan.0.0.clone();
let cb = wasm_bindgen::closure::Closure::new(move |val: wasm_bindgen::JsValue| {
if let Some(string) = val.as_string() {
let _ = sender.try_send(string);
}
});
let _ = clip.read_text().then(&cb);
// fuck it
std::mem::forget(cb);
}
}
text.clear();
}
Some(":delete") => {
Expand Down
6 changes: 3 additions & 3 deletions src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ pub struct NodeLimit(pub usize);
#[derive(Resource)]
pub struct InputReceivers(pub Receiver<f32>, pub Receiver<f32>);

#[derive(Resource)]
pub struct PasteChannel(pub (Sender<String>, Receiver<String>));

// -------------------- events --------------------
#[derive(Event, Default)]
pub struct OrderChange;
Expand All @@ -300,9 +303,6 @@ pub struct SaveCommand(pub String);
#[derive(Event, Default)]
pub struct CopyCommand;

#[derive(Event, Default)]
pub struct PasteCommand;

#[derive(Event, Default)]
pub struct DeleteCommand;

Expand Down
21 changes: 15 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ fn main() {
.insert_resource(SystemClipboard(ClipboardContext::new().unwrap()))
.insert_resource(Msaa::Sample4)
.insert_resource(Version(format!("{} {}", env!("CARGO_PKG_VERSION"), env!("COMMIT_HASH"))))
.insert_resource(PasteChannel(crossbeam_channel::bounded::<String>(1)))
.init_resource::<PolygonHandles>()

.add_systems(Startup, setup)
Expand All @@ -94,7 +95,7 @@ fn main() {
.init_state::<Mode>()
.add_systems(Update, save_scene)
.add_systems(Update, copy_scene.run_if(on_event::<CopyCommand>()))
.add_systems(Update, paste_scene.run_if(on_event::<PasteCommand>()))
.add_systems(Update, paste_scene)
.add_systems(Update, post_load)
.add_systems(Update, file_drag_and_drop)
.add_systems(Update, update_indicator)
Expand All @@ -121,7 +122,6 @@ fn main() {
// events
.add_event::<SaveCommand>()
.add_event::<CopyCommand>()
.add_event::<PasteCommand>()
.add_event::<DeleteCommand>()
.add_event::<ConnectCommand>()
.add_event::<OutDeviceCommand>()
Expand Down Expand Up @@ -400,13 +400,22 @@ fn copy_scene(world: &mut World) {
let type_registry = world.resource::<AppTypeRegistry>().clone();
let type_registry = type_registry.read();
let serialized_scene = scene.serialize(&type_registry).unwrap();
let mut ctx = world.resource_mut::<SystemClipboard>();
ctx.0.set_contents(serialized_scene).unwrap();
#[cfg(not(target_arch = "wasm32"))]
{
let mut ctx = world.resource_mut::<SystemClipboard>();
ctx.0.set_contents(serialized_scene).unwrap();
}
#[cfg(target_arch = "wasm32")]
if let Some(window) = web_sys::window() {
if let Some(clipboard) = window.navigator().clipboard() {
let _ = clipboard.write_text(&serialized_scene);
}
}
}

fn paste_scene(world: &mut World) {
if let Ok(ctx) = world.resource_mut::<SystemClipboard>().0.get_contents() {
let bytes = ctx.into_bytes();
if let Ok(string) = world.resource::<PasteChannel>().0.1.try_recv() {
let bytes = string.into_bytes();
let mut scene = None;
if let Ok(mut deserializer) = Deserializer::from_bytes(&bytes) {
let type_registry = world.resource::<AppTypeRegistry>();
Expand Down

0 comments on commit 1185a2d

Please sign in to comment.