Skip to content

Commit

Permalink
Add IsA<Object> trait bound to Impl traits
Browse files Browse the repository at this point in the history
  • Loading branch information
felinira committed Sep 29, 2024
1 parent cbdbf60 commit d997c25
Show file tree
Hide file tree
Showing 23 changed files with 348 additions and 62 deletions.
11 changes: 9 additions & 2 deletions examples/virtual_methods/cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,14 @@ impl Default for Cat {
///
/// By convention we still create an empty `CatImpl` trait, this allows us to add
/// 'protected' cat methods only available to be called by other Cats later.
pub trait CatImpl: PetImpl {}
pub trait CatImpl: PetImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
{
}

/// To make this class subclassable we need to implement IsSubclassable
unsafe impl<Obj: CatImpl + PetImpl> IsSubclassable<Obj> for Cat {}
unsafe impl<Obj: CatImpl + PetImpl> IsSubclassable<Obj> for Cat where
<Obj as ObjectSubclass>::Type: IsA<glib::Object>
{
}
17 changes: 13 additions & 4 deletions examples/virtual_methods/pet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ pub trait PetExt: IsA<Pet> {
impl<T: IsA<Pet>> PetExt for T {}

/// The `PetImpl` trait contains overridable virtual function definitions for [`Pet`] objects.
pub trait PetImpl: ObjectImpl {
pub trait PetImpl: ObjectImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
{
/// Default implementation of a virtual method.
///
/// This always calls into the implementation of the parent class so that if
Expand All @@ -148,7 +151,10 @@ pub trait PetImpl: ObjectImpl {
/// The `PetImplExt` trait contains non-overridable methods for subclasses to use.
///
/// These are supposed to be called only from inside implementations of `Pet` subclasses.
pub trait PetImplExt: PetImpl {
pub trait PetImplExt: PetImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
{
/// Chains up to the parent implementation of [`PetImpl::pet`]
fn parent_pet(&self) -> bool {
let data = Self::type_data();
Expand All @@ -169,10 +175,13 @@ pub trait PetImplExt: PetImpl {
}

/// The `PetImplExt` trait is implemented for all subclasses that have [`Pet`] in the class hierarchy
impl<T: PetImpl> PetImplExt for T {}
impl<T: PetImpl> PetImplExt for T where <Self as ObjectSubclass>::Type: IsA<glib::Object> {}

/// To make this class subclassable we need to implement IsSubclassable
unsafe impl<Obj: PetImpl> IsSubclassable<Obj> for Pet {
unsafe impl<Obj: PetImpl> IsSubclassable<Obj> for Pet
where
<Obj as ObjectSubclass>::Type: IsA<glib::Object>,
{
/// Override the virtual method function pointers in subclasses to call directly into the
/// `PetImpl` of the subclass.
///
Expand Down
17 changes: 13 additions & 4 deletions examples/virtual_methods/purrable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ pub trait PurrableExt: IsA<Purrable> {
impl<T: IsA<Purrable>> PurrableExt for T {}

/// The `PurrableImpl` trait contains virtual function definitions for [`Purrable`] objects.
pub trait PurrableImpl: ObjectImpl {
pub trait PurrableImpl: ObjectImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
{
/// Return the current purring status.
///
/// The default implementation chains up to the parent implementation,
Expand All @@ -96,7 +99,10 @@ pub trait PurrableImpl: ObjectImpl {
/// The `PurrableImplExt` trait contains non-overridable methods for subclasses to use.
///
/// These are supposed to be called only from inside implementations of `Pet` subclasses.
pub trait PurrableImplExt: PurrableImpl {
pub trait PurrableImplExt: PurrableImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
{
/// Chains up to the parent implementation of [`PurrableExt::is_purring`]
fn parent_is_purring(&self) -> bool {
let data = Self::type_data();
Expand All @@ -109,10 +115,13 @@ pub trait PurrableImplExt: PurrableImpl {
}

/// The `PurrableImplExt` trait is implemented for all classes that implement [`Purrable`].
impl<T: PurrableImpl> PurrableImplExt for T {}
impl<T: PurrableImpl> PurrableImplExt for T where <T as ObjectSubclass>::Type: IsA<glib::Object> {}

/// To make this interface implementable we need to implement [`IsImplementable`]
unsafe impl<Obj: PurrableImpl> IsImplementable<Obj> for Purrable {
unsafe impl<Obj: PurrableImpl> IsImplementable<Obj> for Purrable
where
<Obj as ObjectSubclass>::Type: IsA<glib::Object>,
{
fn interface_init(iface: &mut glib::Interface<Self>) {
let klass = iface.as_mut();

Expand Down
13 changes: 11 additions & 2 deletions gdk-pixbuf/src/subclass/pixbuf_animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{ffi, Pixbuf, PixbufAnimation, PixbufAnimationIter};

pub trait PixbufAnimationImpl: ObjectImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
<Self as ObjectSubclass>::Type: IsA<PixbufAnimation>,
{
fn is_static_image(&self) -> bool {
Expand All @@ -36,6 +37,7 @@ where

pub trait PixbufAnimationImplExt: ObjectSubclass + PixbufAnimationImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
<Self as ObjectSubclass>::Type: IsA<PixbufAnimation>,
{
fn parent_is_static_image(&self) -> bool {
Expand Down Expand Up @@ -117,13 +119,16 @@ where
}
}

impl<T: PixbufAnimationImpl> PixbufAnimationImplExt for T where
<Self as ObjectSubclass>::Type: IsA<PixbufAnimation>
impl<T: PixbufAnimationImpl> PixbufAnimationImplExt for T
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimation>,
{
}

unsafe impl<T: PixbufAnimationImpl> IsSubclassable<T> for PixbufAnimation
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimation>,
{
fn class_init(class: &mut ::glib::Class<Self>) {
Expand All @@ -141,6 +146,7 @@ unsafe extern "C" fn animation_is_static_image<T: PixbufAnimationImpl>(
ptr: *mut ffi::GdkPixbufAnimation,
) -> glib::ffi::gboolean
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimation>,
{
let instance = &*(ptr as *mut T::Instance);
Expand All @@ -154,6 +160,7 @@ unsafe extern "C" fn animation_get_size<T: PixbufAnimationImpl>(
width_ptr: *mut libc::c_int,
height_ptr: *mut libc::c_int,
) where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimation>,
{
if width_ptr.is_null() && height_ptr.is_null() {
Expand All @@ -176,6 +183,7 @@ unsafe extern "C" fn animation_get_static_image<T: PixbufAnimationImpl>(
ptr: *mut ffi::GdkPixbufAnimation,
) -> *mut ffi::GdkPixbuf
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimation>,
{
let instance = &*(ptr as *mut T::Instance);
Expand Down Expand Up @@ -209,6 +217,7 @@ unsafe extern "C" fn animation_get_iter<T: PixbufAnimationImpl>(
start_time_ptr: *const glib::ffi::GTimeVal,
) -> *mut ffi::GdkPixbufAnimationIter
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimation>,
{
let instance = &*(ptr as *mut T::Instance);
Expand Down
13 changes: 11 additions & 2 deletions gdk-pixbuf/src/subclass/pixbuf_animation_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{ffi, Pixbuf, PixbufAnimationIter};

pub trait PixbufAnimationIterImpl: ObjectImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
<Self as ObjectSubclass>::Type: IsA<PixbufAnimationIter>,
{
// rustdoc-stripper-ignore-next
Expand All @@ -37,6 +38,7 @@ where

pub trait PixbufAnimationIterImplExt: ObjectSubclass + PixbufAnimationIterImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
<Self as ObjectSubclass>::Type: IsA<PixbufAnimationIter>,
{
fn parent_delay_time(&self) -> Option<Duration> {
Expand Down Expand Up @@ -122,13 +124,16 @@ where
}
}

impl<T: PixbufAnimationIterImpl> PixbufAnimationIterImplExt for T where
<T as ObjectSubclass>::Type: IsA<PixbufAnimationIter>
impl<T: PixbufAnimationIterImpl> PixbufAnimationIterImplExt for T
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimationIter>,
{
}

unsafe impl<T: PixbufAnimationIterImpl> IsSubclassable<T> for PixbufAnimationIter
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimationIter>,
{
fn class_init(class: &mut ::glib::Class<Self>) {
Expand All @@ -146,6 +151,7 @@ unsafe extern "C" fn animation_iter_get_delay_time<T: PixbufAnimationIterImpl>(
ptr: *mut ffi::GdkPixbufAnimationIter,
) -> i32
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimationIter>,
{
let instance = &*(ptr as *mut T::Instance);
Expand All @@ -158,6 +164,7 @@ unsafe extern "C" fn animation_iter_get_pixbuf<T: PixbufAnimationIterImpl>(
ptr: *mut ffi::GdkPixbufAnimationIter,
) -> *mut ffi::GdkPixbuf
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimationIter>,
{
let instance = &*(ptr as *mut T::Instance);
Expand All @@ -177,6 +184,7 @@ unsafe extern "C" fn animation_iter_on_currently_loading_frame<T: PixbufAnimatio
ptr: *mut ffi::GdkPixbufAnimationIter,
) -> glib::ffi::gboolean
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimationIter>,
{
let instance = &*(ptr as *mut T::Instance);
Expand All @@ -190,6 +198,7 @@ unsafe extern "C" fn animation_iter_advance<T: PixbufAnimationIterImpl>(
current_time_ptr: *const glib::ffi::GTimeVal,
) -> glib::ffi::gboolean
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufAnimationIter>,
{
let instance = &*(ptr as *mut T::Instance);
Expand Down
13 changes: 11 additions & 2 deletions gdk-pixbuf/src/subclass/pixbuf_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{ffi, PixbufLoader};

pub trait PixbufLoaderImpl: ObjectImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
<Self as ObjectSubclass>::Type: IsA<PixbufLoader>,
{
fn size_prepared(&self, width: i32, height: i32) {
Expand All @@ -30,6 +31,7 @@ where

pub trait PixbufLoaderImplExt: ObjectSubclass + PixbufLoaderImpl
where
<Self as ObjectSubclass>::Type: IsA<glib::Object>,
<Self as ObjectSubclass>::Type: IsA<PixbufLoader>,
{
fn parent_size_prepared(&self, width: i32, height: i32) {
Expand Down Expand Up @@ -97,13 +99,16 @@ where
}
}

impl<T: PixbufLoaderImpl> PixbufLoaderImplExt for T where
<T as ObjectSubclass>::Type: IsA<PixbufLoader>
impl<T: PixbufLoaderImpl> PixbufLoaderImplExt for T
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufLoader>,
{
}

unsafe impl<T: PixbufLoaderImpl> IsSubclassable<T> for PixbufLoader
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufLoader>,
{
fn class_init(class: &mut ::glib::Class<Self>) {
Expand All @@ -122,6 +127,7 @@ unsafe extern "C" fn loader_size_prepared<T: PixbufLoaderImpl>(
width: i32,
height: i32,
) where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufLoader>,
{
let instance = &*(ptr as *mut T::Instance);
Expand All @@ -132,6 +138,7 @@ unsafe extern "C" fn loader_size_prepared<T: PixbufLoaderImpl>(

unsafe extern "C" fn loader_area_prepared<T: PixbufLoaderImpl>(ptr: *mut ffi::GdkPixbufLoader)
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufLoader>,
{
let instance = &*(ptr as *mut T::Instance);
Expand All @@ -147,6 +154,7 @@ unsafe extern "C" fn loader_area_updated<T: PixbufLoaderImpl>(
width: i32,
height: i32,
) where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufLoader>,
{
let instance = &*(ptr as *mut T::Instance);
Expand All @@ -157,6 +165,7 @@ unsafe extern "C" fn loader_area_updated<T: PixbufLoaderImpl>(

unsafe extern "C" fn loader_closed<T: PixbufLoaderImpl>(ptr: *mut ffi::GdkPixbufLoader)
where
<T as ObjectSubclass>::Type: IsA<glib::Object>,
<T as ObjectSubclass>::Type: IsA<PixbufLoader>,
{
let instance = &*(ptr as *mut T::Instance);
Expand Down
Loading

0 comments on commit d997c25

Please sign in to comment.