1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
use ffi::*; use std::sync::mpsc::{self,channel,Receiver}; use message::Message; use util::*; use reference::Reference; use object::Object; static REMOVE_WATCH_MESSAGE_STR: &'static str = "gstreamer1.0-rs_remove_watch_message"; unsafe impl Sync for Bus {} unsafe impl Send for Bus {} pub struct Bus{ bus: Object } impl Bus{ pub unsafe fn new(bus: *mut GstBus) -> Option<Bus>{ Object::new(bus as *mut GstObject).map(|obj| Bus{bus: obj}) } pub fn add_watch<W: Watch>(&mut self, watch: W) -> u32{ unsafe{ let watch: Box<Watch> = Box::new(watch); let watch: *mut Box<Watch> = Box::into_raw(Box::new(watch)); gst_bus_add_watch (self.gst_bus_mut(), Some(bus_callback), mem::transmute(watch)) } } pub fn remove_watch(&mut self) -> bool{ unsafe{ let message_cstr = CString::new(REMOVE_WATCH_MESSAGE_STR).unwrap(); let structure = gst_structure_new(message_cstr.as_ptr(), ptr::null()); let message = gst_message_new_application(ptr::null_mut(), structure); gst_bus_post(self.gst_bus_mut(), message) != 0 } } pub fn receiver(&mut self) -> Receiver<Message>{ let (watch,receiver) = channel(); self.add_watch(watch); receiver } pub unsafe fn gst_bus(&self) -> *const GstBus{ self.bus.gst_object() as *const GstBus } pub unsafe fn gst_bus_mut(&mut self) -> *mut GstBus{ self.bus.gst_object_mut() as *mut GstBus } } extern "C" fn bus_callback(_bus: *mut GstBus, msg: *mut GstMessage, data: gpointer) -> gboolean { unsafe{ let alive = { let mut watch: &mut Box<Watch> = mem::transmute(data); match Message::new(msg){ Some(Message::Application(app_msg)) => { let structure = gst_message_get_structure(app_msg); let cname = gst_structure_get_name(structure); if from_c_str!(cname) == REMOVE_WATCH_MESSAGE_STR{ false }else{ watch.call(Message::Application(app_msg)) } } Some(msg) => watch.call(msg), None => true, } }; if !alive{ Box::from_raw(data); } if alive {1} else {0} } } pub trait Watch: Send{ fn call(&mut self, msg: Message) -> bool; } impl Watch for mpsc::Sender<Message>{ fn call(&mut self, msg: Message) -> bool{ self.send(msg).is_ok() } } impl Reference for Bus{ fn reference(&self) -> Bus{ Bus{ bus: self.bus.reference() } } }