[vala] Support connect_after for signals
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] Support connect_after for signals
- Date: Sat, 13 Mar 2010 17:19:58 +0000 (UTC)
commit d06d284ac8d73024e5d46fedad07c512447d2484
Author: Luca Bruno <lethalman88 gmail com>
Date: Sat Jan 16 19:05:33 2010 +0100
Support connect_after for signals
Fixes bug 560773.
codegen/valaccodemodule.vala | 4 ++++
codegen/valagobjectmodule.vala | 38 ++++++++++++++++++++++++++++++++++----
codegen/valagsignalmodule.vala | 29 ++++++++++++++++++++---------
vala/valasignaltype.vala | 15 +++++++++++++++
4 files changed, 73 insertions(+), 13 deletions(-)
---
diff --git a/codegen/valaccodemodule.vala b/codegen/valaccodemodule.vala
index 2fee6b9..ebbc298 100644
--- a/codegen/valaccodemodule.vala
+++ b/codegen/valaccodemodule.vala
@@ -375,6 +375,10 @@ public abstract class Vala.CCodeModule {
return next.get_dynamic_signal_connect_wrapper_name (node);
}
+ public virtual string get_dynamic_signal_connect_after_wrapper_name (DynamicSignal node) {
+ return next.get_dynamic_signal_connect_after_wrapper_name (node);
+ }
+
public virtual string get_dynamic_signal_disconnect_wrapper_name (DynamicSignal node) {
return next.get_dynamic_signal_disconnect_wrapper_name (node);
}
diff --git a/codegen/valagobjectmodule.vala b/codegen/valagobjectmodule.vala
index 388ef59..6290a68 100644
--- a/codegen/valagobjectmodule.vala
+++ b/codegen/valagobjectmodule.vala
@@ -626,7 +626,7 @@ internal class Vala.GObjectModule : GTypeModule {
func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
var block = new CCodeBlock ();
- generate_gobject_connect_wrapper (sig, block);
+ generate_gobject_connect_wrapper (sig, block, false);
// append to C source file
source_declarations.add_type_member_declaration (func.copy ());
@@ -637,14 +637,41 @@ internal class Vala.GObjectModule : GTypeModule {
return connect_wrapper_name;
}
- void generate_gobject_connect_wrapper (DynamicSignal sig, CCodeBlock block) {
+ public override string get_dynamic_signal_connect_after_wrapper_name (DynamicSignal sig) {
+ if (sig.dynamic_type.data_type == null
+ || !sig.dynamic_type.data_type.is_subtype_of (gobject_type)) {
+ return base.get_dynamic_signal_connect_wrapper_name (sig);
+ }
+
+ string connect_wrapper_name = "_%sconnect_after".printf (get_dynamic_signal_cname (sig));
+ var func = new CCodeFunction (connect_wrapper_name, "void");
+ func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
+ func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
+ func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
+ func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
+ var block = new CCodeBlock ();
+ generate_gobject_connect_wrapper (sig, block, true);
+
+ // append to C source file
+ source_declarations.add_type_member_declaration (func.copy ());
+
+ func.block = block;
+ source_type_member_definition.append (func);
+
+ return connect_wrapper_name;
+ }
+
+ void generate_gobject_connect_wrapper (DynamicSignal sig, CCodeBlock block, bool after) {
var m = (Method) sig.handler.symbol_reference;
sig.accept (codegen);
string connect_func = "g_signal_connect_object";
if (m.binding != MemberBinding.INSTANCE) {
- connect_func = "g_signal_connect";
+ if (!after)
+ connect_func = "g_signal_connect";
+ else
+ connect_func = "g_signal_connect_after";
}
var call = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
@@ -654,7 +681,10 @@ internal class Vala.GObjectModule : GTypeModule {
call.add_argument (new CCodeIdentifier ("data"));
if (m.binding == MemberBinding.INSTANCE) {
- call.add_argument (new CCodeConstant ("0"));
+ if (!after)
+ call.add_argument (new CCodeConstant ("0"));
+ else
+ call.add_argument (new CCodeConstant ("G_CONNECT_AFTER"));
}
block.add_statement (new CCodeExpressionStatement (call));
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index 390cece..593f0ce 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -474,7 +474,7 @@ internal class Vala.GSignalModule : GObjectModule {
return null;
}
- return connect_signal (sig, assignment.left, assignment.right, disconnect, assignment);
+ return connect_signal (sig, assignment.left, assignment.right, disconnect, false, assignment);
}
public override void visit_assignment (Assignment assignment) {
@@ -550,11 +550,12 @@ internal class Vala.GSignalModule : GObjectModule {
handler.accept (codegen);
bool disconnect = (method_type.method_symbol.name == "disconnect");
+ bool after = (method_type.method_symbol.name == "connect_after");
- expr.ccodenode = connect_signal (sig, signal_access, handler, disconnect, expr);
+ expr.ccodenode = connect_signal (sig, signal_access, handler, disconnect, after, expr);
}
- CCodeExpression? connect_signal (Signal sig, Expression signal_access, Expression handler, bool disconnect, CodeNode expr) {
+ CCodeExpression? connect_signal (Signal sig, Expression signal_access, Expression handler, bool disconnect, bool after, CodeNode expr) {
string connect_func;
var m = (Method) handler.symbol_reference;
@@ -562,15 +563,19 @@ internal class Vala.GSignalModule : GObjectModule {
if (!disconnect) {
// connect
if (sig is DynamicSignal) {
- connect_func = head.get_dynamic_signal_connect_wrapper_name ((DynamicSignal) sig);
+ if (!after)
+ connect_func = head.get_dynamic_signal_connect_wrapper_name ((DynamicSignal) sig);
+ else
+ connect_func = head.get_dynamic_signal_connect_after_wrapper_name ((DynamicSignal) sig);
} else {
if (m.closure) {
connect_func = "g_signal_connect_data";
} else if (in_gobject_instance (m)) {
connect_func = "g_signal_connect_object";
- } else {
+ } else if (!after) {
connect_func = "g_signal_connect";
- }
+ } else
+ connect_func = "g_signal_connect_after";
}
} else {
// disconnect
@@ -669,7 +674,10 @@ internal class Vala.GSignalModule : GObjectModule {
ccall.add_argument (new CCodeCastExpression (handler_destroy_notify, "GClosureNotify"));
// sixth argument: connect_flags
- ccall.add_argument (new CCodeConstant ("0"));
+ if (!after)
+ ccall.add_argument (new CCodeConstant ("0"));
+ else
+ ccall.add_argument (new CCodeConstant ("G_CONNECT_AFTER"));
} else if (m.binding == MemberBinding.INSTANCE) {
// g_signal_connect_object or g_signal_handlers_disconnect_matched
// or dynamic_signal_connect or dynamic_signal_disconnect
@@ -690,10 +698,13 @@ internal class Vala.GSignalModule : GObjectModule {
// g_signal_connect_object
// fifth argument: connect_flags
- ccall.add_argument (new CCodeConstant ("0"));
+ if (!after)
+ ccall.add_argument (new CCodeConstant ("0"));
+ else
+ ccall.add_argument (new CCodeConstant ("G_CONNECT_AFTER"));
}
} else {
- // g_signal_connect or g_signal_handlers_disconnect_matched
+ // g_signal_connect or g_signal_connect_after or g_signal_handlers_disconnect_matched
// or dynamic_signal_connect or dynamic_signal_disconnect
// fourth resp. seventh argument: user_data
diff --git a/vala/valasignaltype.vala b/vala/valasignaltype.vala
index 851011c..11a1109 100644
--- a/vala/valasignaltype.vala
+++ b/vala/valasignaltype.vala
@@ -29,6 +29,7 @@ public class Vala.SignalType : DataType {
public Signal signal_symbol { get; set; }
Method? connect_method;
+ Method? connect_after_method;
Method? disconnect_method;
public SignalType (Signal signal_symbol) {
@@ -78,6 +79,18 @@ public class Vala.SignalType : DataType {
return connect_method;
}
+ Method get_connect_after_method () {
+ if (connect_after_method == null) {
+ var ulong_type = new IntegerType ((Struct) CodeContext.get ().root.scope.lookup ("ulong"));
+ connect_after_method = new Method ("connect_after", ulong_type);
+ connect_after_method.access = SymbolAccessibility.PUBLIC;
+ connect_after_method.external = true;
+ connect_after_method.owner = signal_symbol.scope;
+ connect_after_method.add_parameter (new FormalParameter ("handler", get_handler_type ()));
+ }
+ return connect_after_method;
+ }
+
Method get_disconnect_method () {
if (disconnect_method == null) {
disconnect_method = new Method ("disconnect", new VoidType ());
@@ -92,6 +105,8 @@ public class Vala.SignalType : DataType {
public override Symbol? get_member (string member_name) {
if (member_name == "connect") {
return get_connect_method ();
+ } else if (member_name == "connect_after") {
+ return get_connect_after_method ();
} else if (member_name == "disconnect") {
return get_disconnect_method ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]