Commit e1139c1a authored by Rico Tzschichholz's avatar Rico Tzschichholz

codegen: Add support for delegate parameters in signals

Fixes #205
parent 4aca8df6
......@@ -1063,6 +1063,16 @@ public class Vala.CCodeAttribute : AttributeCache {
}
return ret;
}
} else if (node is DelegateType) {
unowned DelegateType delegate_type = (DelegateType) node;
var ret = "POINTER";
if (delegate_type.delegate_symbol.has_target) {
ret = "%s,POINTER".printf (ret);
if (delegate_type.is_disposable ()) {
ret = "%s,POINTER".printf (ret);
}
}
return ret;
} else if (node is VoidType) {
return "VOID";
} else {
......
......@@ -71,6 +71,8 @@ public class Vala.GSignalModule : GObjectModule {
return "gint";
} else if (t is ArrayType) {
return "gpointer";
} else if (t is DelegateType) {
return "gpointer";
} else if (t is ErrorType) {
return "gpointer";
}
......@@ -199,6 +201,16 @@ public class Vala.GSignalModule : GObjectModule {
callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), length_ctype));
n_params++;
}
} else if (p.variable_type is DelegateType) {
unowned DelegateType delegate_type = (DelegateType) p.variable_type;
if (delegate_type.delegate_symbol.has_target) {
callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), get_ccode_name (delegate_target_type)));
n_params++;
if (delegate_type.is_disposable ()) {
callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), get_ccode_name (delegate_target_destroy_type)));
n_params++;
}
}
}
}
callback_decl.add_parameter (new CCodeParameter ("data2", "gpointer"));
......@@ -253,6 +265,8 @@ public class Vala.GSignalModule : GObjectModule {
} else {
get_value_function = "g_value_get_pointer";
}
} else if (p.variable_type is DelegateType) {
get_value_function = "g_value_get_pointer";
} else if (p.variable_type is PointerType || p.variable_type is GenericType) {
get_value_function = "g_value_get_pointer";
} else if (p.variable_type is ErrorType) {
......@@ -276,6 +290,20 @@ public class Vala.GSignalModule : GObjectModule {
fc.add_argument (inner_fc);
i++;
}
} else if (p.variable_type is DelegateType) {
unowned DelegateType delegate_type = (DelegateType) p.variable_type;
if (delegate_type.delegate_symbol.has_target) {
inner_fc = new CCodeFunctionCall (new CCodeIdentifier (get_value_function));
inner_fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("param_values"), new CCodeIdentifier (i.to_string ())));
fc.add_argument (inner_fc);
i++;
if (delegate_type.is_disposable ()) {
inner_fc = new CCodeFunctionCall (new CCodeIdentifier (get_value_function));
inner_fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("param_values"), new CCodeIdentifier (i.to_string ())));
fc.add_argument (inner_fc);
i++;
}
}
}
}
fc.add_argument (new CCodeIdentifier ("data2"));
......@@ -392,6 +420,14 @@ public class Vala.GSignalModule : GObjectModule {
params_len++;
if (param.variable_type is ArrayType) {
params_len += ((ArrayType) param.variable_type).rank;
} else if (param.variable_type is DelegateType) {
unowned DelegateType delegate_type = (DelegateType) param.variable_type;
if (delegate_type.delegate_symbol.has_target) {
params_len++;
if (delegate_type.is_disposable ()) {
params_len++;
}
}
}
}
......@@ -409,6 +445,15 @@ public class Vala.GSignalModule : GObjectModule {
for (var i = 0; i < array_type.rank; i++) {
csignew.add_argument (new CCodeConstant (length_type_id));
}
} else if (param.variable_type is DelegateType) {
unowned DelegateType delegate_type = (DelegateType) param.variable_type;
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
if (delegate_type.delegate_symbol.has_target) {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
if (delegate_type.is_disposable ()) {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
}
}
} else if (param.variable_type is PointerType || param.variable_type is GenericType || param.direction != ParameterDirection.IN) {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
} else if (param.variable_type is ErrorType) {
......
......@@ -268,6 +268,7 @@ TESTS = \
objects/regex.vala \
objects/signals.vala \
objects/signals-delegate.vala \
objects/signals-delegate-parameter.vala \
objects/singleton.vala \
objects/test-025.vala \
objects/test-026.vala \
......
delegate void FooFunc ();
[CCode (has_target = false)]
delegate void BarFunc ();
class Foo : Object {
public signal void delegate_param_no_target (BarFunc f);
public signal void delegate_param_with_target (FooFunc f);
public signal void delegate_param_with_destroy (owned FooFunc f);
}
void no_target_cb (BarFunc f) {
f ();
}
void with_target_cb (FooFunc f) {
f ();
}
void with_destroy_cb (owned FooFunc f) {
f ();
}
bool success1 = false;
class Bar : Object {
Foo foo;
bool success2 = false;
bool success3 = false;
public Bar () {
foo = new Foo ();
}
public void test_no_target () {
foo.delegate_param_no_target.connect (no_target_cb);
foo.delegate_param_no_target (() => {
success1 = true;
});
assert (success1);
}
public void test_with_target () {
foo.delegate_param_with_target.connect (with_target_cb);
foo.delegate_param_with_target (() => {
assert (this.ref_count == 1);
success2 = true;
});
assert (this.ref_count == 1);
assert (success2);
}
public void test_with_destroy () {
foo.delegate_param_with_destroy.connect (with_destroy_cb);
foo.delegate_param_with_destroy (() => {
assert (this.ref_count == 2);
success3 = true;
});
assert (this.ref_count == 1);
assert (success3);
}
}
void main () {
var bar = new Bar ();
bar.test_no_target ();
bar.test_with_target ();
bar.test_with_destroy ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment