Skip to content
This repository has been archived by the owner on Jun 8, 2021. It is now read-only.

Allow specifying class struct to glib_wrapper!() macro #234

Merged
merged 3 commits into from
Nov 6, 2017

Conversation

federicomenaquintero
Copy link
Contributor

This goes along with gtk-rs/gir#459

I'm not 100% sure if this works yet, as my gtk module doesn't build (but glib builds). Consider it as a proof of concept for now.

This is an API break for users of the glib_wrapper!() macro.

Now in the Wrapper trait we keep two associated types:

pub trait Wrapper {
    type GlibType: 'static;
    type GlibClassType: 'static;   // new one
}

This keeps the types of the instance struct and the class struct
together, so we can access them as needed.  We will need to access
both in the code generator for GObject boilerplate.

This is for gtk-rs#233
As before, we can have

    pub struct Foo(Object<ffi::Foo>);

in the macro call; this now means that there is no class struct
available.  To specify class structs,

    pub struct Foo(Object<ffi::Foo, ffi::FooClass>);
src/wrapper.rs Outdated
/// #### Non-derivable classes
///
/// By convention, GObject implements "final" classes, i.e. those who cannot
/// be subclassed, by exposing a public Instance struct, but no corresponding
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the instance struct could also be opaquely defined (i.e. only a pointer typedef in the public header, with the actual struct definition hidden). This is not a problem though and handled

We now have examples of each use case.
@EPashkin
Copy link
Member

While this PR still not uses GlibClassType I vote for merge it as is to fix block for future regens.
@GuillaumeGomez, @sdroege what you think about it?

@sdroege
Copy link
Member

sdroege commented Sep 22, 2017

I would like it if there was a commit that makes glib_wrapper! also emit code like the following

#[repr(C)]
pub struct FooClass(ffi::BarFooClass);

impl IsA<ParentOfFooClass> for FooClass { }
impl IsA<ParentOfParentParentOfFooClass> for FooClass { }

impl Foo {
    pub fn get_class(&self) -> &FooClass {
        unsafe {
            let stash = self.to_glib_none();
            let ptr: ffi::Foo = stash.0;
            let class = *(ptr as *const *const ffi::BarFooClass);
            &*(class as *const FooClass)
        }
}

This would lead the way to having immutable class methods later (g_object_class_list_properties(), gst_element_class_get_pad_template(), etc). Same for mutable ones (to be called in class_init / base_init) would be something that could be added too then, but would only be useful for myself and the gnome-class macro :)

@EPashkin
Copy link
Member

Good idea

@federicomenaquintero
Copy link
Contributor Author

Could we get this merged and postpone Sebastian's idea until we decide on the following?

As far as I can tell, generating pub struct FooClass requires something like the concat_idents!() macro, which is a nightly-only feature.

It may be possible to also have an internal procedural macro inside glib-rs itself that generates the FooClass identifier.

This is a bit more work than I'd like to put in just right now... maybe we can do this during the hackfest in Berlin?

@EPashkin
Copy link
Member

EPashkin commented Nov 6, 2017

👍 for merge this and related gir's PR as is.
This will need full Regen again, but all CI IMHO will pass.

@GuillaumeGomez
Copy link
Member

Fine by me. Thanks!

@federicomenaquintero
Copy link
Contributor Author

Thank you!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants