Skip to content

Commit 9d147b2

Browse files
Paolo Borellisdroege
Paolo Borelli
authored andcommitted
nameable: port to the latest gtk-rs-core GInterface changes
1 parent e15705e commit 9d147b2

File tree

2 files changed

+77
-41
lines changed

2 files changed

+77
-41
lines changed

src/nameable/imp.rs

+43-35
Original file line numberDiff line numberDiff line change
@@ -3,61 +3,65 @@ use glib::translate::*;
33

44
use std::ffi::c_char;
55

6-
// Instance struct
7-
pub struct Nameable;
6+
// Type implementing ObjectInterface. Use a uninhabited enum to make the type uninstantiatable.
7+
pub enum Nameable {}
88

9-
// Interface struct aka "vtable"
10-
//
11-
// Here we would store virtual methods and similar
12-
#[derive(Clone, Copy)]
13-
#[repr(C)]
14-
pub struct NameableInterface {
15-
pub parent_iface: glib::gobject_ffi::GTypeInterface,
16-
pub get_name: Option<unsafe extern "C" fn(*mut Nameable) -> *mut c_char>,
9+
// Default implementation of the interface methods (note: these are optional)
10+
impl Nameable {
11+
fn name_default() -> Option<String> {
12+
None
13+
}
1714
}
1815

1916
#[glib::object_interface]
20-
unsafe impl ObjectInterface for NameableInterface {
17+
impl ObjectInterface for Nameable {
2118
const NAME: &'static str = "ExNameable";
19+
type Instance = ffi::ExNameable;
20+
type Interface = ffi::ExNameableInterface;
2221
type Prerequisites = (glib::Object,);
2322

2423
// Interface struct initialization, called from GObject
25-
fn interface_init(&mut self) {
24+
fn interface_init(iface: &mut Self::Interface) {
25+
// Optionally set the default implementation
26+
iface.get_name = Some(get_name_default_trampoline);
27+
2628
// TODO: Could also add signals here, and interface properties via
2729
// g_object_interface_install_property()
28-
self.get_name = Some(get_name_default_trampoline);
2930
}
3031
}
3132

32-
//
33-
// Virtual method implementations / trampolines to safe implementations
34-
//
35-
// The default implementations are optional!
36-
//
37-
unsafe extern "C" fn get_name_default_trampoline(this: *mut Nameable) -> *mut c_char {
38-
NameableInterface::name_default(&from_glib_borrow(this)).to_glib_full()
39-
}
40-
41-
//
42-
// Safe implementations. These take the wrapper type, and not &Self, as first argument
43-
//
44-
impl NameableInterface {
45-
fn name_default(_this: &super::Nameable) -> Option<String> {
46-
None
47-
}
33+
// trampoline to safe implementation
34+
unsafe extern "C" fn get_name_default_trampoline(_this: *mut ffi::ExNameable) -> *mut c_char {
35+
Nameable::name_default().to_glib_full()
4836
}
4937

5038
pub(crate) mod ffi {
5139
use super::*;
40+
use glib::object::ObjectExt;
5241
use std::ffi::c_char;
5342
use std::ptr;
5443

55-
pub type ExNameable = super::Nameable;
56-
pub type ExNameableInterface = super::NameableInterface;
44+
// Instance struct, to be used as pointer to "self" in ffi methods
45+
#[repr(C)]
46+
pub struct ExNameable(std::ffi::c_void);
47+
48+
// Interface struct aka "vtable"
49+
//
50+
// Here we would store virtual methods and similar
51+
#[derive(Clone, Copy)]
52+
#[repr(C)]
53+
pub struct ExNameableInterface {
54+
pub parent_iface: glib::gobject_ffi::GTypeInterface,
55+
pub get_name: Option<unsafe extern "C" fn(*mut ExNameable) -> *mut c_char>,
56+
}
57+
58+
unsafe impl InterfaceStruct for ExNameableInterface {
59+
type Type = super::Nameable;
60+
}
5761

5862
#[no_mangle]
5963
pub extern "C" fn ex_nameable_get_type() -> glib::ffi::GType {
60-
<super::NameableInterface as ObjectInterfaceType>::type_().into_glib()
64+
<super::Nameable as ObjectInterfaceType>::type_().into_glib()
6165
}
6266

6367
// Virtual method callers
@@ -66,8 +70,12 @@ pub(crate) mod ffi {
6670
/// Must be a Nameable interface.
6771
#[no_mangle]
6872
pub unsafe extern "C" fn ex_nameable_get_name(this: *mut ExNameable) -> *mut c_char {
69-
let wrapper = super::super::from_glib_borrow::<_, super::super::Nameable>(this);
70-
let iface = <super::NameableInterface as ObjectInterfaceExt>::from_obj(&*wrapper);
71-
iface.get_name.map(|f| f(this)).unwrap_or(ptr::null_mut())
73+
let wrapper = from_glib_borrow::<_, super::super::Nameable>(this);
74+
let iface = wrapper.interface::<super::super::Nameable>().unwrap();
75+
iface
76+
.as_ref()
77+
.get_name
78+
.map(|f| f(this))
79+
.unwrap_or(ptr::null_mut())
7280
}
7381
}

src/nameable/mod.rs

+34-6
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,56 @@ mod ffi;
88

99
use glib::{prelude::*, subclass::prelude::*, translate::*};
1010

11+
#[cfg(feature = "bindings")]
1112
glib::wrapper! {
12-
pub struct Nameable(Interface<ffi::ExNameable, ffi::ExNameableInterface>);
13+
pub struct Nameable(Interface<ffi::Nameable, ffi::Interface>);
1314

1415
match fn {
1516
type_ => || ffi::ex_nameable_get_type(),
1617
}
1718
}
1819

19-
pub trait NameableExt {
20-
fn name(&self) -> Option<String>;
20+
#[cfg(not(feature = "bindings"))]
21+
glib::wrapper! {
22+
pub struct Nameable(ObjectInterface<imp::Nameable>);
2123
}
2224

23-
impl<O: IsA<Nameable>> NameableExt for O {
25+
pub trait NameableExt: IsA<Nameable> {
2426
fn name(&self) -> Option<String> {
25-
unsafe { from_glib_full(ffi::ex_nameable_get_name(self.as_ref().to_glib_none().0)) }
27+
let iface = self.interface::<Nameable>().unwrap();
28+
unsafe {
29+
from_glib_full(((iface.as_ref()).get_name.unwrap())(
30+
self.upcast_ref::<Nameable>().to_glib_none().0,
31+
))
32+
}
2633
}
2734
}
2835

36+
impl<O: IsA<Nameable>> NameableExt for O {}
37+
2938
pub trait NameableImpl: ObjectImpl {
30-
fn name(&self) -> Option<String>;
39+
fn name(&self) -> Option<String> {
40+
self.parent_name()
41+
}
3142
}
3243

44+
pub trait NameableImplExt: NameableImpl {
45+
fn parent_name(&self) -> Option<String> {
46+
let data = Self::type_data();
47+
let parent_iface = unsafe {
48+
&*(data.as_ref().parent_interface::<Nameable>() as *const ffi::ExNameableInterface)
49+
};
50+
51+
unsafe {
52+
from_glib_full((parent_iface.get_name.unwrap())(
53+
self.obj().unsafe_cast_ref::<Nameable>().to_glib_none().0,
54+
))
55+
}
56+
}
57+
}
58+
59+
impl<T: NameableImpl> NameableImplExt for T {}
60+
3361
unsafe impl<T: ObjectSubclass + NameableImpl> IsImplementable<T> for Nameable {
3462
fn interface_init(iface: &mut glib::Interface<Self>) {
3563
let iface = iface.as_mut();

0 commit comments

Comments
 (0)