Commit d4997ba6 authored by mredlek's avatar mredlek

WIP: Support owned types, such as ::glib::Variant

parent dd215fa0
...@@ -19,7 +19,7 @@ libc = "0.2" ...@@ -19,7 +19,7 @@ libc = "0.2"
proc-macro2 = {version = "0.4.8",features = ["nightly"]} proc-macro2 = {version = "0.4.8",features = ["nightly"]}
quote = { version="0.6" } quote = { version="0.6" }
rustfmt = "0.10.0" rustfmt = "0.10.0"
syn = { version="0.14", features=["full"] } syn = { version="0.14", features=["full", "extra-traits"] }
unicode-xid = "0.0.4" unicode-xid = "0.0.4"
[dev-dependencies] [dev-dependencies]
......
...@@ -127,14 +127,9 @@ impl<'ast> ToTokens for ToGlibType<'ast> { ...@@ -127,14 +127,9 @@ impl<'ast> ToTokens for ToGlibType<'ast> {
}).to_tokens(tokens); }).to_tokens(tokens);
} }
Ty::Integer(ref i) => i.to_tokens(tokens), Ty::Integer(ref i) => i.to_tokens(tokens),
Ty::Owned(_) => { Ty::Owned(ref t) => {
Diagnostic::spanned(
self.0.span().unstable(),
Level::Error,
"unimplemented glib type for owned types",
).emit();
(quote! { (quote! {
() <#t as GlibPtrDefault>::GlibType
}).to_tokens(tokens); }).to_tokens(tokens);
} }
} }
...@@ -160,14 +155,9 @@ impl<'ast, T: ToTokens> ToTokens for ToGlib<'ast, T> { ...@@ -160,14 +155,9 @@ impl<'ast, T: ToTokens> ToTokens for ToGlib<'ast, T> {
<#t as ToGlibPtr<_>>::to_glib_none(#expr).0 <#t as ToGlibPtr<_>>::to_glib_none(#expr).0
}).to_tokens(tokens); }).to_tokens(tokens);
} }
Ty::Owned(_) => { Ty::Owned(ref t) => {
Diagnostic::spanned(
self.0.span().unstable(),
Level::Error,
"unimplemented glib type for owned types",
).emit();
(quote! { (quote! {
() <#t as ToGlibPtr<_>>::to_glib_full(&#expr)
}).to_tokens(tokens); }).to_tokens(tokens);
} }
} }
...@@ -178,38 +168,21 @@ struct FromGlib<'ast>(&'ast Ty<'ast>, TokenStream); ...@@ -178,38 +168,21 @@ struct FromGlib<'ast>(&'ast Ty<'ast>, TokenStream);
impl<'ast> ToTokens for FromGlib<'ast> { impl<'ast> ToTokens for FromGlib<'ast> {
fn to_tokens(&self, tokens: &mut TokenStream) { fn to_tokens(&self, tokens: &mut TokenStream) {
let needs_conversion = match *self.0 { match self {
Ty::Unit => false, // no conversion necessary FromGlib(Ty::Unit, inner) => { inner.to_tokens(tokens); }, // no conversion necessary
Ty::Char(ref i) | Ty::Bool(ref i) => { FromGlib(Ty::Char(ref i), inner) | FromGlib(Ty::Bool(ref i), inner) => {
(quote! { tokens.extend(quote! {
<#i as FromGlib<_>>::from_glib <#i as FromGlib<_>>::from_glib(#inner)
}).to_tokens(tokens); }) },
true FromGlib(Ty::Borrowed(ref t), inner) => {
} tokens.extend(quote! {
Ty::Borrowed(ref t) => { &<#t as FromGlibPtrBorrow<_>>::from_glib_borrow(#inner)
(quote! { }) },
&<#t as FromGlibPtrBorrow<_>>::from_glib_borrow FromGlib(Ty::Integer(_), inner) => inner.to_tokens(tokens), // no conversion necessary
}).to_tokens(tokens); FromGlib(Ty::Owned(t), inner) => {
true tokens.extend(quote! {
} unsafe { <#t as FromGlibPtrFull<_>>::from_glib_full(#inner) }
Ty::Integer(_) => false, // no conversion necessary }); }
Ty::Owned(_) => {
Diagnostic::spanned(
self.0.span().unstable(),
Level::Error,
"unimplemented glib type for owned types",
).emit();
false
}
};
if needs_conversion {
tokens.append(TokenTree::Group(Group::new(
Delimiter::Parenthesis,
self.1.clone(),
)));
} else {
self.1.to_tokens(tokens);
} }
} }
} }
......
...@@ -732,10 +732,9 @@ impl<'a> ToTokens for FnArg<'a> { ...@@ -732,10 +732,9 @@ impl<'a> ToTokens for FnArg<'a> {
impl<'a> ToTokens for Ty<'a> { impl<'a> ToTokens for Ty<'a> {
fn to_tokens(&self, tokens: &mut TokenStream) { fn to_tokens(&self, tokens: &mut TokenStream) {
match *self { match *self {
Ty::Unit => tokens.append(TokenTree::Group(Group::new( Ty::Unit => tokens.extend(
Delimiter::Parenthesis, quote!{ () },
quote!{ () }.into(), ),
))),
Ty::Char(ref tok) => tok.to_tokens(tokens), Ty::Char(ref tok) => tok.to_tokens(tokens),
Ty::Bool(ref tok) => tok.to_tokens(tokens), Ty::Bool(ref tok) => tok.to_tokens(tokens),
Ty::Integer(ref t) => t.to_tokens(tokens), Ty::Integer(ref t) => t.to_tokens(tokens),
......
#![deny(warnings)]
#![feature(proc_macro_non_items, proc_macro_gen)]
extern crate gobject_gen;
#[macro_use]
extern crate glib;
#[allow(dead_code)]
use gobject_gen::gobject_gen;
use std::cell::RefCell;
gobject_gen! {
class Counter2 {
f: RefCell<Option<::glib::Variant>>,
}
impl Counter2 {
pub fn set(&self, x: ::glib::Variant) {
self.get_priv().f.replace(Some(x));
}
pub fn get(&self) -> ::glib::Variant {
self.get_priv().f.borrow().clone().unwrap_or(0.into())
}
}
}
/********************************************************************************/
/*pub mod CounterMod {
# ! [ allow ( non_snake_case ) ] extern crate glib_sys as glib_ffi ;
extern
crate gobject_sys as gobject_ffi ;
extern crate glib ;
use glib::IsA;
#[allow(unused_imports)]
use glib::object::Downcast;
use glib::translate::*;
use std::mem;
use std::ptr;
#[allow(unused_imports)]
use super::*;
glib_wrapper ! {
pub struct Counter ( Object < imp :: CounterFfi , imp :: CounterClass > ) ;
match fn { get_type => || imp :: counter_get_type ( ) , } }
pub mod imp {
#[allow(unused_imports)]
use super::super::*;
use super::glib;
use super::glib_ffi;
use super::gobject_ffi;
use std::mem;
use std::ptr;
#[allow(unused_imports)]
use glib::translate::*;
#[allow(unused_imports)]
use std::ffi::CString;
#[repr(C)]
pub struct CounterFfi {
pub parent: <glib::Object as glib::wrapper::Wrapper>::GlibType,
}
#[repr(C)]
pub struct CounterClass {
pub parent_class: <glib::Object as glib::wrapper::Wrapper>::GlibClassType,
}
struct CounterClassPrivate {
parent_class: *const <glib::Object as glib::wrapper::Wrapper>::GlibClassType,
properties: *const Vec<*const gobject_ffi::GParamSpec>,
}
static mut PRIV: CounterClassPrivate = CounterClassPrivate {
parent_class: 0 as *const _,
properties: 0 as *const _,
};
#[derive(Default)]
struct CounterPriv {
f: RefCell<Option<::glib::Variant>>,
}
impl super::Counter {
#[allow(dead_code)]
fn get_priv(&self) -> &CounterPriv {
unsafe {
let _private = gobject_ffi::g_type_instance_get_private(
<Self as ToGlibPtr<*mut CounterFfi>>::to_glib_none(self).0 as
*mut gobject_ffi::GTypeInstance,
counter_get_type(),
) as *const Option<CounterPriv>;
(&*_private).as_ref().unwrap()
}
}
fn set_impl(&self, x: ::glib::Variant) -> () {
self.get_priv().f.replace(Some(x));
}
fn get_impl(&self) -> ::glib::Variant {
self.get_priv().f.borrow().clone().unwrap_or(0.into())
}
#[allow(dead_code, unused_variables)]
fn set_property_impl(&self, property_id: u32, value: *mut gobject_ffi::GValue) {
match property_id {
_ => {}
}
}
#[allow(dead_code, unused_variables)]
fn get_property_impl(&self, property_id: u32, value: *mut gobject_ffi::GValue) {
match property_id {
_ => {}
}
}
}
impl CounterFfi {
#[allow(dead_code)]
fn get_vtable(&self) -> &CounterClass {
unsafe {
let klass = (*(self as *const _ as *const gobject_ffi::GTypeInstance)).g_class;
&*(klass as *const CounterClass)
}
}
unsafe extern "C" fn init(
obj: *mut gobject_ffi::GTypeInstance,
_klass: glib_ffi::gpointer,
) {
# [ allow ( unused_variables ) ] let obj = obj; # [ allow ( deprecated ) ]
let _guard = glib::CallbackGuard::new();
let _private =
gobject_ffi::g_type_instance_get_private(obj, counter_get_type()) as
*mut Option<CounterPriv>;
ptr::write(_private, Some(<CounterPriv as Default>::default()));
}
unsafe extern "C" fn finalize(obj: *mut gobject_ffi::GObject) {
# [ allow ( deprecated ) ] let _guard = glib::CallbackGuard::new();
let _private = gobject_ffi::g_type_instance_get_private(
obj as *mut gobject_ffi::GTypeInstance,
counter_get_type(),
) as *mut Option<CounterPriv>;
let _ = (*_private).take();
(*(PRIV.parent_class as *mut gobject_ffi::GObjectClass))
.finalize
.map(|f| f(obj));
}
unsafe extern "C" fn set_property(
obj: *mut gobject_ffi::GObject,
property_id: u32,
value: *mut gobject_ffi::GValue,
_pspec: *mut gobject_ffi::GParamSpec,
) {
# [ allow ( deprecated ) ] let _guard = glib::CallbackGuard::new();
let this: &Counter = &Counter::from_glib_borrow(obj as *mut CounterFfi);
this.set_property_impl(property_id, value);
}
unsafe extern "C" fn get_property(
obj: *mut gobject_ffi::GObject,
property_id: u32,
value: *mut gobject_ffi::GValue,
_pspec: *mut gobject_ffi::GParamSpec,
) {
# [ allow ( deprecated ) ] let _guard = glib::CallbackGuard::new();
let this: &Counter = &Counter::from_glib_borrow(obj as *mut CounterFfi);
this.get_property_impl(property_id, value);
}
}
impl CounterClass {
unsafe extern "C" fn init(vtable: glib_ffi::gpointer, _klass_data: glib_ffi::gpointer) {
# [ allow ( deprecated ) ] let _guard = glib::CallbackGuard::new();
gobject_ffi::g_type_class_add_private(
vtable,
mem::size_of::<Option<CounterPriv>>(),
);
{
let gobject_class = &mut *(vtable as *mut gobject_ffi::GObjectClass);
gobject_class.finalize = Some(CounterFfi::finalize);
gobject_class.set_property = Some(CounterFfi::set_property);
gobject_class.get_property = Some(CounterFfi::get_property);
let mut properties = Vec::new();
properties.push(ptr::null());
if properties.len() > 1 {
gobject_ffi::g_object_class_install_properties(
gobject_class,
properties.len() as u32,
properties.as_mut_ptr() as *mut *mut _,
);
}
PRIV.properties = Box::into_raw(Box::new(properties));
}
{
# [ allow ( unused_variables ) ] let vtable = &mut *(vtable as *mut CounterClass);
}
{}
PRIV.parent_class = gobject_ffi::g_type_class_peek_parent(vtable) as
*const <glib::Object as glib::wrapper::Wrapper>::GlibClassType;
}
}
#[no_mangle]
pub unsafe extern "C" fn counter_new() -> *mut CounterFfi {
# [ allow ( deprecated ) ] let _guard = glib::CallbackGuard::new();
let this = gobject_ffi::g_object_newv(counter_get_type(), 0, ptr::null_mut());
this as *mut CounterFfi
}
#[no_mangle]
pub unsafe extern "C" fn counter_set(
this: *mut CounterFfi,
x: <::glib::Variant as GlibPtrDefault>::GlibType,
) -> () {
# [ allow ( deprecated ) ] let _guard = glib::CallbackGuard::new();
let instance: &super::Counter = &from_glib_borrow(this);
instance.set_impl(unsafe {
<::glib::Variant as FromGlibPtrFull<_>>::from_glib_full(x)
})
}
#[no_mangle]
pub unsafe extern "C" fn counter_get(
this: *mut CounterFfi,
) -> <::glib::Variant as GlibPtrDefault>::GlibType {
# [ allow ( deprecated ) ] let _guard = glib::CallbackGuard::new();
let instance: &super::Counter = &from_glib_borrow(this);
<::glib::Variant as ToGlibPtr<_>>::to_glib_full(&instance.get_impl())
}
#[no_mangle]
pub unsafe extern "C" fn counter_get_type() -> glib_ffi::GType {
# [ allow ( deprecated ) ] let _guard = glib::CallbackGuard::new();
use std::sync::{Once, ONCE_INIT};
use std::u16;
static mut TYPE: glib_ffi::GType = gobject_ffi::G_TYPE_INVALID;
static ONCE: Once = ONCE_INIT;
ONCE.call_once(|| {
let class_size = mem::size_of::<CounterClass>();
assert!(class_size <= u16::MAX as usize);
let instance_size = mem::size_of::<CounterFfi>();
assert!(instance_size <= u16::MAX as usize);
TYPE = gobject_ffi::g_type_register_static_simple(
<glib::Object as glib::StaticType>::static_type().to_glib(),
b"Counter\x00" as *const u8 as *const i8,
class_size as u32,
Some(CounterClass::init),
instance_size as u32,
Some(CounterFfi::init),
gobject_ffi::GTypeFlags::empty(),
);
});
TYPE
}
}
impl Counter {
pub fn new() -> Counter {
unsafe { from_glib_full(imp::counter_new()) }
}
}
pub trait CounterExt {
fn set(&self, x: ::glib::Variant) -> ();
fn get(&self) -> ::glib::Variant;
}
impl<O: IsA<Counter> + IsA<glib::object::Object> + glib::object::ObjectExt> CounterExt for O {
fn set(&self, x: ::glib::Variant) -> () {
unsafe {
imp::counter_set(
self.to_glib_none().0,
<::glib::Variant as ToGlibPtr<_>>::to_glib_full(&x),
)
}
}
fn get(&self) -> ::glib::Variant {
unsafe {
<::glib::Variant as FromGlibPtrFull<_>>::from_glib_full(
unsafe { imp::counter_get(self.to_glib_none().0) },
)
}
}
}
}
pub use CounterMod::*;
*/
#[test]
fn test_variant() {
let c: Counter2 = Counter2::new();
println!("Counter has value: {:?}", c.get().get::<u32>());
c.set(10u32.into());
assert_eq!(c.get().get::<u32>(), Some(10u32));
println!("Counter has value: {:?}", c.get().get::<u32>());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment