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