@@ -3,61 +3,65 @@ use glib::translate::*;
3
3
4
4
use std:: ffi:: c_char;
5
5
6
- // Instance struct
7
- pub struct Nameable ;
6
+ // Type implementing ObjectInterface. Use a uninhabited enum to make the type uninstantiatable.
7
+ pub enum Nameable { }
8
8
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
+ }
17
14
}
18
15
19
16
#[ glib:: object_interface]
20
- unsafe impl ObjectInterface for NameableInterface {
17
+ impl ObjectInterface for Nameable {
21
18
const NAME : & ' static str = "ExNameable" ;
19
+ type Instance = ffi:: ExNameable ;
20
+ type Interface = ffi:: ExNameableInterface ;
22
21
type Prerequisites = ( glib:: Object , ) ;
23
22
24
23
// 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
+
26
28
// TODO: Could also add signals here, and interface properties via
27
29
// g_object_interface_install_property()
28
- self . get_name = Some ( get_name_default_trampoline) ;
29
30
}
30
31
}
31
32
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 ( )
48
36
}
49
37
50
38
pub ( crate ) mod ffi {
51
39
use super :: * ;
40
+ use glib:: object:: ObjectExt ;
52
41
use std:: ffi:: c_char;
53
42
use std:: ptr;
54
43
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
+ }
57
61
58
62
#[ no_mangle]
59
63
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 ( )
61
65
}
62
66
63
67
// Virtual method callers
@@ -66,8 +70,12 @@ pub(crate) mod ffi {
66
70
/// Must be a Nameable interface.
67
71
#[ no_mangle]
68
72
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 ( ) )
72
80
}
73
81
}
0 commit comments