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

Commit d856438

Browse files
committed
Move signal creation functions into the types module
The same code will also work for interfaces.
1 parent 2063013 commit d856438

File tree

2 files changed

+102
-56
lines changed

2 files changed

+102
-56
lines changed

src/subclass/object.rs

Lines changed: 15 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::mem;
1212
use std::ptr;
1313

1414
use translate::*;
15-
use {Closure, Object, ObjectClass, Type, Value};
15+
use {Object, ObjectClass, Type, Value};
1616

1717
use super::prelude::*;
1818
use super::types;
@@ -177,19 +177,12 @@ pub unsafe trait ObjectClassSubclassExt: Sized + 'static {
177177
/// This can be emitted later by `glib::Object::emit` and external code
178178
/// can connect to the signal to get notified about emissions.
179179
fn add_signal(&mut self, name: &str, arg_types: &[Type], ret_type: Type) {
180-
let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::<Vec<_>>();
181180
unsafe {
182-
gobject_ffi::g_signal_newv(
183-
name.to_glib_none().0,
181+
super::types::add_signal(
184182
*(self as *mut _ as *mut ffi::GType),
185-
gobject_ffi::G_SIGNAL_RUN_LAST,
186-
ptr::null_mut(),
187-
None,
188-
ptr::null_mut(),
189-
None,
190-
ret_type.to_glib(),
191-
arg_types.len() as u32,
192-
arg_types.as_ptr() as *mut _,
183+
name,
184+
arg_types,
185+
ret_type,
193186
);
194187
}
195188
}
@@ -212,38 +205,13 @@ pub unsafe trait ObjectClassSubclassExt: Sized + 'static {
212205
) where
213206
F: Fn(&mut Value, &Value) -> bool + Send + Sync + 'static,
214207
{
215-
let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::<Vec<_>>();
216-
217-
let accumulator: Box<Box<Fn(&mut Value, &Value) -> bool + Send + Sync + 'static>> =
218-
Box::new(Box::new(accumulator));
219-
220-
unsafe extern "C" fn accumulator_trampoline(
221-
_ihint: *mut gobject_ffi::GSignalInvocationHint,
222-
return_accu: *mut gobject_ffi::GValue,
223-
handler_return: *const gobject_ffi::GValue,
224-
data: ffi::gpointer,
225-
) -> ffi::gboolean {
226-
let accumulator: &&(Fn(&mut Value, &Value) -> bool + Send + Sync + 'static) =
227-
&*(data as *const &(Fn(&mut Value, &Value) -> bool + Send + Sync + 'static));
228-
accumulator(
229-
&mut *(return_accu as *mut Value),
230-
&*(handler_return as *const Value),
231-
)
232-
.to_glib()
233-
}
234-
235208
unsafe {
236-
gobject_ffi::g_signal_newv(
237-
name.to_glib_none().0,
209+
super::types::add_signal_with_accumulator(
238210
*(self as *mut _ as *mut ffi::GType),
239-
gobject_ffi::G_SIGNAL_RUN_LAST,
240-
ptr::null_mut(),
241-
Some(accumulator_trampoline),
242-
Box::into_raw(accumulator) as ffi::gpointer,
243-
None,
244-
ret_type.to_glib(),
245-
arg_types.len() as u32,
246-
arg_types.as_ptr() as *mut _,
211+
name,
212+
arg_types,
213+
ret_type,
214+
accumulator,
247215
);
248216
}
249217
}
@@ -258,20 +226,13 @@ pub unsafe trait ObjectClassSubclassExt: Sized + 'static {
258226
where
259227
F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static,
260228
{
261-
let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::<Vec<_>>();
262-
let handler = Closure::new(handler);
263229
unsafe {
264-
gobject_ffi::g_signal_newv(
265-
name.to_glib_none().0,
230+
super::types::add_action_signal(
266231
*(self as *mut _ as *mut ffi::GType),
267-
gobject_ffi::G_SIGNAL_RUN_LAST | gobject_ffi::G_SIGNAL_ACTION,
268-
handler.to_glib_none().0,
269-
None,
270-
ptr::null_mut(),
271-
None,
272-
ret_type.to_glib(),
273-
arg_types.len() as u32,
274-
arg_types.as_ptr() as *mut _,
232+
name,
233+
arg_types,
234+
ret_type,
235+
handler,
275236
);
276237
}
277238
}

src/subclass/types.rs

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use std::marker;
1111
use std::mem;
1212
use std::ptr;
1313

14+
use object::{ObjectExt, ObjectType};
1415
use translate::*;
15-
use {IsA, IsClassFor, StaticType, Type};
16-
use object::{ObjectType, ObjectExt};
16+
use {Closure, IsA, IsClassFor, StaticType, Type, Value};
1717

1818
use super::object::ObjectImpl;
1919

@@ -484,3 +484,88 @@ where
484484
type_
485485
}
486486
}
487+
488+
pub(crate) unsafe fn add_signal(type_: ffi::GType, name: &str, arg_types: &[Type], ret_type: Type) {
489+
let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::<Vec<_>>();
490+
491+
gobject_ffi::g_signal_newv(
492+
name.to_glib_none().0,
493+
type_,
494+
gobject_ffi::G_SIGNAL_RUN_LAST,
495+
ptr::null_mut(),
496+
None,
497+
ptr::null_mut(),
498+
None,
499+
ret_type.to_glib(),
500+
arg_types.len() as u32,
501+
arg_types.as_ptr() as *mut _,
502+
);
503+
}
504+
505+
pub(crate) unsafe fn add_signal_with_accumulator<F>(
506+
type_: ffi::GType,
507+
name: &str,
508+
arg_types: &[Type],
509+
ret_type: Type,
510+
accumulator: F,
511+
) where
512+
F: Fn(&mut Value, &Value) -> bool + Send + Sync + 'static,
513+
{
514+
let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::<Vec<_>>();
515+
516+
let accumulator: Box<Box<Fn(&mut Value, &Value) -> bool + Send + Sync + 'static>> =
517+
Box::new(Box::new(accumulator));
518+
519+
unsafe extern "C" fn accumulator_trampoline(
520+
_ihint: *mut gobject_ffi::GSignalInvocationHint,
521+
return_accu: *mut gobject_ffi::GValue,
522+
handler_return: *const gobject_ffi::GValue,
523+
data: ffi::gpointer,
524+
) -> ffi::gboolean {
525+
let accumulator: &&(Fn(&mut Value, &Value) -> bool + Send + Sync + 'static) =
526+
&*(data as *const &(Fn(&mut Value, &Value) -> bool + Send + Sync + 'static));
527+
accumulator(
528+
&mut *(return_accu as *mut Value),
529+
&*(handler_return as *const Value),
530+
)
531+
.to_glib()
532+
}
533+
534+
gobject_ffi::g_signal_newv(
535+
name.to_glib_none().0,
536+
type_,
537+
gobject_ffi::G_SIGNAL_RUN_LAST,
538+
ptr::null_mut(),
539+
Some(accumulator_trampoline),
540+
Box::into_raw(accumulator) as ffi::gpointer,
541+
None,
542+
ret_type.to_glib(),
543+
arg_types.len() as u32,
544+
arg_types.as_ptr() as *mut _,
545+
);
546+
}
547+
pub(crate) unsafe fn add_action_signal<F>(
548+
type_: ffi::GType,
549+
name: &str,
550+
arg_types: &[Type],
551+
ret_type: Type,
552+
handler: F,
553+
) where
554+
F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static,
555+
{
556+
let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::<Vec<_>>();
557+
let handler = Closure::new(handler);
558+
559+
gobject_ffi::g_signal_newv(
560+
name.to_glib_none().0,
561+
type_,
562+
gobject_ffi::G_SIGNAL_RUN_LAST | gobject_ffi::G_SIGNAL_ACTION,
563+
handler.to_glib_none().0,
564+
None,
565+
ptr::null_mut(),
566+
None,
567+
ret_type.to_glib(),
568+
arg_types.len() as u32,
569+
arg_types.as_ptr() as *mut _,
570+
);
571+
}

0 commit comments

Comments
 (0)