Skip to content

Commit 36f36d1

Browse files
committed
ThreadGuard: Implement ToValue, Fromvalue and Default traits
This will also allow ThreadGuard to be used with the new property macro.
1 parent dcf23b2 commit 36f36d1

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

glib-macros/tests/properties.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ mod foo {
8888

8989
pub mod imp {
9090
use glib::{ParamSpec, Value};
91+
use glib::thread_guard::ThreadGuard;
9192
use std::rc::Rc;
9293

9394
use super::*;
@@ -145,6 +146,8 @@ mod foo {
145146
cell: Cell<u8>,
146147
#[property(get = Self::overridden, override_class = Base)]
147148
overridden: PhantomData<u32>,
149+
#[property(get, set, default = "")]
150+
thread_guard: RefCell<ThreadGuard<String>>,
148151
}
149152

150153
impl ObjectImpl for Foo {

glib/src/param_spec.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,17 @@ pub trait HasParamSpec {
20652065
fn param_spec_builder() -> Self::BuilderFn;
20662066
}
20672067

2068+
impl<T: crate::value::ToValueOptional + HasParamSpec> HasParamSpec
2069+
for crate::thread_guard::ThreadGuard<T>
2070+
{
2071+
type ParamSpec = T::ParamSpec;
2072+
type SetValue = T::SetValue;
2073+
type BuilderFn = T::BuilderFn;
2074+
2075+
fn param_spec_builder() -> Self::BuilderFn {
2076+
T::param_spec_builder()
2077+
}
2078+
}
20682079
impl<T: crate::value::ToValueOptional + HasParamSpec> HasParamSpec for Option<T> {
20692080
type ParamSpec = T::ParamSpec;
20702081
type SetValue = T::SetValue;

glib/src/thread_guard.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{
44
mem, ptr,
55
sync::atomic::{AtomicUsize, Ordering},
66
};
7+
78
fn next_thread_id() -> usize {
89
static COUNTER: AtomicUsize = AtomicUsize::new(0);
910
COUNTER.fetch_add(1, Ordering::SeqCst)
@@ -111,4 +112,40 @@ impl<T> Drop for ThreadGuard<T> {
111112
}
112113
}
113114

115+
impl<T: Default> Default for ThreadGuard<T> {
116+
fn default() -> Self {
117+
Self::new(T::default())
118+
}
119+
}
120+
114121
unsafe impl<T> Send for ThreadGuard<T> {}
122+
123+
impl<T: crate::ToValue + crate::StaticType> crate::ToValue for ThreadGuard<T> {
124+
fn to_value(&self) -> crate::Value {
125+
T::to_value(self.get_ref())
126+
}
127+
128+
fn value_type(&self) -> crate::Type {
129+
T::static_type()
130+
}
131+
}
132+
133+
unsafe impl<'a, T, C, E> crate::value::FromValue<'a> for ThreadGuard<T>
134+
where
135+
T: crate::value::FromValue<'a, Checker = C> + crate::StaticType,
136+
C: crate::value::ValueTypeChecker<Error = crate::value::ValueTypeMismatchOrNoneError<E>>,
137+
E: std::error::Error + Send + Sized + 'static,
138+
{
139+
type Checker = crate::value::ValueTypeOrNoneChecker<T, C, E>;
140+
141+
unsafe fn from_value(value: &'a crate::Value) -> Self {
142+
match T::Checker::check(value) {
143+
Err(crate::value::ValueTypeMismatchOrNoneError::UnexpectedNone) => panic!(),
144+
Err(crate::value::ValueTypeMismatchOrNoneError::WrongValueType(_err)) => {
145+
// This should've been caught by the caller already.
146+
unreachable!();
147+
}
148+
Ok(_) => Self::new(T::from_value(value)),
149+
}
150+
}
151+
}

0 commit comments

Comments
 (0)