this repo has no description
at main 4.2 kB view raw
1use crossbeam_channel::{bounded, Receiver}; 2use std::{ 3 collections::HashMap, 4 fs::File, 5 io::Read, 6 sync::{Arc, Mutex}, 7}; 8 9use flate2::read::GzDecoder; 10use serde_json::{Map, Value}; 11use tauri::{App, Emitter, Listener, Manager, WindowEvent}; 12 13use crate::{ 14 osc::{self, OSCMessage}, runtime::{commands::RuntimeCommand, nodes::RuntimeNodeTree, recurse_runtime}, structs::parameter_types::ParameterType, utils::{setup_traymenu::setup_traymenu, vrchat_builtin_parameters} 15}; 16 17pub fn setup( 18 app: &mut App, 19 addresses: &'static Mutex<Vec<OSCMessage>>, 20 runtime_command_receiver: Receiver<RuntimeCommand>, 21) { 22 let window = app.get_webview_window("main").unwrap(); 23 window.hide().unwrap(); 24 25 let win_handle = window.clone(); 26 27 window.on_window_event(move |event| match event { 28 WindowEvent::CloseRequested { api, .. } => { 29 api.prevent_close(); 30 win_handle.emit("prompt_to_close", ()).unwrap(); 31 } 32 WindowEvent::Resized(_) => { 33 let minimised = win_handle.is_minimized().unwrap(); 34 if minimised{ 35 win_handle.hide().unwrap(); 36 win_handle.emit("hide-window", ()).unwrap(); 37 win_handle.unminimize().unwrap(); 38 } 39 } 40 _ => {} 41 }); 42 43 setup_traymenu(app.handle()); 44 45 let handle = window.clone(); 46 window.listen("tauri://drag-drop", move |ev| { 47 let path: Value = serde_json::from_str(ev.payload()).unwrap(); 48 let path = path["paths"][0].as_str().unwrap(); 49 50 let file = File::open(&path).unwrap(); 51 let mut decoder = GzDecoder::new(file); 52 let mut string = String::new(); 53 54 decoder.read_to_string(&mut string).unwrap(); 55 56 let mut map = Map::new(); 57 58 map.insert("path".to_owned(), Value::String(path.to_owned())); 59 map.insert("graph".to_owned(), Value::String(string)); 60 61 handle.emit("load_new_tab", Value::Object(map)).unwrap(); 62 }); 63 64 let (sender, receiver) = bounded(1024); 65 66 tokio::spawn(async move { 67 osc::start_server(sender, "127.0.0.1:9001"); 68 }); 69 70 let (runtime_sender, runtime_receiver) = bounded(1024); 71 72 let runtime_sender_1 = runtime_sender.clone(); 73 tokio::spawn(async move { 74 loop { 75 let cmd = runtime_command_receiver.recv().unwrap(); 76 runtime_sender_1.send(cmd).unwrap(); 77 } 78 }); 79 80 tokio::spawn(async move { 81 loop { 82 let message = receiver.recv().unwrap(); 83 84 window.emit("osc-message", &message).unwrap(); 85 86 let msg = message.clone(); 87 let mut addrs = addresses.lock().unwrap(); 88 if !addrs.contains(&msg) { 89 addrs.push(msg); 90 } 91 92 if message.address == "/avatar/change".to_owned(){ 93 *addrs = vrchat_builtin_parameters::get_read_addresses(); 94 95 // TODO: Read avatar paramaters from file 96 } 97 98 runtime_sender 99 .send(RuntimeCommand::OSCMessage(message)) 100 .unwrap(); 101 } 102 }); 103 104 // TODO: Run tabs in seperate threads (really not looking forward to this... thanks rust) 105 106 tokio::spawn(async move { 107 let mut tabs: HashMap<String, RuntimeNodeTree> = HashMap::new(); 108 109 // #[cfg(target_os = "windows")] 110 let enigo = Arc::new(Mutex::new(enigo::Enigo::new(&enigo::Settings::default()).unwrap())); 111 112 loop { 113 let cmd = runtime_receiver.recv().unwrap(); 114 115 match cmd { 116 RuntimeCommand::OSCMessage(msg) => { 117 for (_, mut tab) in &mut tabs { 118 let keys: Vec<String> = tab.nodes.keys().map(|x| x.clone()).collect(); 119 120 for id in keys { 121 let entry = tab.nodes[&id].is_entrypoint(); 122 123 if entry { 124 let mut args = vec![ ParameterType::String(msg.address.clone())]; 125 let mut values = msg.values.clone(); 126 127 args.append(&mut values); 128 let _ = recurse_runtime(id.clone(), &mut tab, args); 129 } 130 } 131 } 132 } 133 134 RuntimeCommand::AddTab(graph, id) => { 135 // #[cfg(target_os = "windows")] 136 tabs.insert(id, RuntimeNodeTree::from(graph, enigo.clone())); 137 138 // #[cfg(target_os = "linux")] 139 // tabs.insert(id, RuntimeNodeTree::from(graph)); 140 } 141 RuntimeCommand::RemoveTab(id) => { 142 tabs.remove(&id); 143 } 144 } 145 } 146 }); 147}