From c23498039d902bafbcf21d15b23e48484b09b6ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 4 Aug 2017 18:13:33 +0300 Subject: [PATCH] Clean up SendCell implementation and implement some more traits For moving it elsewhere later as public API. --- examples/src/bin/gtksink.rs | 98 +++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/examples/src/bin/gtksink.rs b/examples/src/bin/gtksink.rs index 8590d80de..5da15d72a 100644 --- a/examples/src/bin/gtksink.rs +++ b/examples/src/bin/gtksink.rs @@ -14,37 +14,6 @@ use gtk::ApplicationExt as GtkApplicationExt; use std::env; -// Workaround for GTK objects not implementing Send (nor Sync) -// but us having to use them in a closure that requires Send -use std::thread; -use std::ops::Deref; - -#[derive(Clone, Debug)] -pub struct SendCell { - data: T, - thread_id: thread::ThreadId, -} - -impl SendCell { - pub fn new(data: T) -> Self { - SendCell { - data: data, - thread_id: thread::current().id(), - } - } -} - -impl Deref for SendCell { - type Target = T; - - fn deref(&self) -> &T { - assert_eq!(thread::current().id(), self.thread_id); - &self.data - } -} - -unsafe impl Send for SendCell {} - fn create_ui(app: >k::Application) { let pipeline = Pipeline::new(None); let src = ElementFactory::make("videotestsrc", None).unwrap(); @@ -126,7 +95,7 @@ fn create_ui(app: >k::Application) { err.get_error(), err.get_debug() ); - app.quit(); + app.get().quit(); } _ => (), }; @@ -153,3 +122,68 @@ fn main() { let args_ref = args.iter().map(|a| a.as_str()).collect::>(); app.run(&args_ref); } + +// Workaround for GTK objects not implementing Send (nor Sync) +// but us having to use them in a closure that requires Send +use std::thread; +use std::cmp; + +#[derive(Clone, Debug)] +pub struct SendCell { + data: T, + thread_id: thread::ThreadId, +} + +impl SendCell { + pub fn new(data: T) -> Self { + SendCell { + data: data, + thread_id: thread::current().id(), + } + } + + pub fn get(&self) -> &T { + assert_eq!(thread::current().id(), self.thread_id); + &self.data + } + + pub fn try_get(&self) -> Option<&T> { + if thread::current().id() == self.thread_id { + Some(&self.data) + } else { + None + } + } +} + +impl From for SendCell { + fn from(t: T) -> SendCell { + SendCell::new(t) + } +} + +impl Default for SendCell { + fn default() -> SendCell { + SendCell::new(T::default()) + } +} + +impl PartialEq> for SendCell { + fn eq(&self, other: &Self) -> bool { + self.data.eq(&other.data) + } +} +impl Eq for SendCell {} + +impl PartialOrd> for SendCell { + fn partial_cmp(&self, other: &Self) -> Option { + self.data.partial_cmp(&other.data) + } +} +impl Ord for SendCell { + fn cmp(&self, other: &Self) -> cmp::Ordering { + self.data.cmp(&other.data) + } +} + +unsafe impl Send for SendCell {}