Skip to content

Commit

Permalink
generalize support of dynamic objects to any TypePlugin subclass
Browse files Browse the repository at this point in the history
Signed-off-by: fbrouille <fbrouille@users.noreply.github.com>
  • Loading branch information
fbrouille committed Oct 18, 2023
1 parent 02194dc commit 22ab846
Show file tree
Hide file tree
Showing 21 changed files with 1,434 additions and 664 deletions.
1 change: 1 addition & 0 deletions glib-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "2.0", features = ["full"] }
proc-macro-crate = "2.0"
libc = "0.2"

[lib]
proc-macro = true
Expand Down
79 changes: 41 additions & 38 deletions glib-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,41 +646,43 @@ pub fn object_subclass(_attr: TokenStream, item: TokenStream) -> TokenStream {
}

/// Macro for boilerplate of [`ObjectSubclass`] implementations specific to
/// module types.
/// dynamic types.
///
/// A module type must be explicitly registered when a module is loaded (see
/// [`TypeModule`]).
/// Therefore, unlike for non module types a module type can be registered
/// A dynamic type must be explicitly registered when the system loads the
/// implementation (see [`TypePlugin`] and [`TypeModule`].
/// Therefore, unlike for static types a dynamic type can be registered
/// several times.
///
/// A module type is never unregistered but is marked as unloaded by the glib
/// type system when the module is unloaded (see [`TypeModuleExt::unuse`]).
/// Therefore, a module type marked as unloaded by the glib type system must be
/// registered again, when the module is reloaded.
/// A dynamic type is never unregistered. The system calls
/// [`TypePluginExt::unuse`] to unload the type's implementation. If the
/// plugin's implementation is a module, the dynamic type is marked as unloaded
/// and must be registered again, when the module is reloaded.
///
/// This macro provides two behaviors when registering a module type:
/// This macro provides two behaviors when registering a dynamic type:
///
/// By default the module type is registered when the module is loaded,
/// By default the dynamic type is registered when the system loads the
/// implementation (e.g. when the module is loaded)
/// ```ignore
/// #[glib::module_object_subclass]
/// #[glib::dynamic_object_subclass]
/// impl ObjectSubclass for MyType { ... }
/// ```
///
/// Optionally by setting the macro attribute to `lazy_registration = true` to
/// postpone the registration of the module type on first use (when `type_()`
/// Optionally setting the macro attribute to `lazy_registration = true`
/// postpones the registration of the dynamic type on first use (when `type_()`
/// is called for the first time), similarly to the [`macro@object_subclass`]
/// macro.
/// ```ignore
/// #[glib::module_object_subclass(lazy_registration = true)]
/// #[glib::dynamic_object_subclass(lazy_registration = true)]
/// impl ObjectSubclass for MyType { ... }
/// ```
///
/// [`ObjectSubclass`]: ../glib/subclass/types/trait.ObjectSubclass.html
/// [`TypeModule`]: ../glib/gobject/auto/type_module/struct.TypeModule.html
/// [`TypeModuleExt::unuse`]: ../glib/gobject/auto/type_module/trait.TypeModuleExt.html#method.unuse
/// [`TypePlugin`]: ../glib/gobject/type_plugin/struct.TypePlugin.html
/// [`TypeModule`]: ../glib/gobject/type_module/struct.TypeModule.html
/// [`TypePluginExt::unuse`]: ../glib/gobject/type_plugin/trait.TypePluginExt.html#method.unuse
#[proc_macro_attribute]
#[proc_macro_error]
pub fn module_object_subclass(attr: TokenStream, item: TokenStream) -> TokenStream {
pub fn dynamic_object_subclass(attr: TokenStream, item: TokenStream) -> TokenStream {
use proc_macro_error::abort_call_site;
let attr = if attr.is_empty() {
None
Expand All @@ -692,7 +694,7 @@ pub fn module_object_subclass(attr: TokenStream, item: TokenStream) -> TokenStre
};
match syn::parse::<syn::ItemImpl>(item) {
Ok(input) => {
object_subclass_attribute::impl_module_object_subclass(attr.as_ref(), &input).into()
object_subclass_attribute::impl_dynamic_object_subclass(attr.as_ref(), &input).into()
}
Err(_) => abort_call_site!(object_subclass_attribute::WRONG_PLACE_MSG),
}
Expand Down Expand Up @@ -724,42 +726,43 @@ pub fn object_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
}

/// Macro for boilerplate of [`ObjectInterface`] implementations specific to
/// module interfaces.
/// dynamic interfaces.
///
/// A module interface must be explicitly registered when a module is loaded
/// (see [`TypeModule`]).
/// A dynamic interface must be explicitly registered when the system loads the
/// implementation (see [`TypePlugin`] and [`TypeModule`].
/// Therefore, unlike for static interfaces a dynamic interface can be
/// registered several times.
///
/// A module interface is never unregistered but is marked as unloaded when the
/// module is unloaded (see [`TypeModuleExt::unuse`]). Therefore, a module
/// interface marked as unloaded must be registered again, when the module is
/// reloaded.
/// A dynamic interface is never unregistered. The system calls
/// [`TypePluginExt::unuse`] to unload the type's implementation. If the
/// plugin's implementation is a module, the dynamic interface is marked as
/// unloaded and must be registered again, when the module is reloaded.
///
/// Calling `type_()` will panic if the module is unloaded (the module
/// interface cannot be used).
/// This macro provides two behaviors when registering a dynamic interface:
///
/// This macro provides two behaviors when registering a module interface:
///
/// By default the module interface is registered when the module is loaded,
/// By default the dynamic interface is registered when the system loads the
/// implementation (e.g. when the module is loaded)
/// ```ignore
/// #[glib::module_object_interface]
/// #[glib::dynamic_object_interface]
/// unsafe impl ObjectInterface for MyInterface { ... }
/// ```
///
/// Optionally by setting the macro attribute to `lazy_registration = true` to
/// postpone the registration of the module interface on first use (when
/// Optionally setting the macro attribute to `lazy_registration = true`
/// postpones the registration of the dynamic interface on first use (when
/// `type_()` is called for the first time), similarly to the
/// [`macro@object_interface`] macro.
/// ```ignore
/// #[glib::module_object_interface(lazy_registration = true)]
/// #[glib::dynamic_object_interface(lazy_registration = true)]
/// unsafe impl ObjectInterface for MyInterface { ... }
/// ```
///
/// [`ObjectInterface`]: ../glib/subclass/interface/trait.ObjectInterface.html
/// [`TypeModule`]: ../glib/gobject/auto/type_module/struct.TypeModule.html
/// [`TypeModuleExt::unuse`]: ../glib/gobject/auto/type_module/trait.TypeModuleExt.html#method.unuse
/// [`TypePlugin`]: ../glib/gobject/type_plugin/struct.TypePlugin.html
/// [`TypeModule`]: ../glib/gobject/type_module/struct.TypeModule.html
/// [`TypePluginExt::unuse`]: ../glib/gobject/type_plugin/trait.TypePluginExt.html#method.unuse
#[proc_macro_attribute]
#[proc_macro_error]
pub fn module_object_interface(attr: TokenStream, item: TokenStream) -> TokenStream {
pub fn dynamic_object_interface(attr: TokenStream, item: TokenStream) -> TokenStream {
use proc_macro_error::abort_call_site;
let attr = if attr.is_empty() {
None
Expand All @@ -771,7 +774,7 @@ pub fn module_object_interface(attr: TokenStream, item: TokenStream) -> TokenStr
};
match syn::parse::<syn::ItemImpl>(item) {
Ok(input) => {
object_interface_attribute::impl_module_object_interface(attr.as_ref(), &input).into()
object_interface_attribute::impl_dynamic_object_interface(attr.as_ref(), &input).into()
}
Err(_) => abort_call_site!(object_interface_attribute::WRONG_PLACE_MSG),
}
Expand Down
Loading

0 comments on commit 22ab846

Please sign in to comment.