public CCodeStruct param_spec_struct;
public CCodeStruct closure_struct;
public CCodeEnum prop_enum;
+ public CCodeEnum signal_enum;
public CCodeFunction ccode { get { return emit_context.ccode; } }
return new CCodeFunctionCall (new CCodeIdentifier (""));
}
- public virtual CCodeFunctionCall get_signal_creation (Signal sig, TypeSymbol type) {
+ public virtual CCodeExpression get_signal_creation (Signal sig, TypeSymbol type) {
return new CCodeFunctionCall (new CCodeIdentifier (""));
}
return get_cvalue_ (detail_value);
}
+ private CCodeExpression get_signal_id_cexpression (Signal sig) {
+ var cl = (TypeSymbol) sig.parent_symbol;
+ var signal_array = new CCodeIdentifier ("%s_signals".printf (get_ccode_lower_case_name (cl)));
+ var signal_enum_value = new CCodeIdentifier ("%s_%s_SIGNAL".printf (get_ccode_upper_case_name (cl), sig.name.ascii_up ()));
+
+ return new CCodeElementAccess (signal_array, signal_enum_value);
+ }
+
+ private CCodeExpression? get_detail_cexpression (Expression detail_expr, CodeNode node) {
+ if (detail_expr.value_type is NullType || !detail_expr.value_type.compatible (string_type)) {
+ node.error = true;
+ Report.error (detail_expr.source_reference, "only string details are supported");
+ return null;
+ }
+
+ var detail_cexpr = get_cvalue (detail_expr);
+ CCodeFunctionCall detail_ccall;
+ if (is_constant_ccode_expression (detail_cexpr)) {
+ detail_ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
+ } else {
+ detail_ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
+ }
+ detail_ccall.add_argument (detail_cexpr);
+
+ return detail_ccall;
+ }
+
public override void visit_signal (Signal sig) {
// parent_symbol may be null for dynamic signals
}
}
+ signal_enum.add_value (new CCodeEnumValue ("%s_%s_SIGNAL".printf (get_ccode_upper_case_name ((TypeSymbol)sig.parent_symbol), sig.name.ascii_up ())));
+
sig.accept_children (this);
// declare parameter type
user_marshal_set.add (signature);
}
- public override CCodeFunctionCall get_signal_creation (Signal sig, TypeSymbol type) {
+ public override CCodeExpression get_signal_creation (Signal sig, TypeSymbol type) {
var csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new"));
csignew.add_argument (new CCodeConstant ("\"%s\"".printf (get_ccode_name (sig))));
csignew.add_argument (new CCodeIdentifier (get_ccode_type_id (type)));
marshal_arg.name = marshaller;
- return csignew;
+ return new CCodeAssignment (get_signal_id_cexpression (sig), csignew);
}
public override void visit_element_access (ElementAccess expr) {
var ma = (MemberAccess) expr.container;
var detail_expr = expr.get_indices ().get (0);
- var signal_name_cexpr = get_signal_name_cexpression (sig, detail_expr, expr);
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
- ccall.add_argument (get_cvalue (ma.inner));
- if (signal_name_cexpr != null) {
- ccall.add_argument (signal_name_cexpr);
+
+ CCodeFunctionCall ccall;
+ if (!sig.external_package && expr.source_reference.file == sig.source_reference.file) {
+ var detail_cexpr = get_detail_cexpression (detail_expr, expr);
+
+ ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit"));
+ ccall.add_argument (get_cvalue (ma.inner));
+ ccall.add_argument (get_signal_id_cexpression (sig));
+ if (detail_cexpr != null) {
+ ccall.add_argument (detail_cexpr);
+ }
+ } else {
+ var signal_name_cexpr = get_signal_name_cexpression (sig, detail_expr, expr);
+
+ ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
+ ccall.add_argument (get_cvalue (ma.inner));
+ if (signal_name_cexpr != null) {
+ ccall.add_argument (signal_name_cexpr);
+ }
}
+
set_cvalue (expr, ccall);
} else {
// signal connect or disconnect
return;
}
- if (get_signal_has_emitter (sig)) {
+ if (!sig.external_package && expr.source_reference.file == sig.source_reference.file) {
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit"));
+ ccall.add_argument (pub_inst);
+ ccall.add_argument (get_signal_id_cexpression (sig));
+ ccall.add_argument (new CCodeConstant ("0"));
+
+ set_cvalue (expr, ccall);
+ } else if (get_signal_has_emitter (sig)) {
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (get_ccode_lower_case_name (cl), sig.name)));
ccall.add_argument (pub_inst);
var old_param_spec_struct = param_spec_struct;
var old_prop_enum = prop_enum;
+ var old_signal_enum = signal_enum;
var old_class_init_context = class_init_context;
var old_base_init_context = base_init_context;
var old_class_finalize_context = class_finalize_context;
prop_enum = new CCodeEnum ();
prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (get_ccode_upper_case_name (cl, null))));
+ signal_enum = new CCodeEnum ();
class_init_context = new EmitContext (cl);
base_init_context = new EmitContext (cl);
class_finalize_context = new EmitContext (cl);
pop_context ();
}
+ if (cl.get_signals ().size > 0) {
+ var last_signal = "%s_LAST_SIGNAL".printf (get_ccode_upper_case_name (cl));
+ signal_enum.add_value (new CCodeEnumValue (last_signal));
+ cfile.add_type_declaration (signal_enum);
+
+ var signal_array_decl = new CCodeDeclaration ("guint");
+ signal_array_decl.modifiers |= CCodeModifiers.STATIC;
+ signal_array_decl.add_declarator (new CCodeVariableDeclarator ("%s_signals".printf (get_ccode_lower_case_name (cl)), new CCodeConstant ("{0}"), new CCodeDeclaratorSuffix.with_array (new CCodeIdentifier (last_signal))));
+ cfile.add_type_declaration (signal_array_decl);
+ }
+
if (cl.class_constructor != null) {
add_base_init_function (cl);
param_spec_struct = old_param_spec_struct;
prop_enum = old_prop_enum;
+ signal_enum = old_signal_enum;
class_init_context = old_class_init_context;
base_init_context = old_base_init_context;
class_finalize_context = old_class_finalize_context;
push_context (new EmitContext (iface));
push_line (iface.source_reference);
+ var old_signal_enum = signal_enum;
+
if (get_ccode_name (iface).length < 3) {
iface.error = true;
Report.error (iface.source_reference, "Interface name `%s' is too short".printf (get_ccode_name (iface)));
return;
}
+ signal_enum = new CCodeEnum ();
+
generate_interface_declaration (iface, cfile);
if (!iface.is_internal_symbol ()) {
generate_interface_declaration (iface, header_file);
iface.accept_children (this);
+ if (iface.get_signals ().size > 0) {
+ var last_signal = "%s_LAST_SIGNAL".printf (get_ccode_upper_case_name (iface));
+ signal_enum.add_value (new CCodeEnumValue (last_signal));
+ cfile.add_type_declaration (signal_enum);
+
+ var signal_array_decl = new CCodeDeclaration ("guint");
+ signal_array_decl.modifiers |= CCodeModifiers.STATIC;
+ signal_array_decl.add_declarator (new CCodeVariableDeclarator ("%s_signals".printf (get_ccode_lower_case_name (iface)), new CCodeConstant ("{0}"), new CCodeDeclaratorSuffix.with_array (new CCodeIdentifier (last_signal))));
+ cfile.add_type_declaration (signal_array_decl);
+ }
+
add_interface_base_init_function (iface);
if (iface.comment != null) {
cfile.add_type_member_declaration (type_fun.get_source_declaration ());
cfile.add_type_member_definition (type_fun.get_definition ());
+ signal_enum = old_signal_enum;
+
pop_line ();
pop_context ();
}
objects/bug641418-1.test \
objects/bug641418-2.test \
objects/bug641418-3.test \
+ objects/bug641828.vala \
objects/bug642809.vala \
objects/bug643711.vala \
objects/bug646362.vala \
--- /dev/null
+public interface Bar : GLib.Object {
+ public signal int bar (int i);
+}
+
+public class Foo : GLib.Object, Bar {
+}
+
+void main () {
+ var f = new Foo ();
+
+ f.bar.connect (i => i + 12);
+
+ var res = f.bar (30);
+ assert (res == 42);
+}