Attribute Macro glib::object_subclass
source · #[object_subclass]
Expand description
Macro for boilerplate of ObjectSubclass
implementations.
This adds implementations for the type_data()
and type_()
methods,
which should probably never be defined differently.
It provides default values for the Instance
, Class
, and Interfaces
type parameters. If these are present, the macro will use the provided value
instead of the default.
Usually the defaults for Instance
and Class
will work. Interfaces
is
necessary for types that implement interfaces.
type Instance = glib::subclass::basic::InstanceStruct<Self>;
type Class = glib::subclass::basic::ClassStruct<Self>;
type Interfaces = ();
If no new()
or with_class()
method is provide, the macro adds a new()
implementation calling Default::default()
. So the type needs to implement
Default
, or this should be overridden.
fn new() -> Self {
Default::default()
}
An object subclass can be registered as a dynamic type by setting the macro
helper attribute object_class_dynamic
:
#[derive(Default)]
pub struct MyType;
#[glib::object_subclass]
#[object_subclass_dynamic]
impl ObjectSubclass for MyType { ... }
As a dynamic type, an object subclass must be explicitly registered when
the system loads the implementation (see TypePlugin
and TypeModule
.
Therefore, whereas an object subclass can be registered only once as a
static type, it can be registered several times as a dynamic type.
An object subclass registered as a dynamic type is never unregistered. The
system calls TypePluginExt::unuse
to unload the implementation. If the
TypePlugin
subclass is a TypeModule
, the object subclass registered
as a dynamic type is marked as unloaded and must be registered again when
the module is reloaded.
The macro helper attribute object_class_dynamic
provides two behaviors
when registering an object subclass as a dynamic type:
- lazy registration: by default an object subclass is registered as a
dynamic type when the system loads the implementation (e.g. when the module
is loaded). Optionally setting
lazy_registration
totrue
postpones registration on the first use (whenstatic_type()
is called for the first time):
#[derive(Default)]
pub struct MyType;
#[glib::object_subclass]
#[object_subclass_dynamic(lazy_registration = true)]
impl ObjectSubclass for MyType { ... }
- registration within
TypeModule
subclass or withinTypePlugin
subclass: an object subclass is usually registered as a dynamic type within aTypeModule
subclass:
#[derive(Default)]
pub struct MyModuleType;
#[glib::object_subclass]
#[object_subclass_dynamic]
impl ObjectSubclass for MyModuleType { ... }
...
#[derive(Default)]
pub struct MyModule;
...
impl TypeModuleImpl for MyModule {
fn load(&self) -> bool {
// registers object subclasses as dynamic types.
let my_module = self.obj();
let type_module: &glib::TypeModule = my_module.upcast_ref();
MyModuleType::on_implementation_load(type_module)
}
...
}
Optionally setting plugin_type
allows to register an object subclass as a
dynamic type within a TypePlugin
subclass that is not a TypeModule
:
#[derive(Default)]
pub struct MyPluginType;
#[glib::object_subclass]
#[object_subclass_dynamic(plugin_type = MyPlugin)]
impl ObjectSubclass for MyPluginType { ... }
...
#[derive(Default)]
pub struct MyPlugin;
...
impl TypePluginImpl for MyPlugin {
fn use_plugin(&self) {
// register object subclasses as dynamic types.
let my_plugin = self.obj();
MyPluginType::on_implementation_load(my_plugin.as_ref());
}
...
}