A framework for the Godot engine to create TTRPG games for Advanced 5th Edition, Pathfinder 2nd Edition, and more
at main 86 lines 1.8 kB view raw
1use std::collections::HashMap; 2use wasm_bindgen::prelude::*; 3use rmpv::Value; 4 5#[wasm_bindgen] 6pub struct DiceWire { 7 hooks: Hooks 8} 9 10impl DiceWire { 11 pub fn new() -> Self { 12 Self { 13 hooks: Hooks::new() 14 } 15 } 16} 17 18#[wasm_bindgen] 19pub struct Hooks { 20 events: HashMap<String, Vec<Hook>> 21} 22 23impl Hooks { 24 pub fn new() -> Self { 25 Self { 26 events: HashMap::new() 27 } 28 } 29 30 pub fn on<F>(&mut self, event: String, callback: F) 31 where 32 F: Fn(&Value) + 'static + Send + Sync 33 { 34 self.events.entry(event) 35 .or_insert_with(Vec::new) 36 .push(Hook::new(callback, false)); 37 } 38 39 pub fn once<F>(&mut self, event: String, callback: F) 40 where 41 F: Fn(&Value) + 'static + Send + Sync 42 { 43 self.events.entry(event) 44 .or_insert_with(Vec::new) 45 .push(Hook::new(callback, true)); 46 } 47 48 pub fn emit(&mut self, event: String, data: &Value) { 49 if let Some(event_list) = self.events.get_mut(&event) { 50 for event in event_list.iter_mut() { 51 event.call(data); 52 } 53 } 54 } 55} 56 57#[wasm_bindgen] 58pub struct Hook { 59 func: Box<dyn Fn(&Value) -> () + Sync + Send>, 60 once: bool, 61 called: bool 62} 63 64impl Hook { 65 pub fn new<F>(callback: F, once: bool) -> Self 66 where 67 F: Fn(&Value) -> () + 'static + Send + Sync 68 { 69 Self { 70 func: Box::new(callback), 71 once, 72 called: false 73 } 74 } 75 76 pub fn call(&mut self, data: &Value) { 77 if self.once { 78 if !self.called { 79 (self.func)(data); 80 self.called = true; 81 } 82 } else { 83 (self.func)(data); 84 } 85 } 86}