Skip to content

Commit e0d357c

Browse files
Allow immutable signals, and add one to qml_features
1 parent c6710b7 commit e0d357c

File tree

5 files changed

+29
-20
lines changed

5 files changed

+29
-20
lines changed

crates/cxx-qt-gen/src/generator/cpp/signal.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fn parameter_types_and_values(
5151
parameters: &[ParsedFunctionParameter],
5252
type_names: &TypeNames,
5353
self_ty: &Name,
54+
mutable: bool,
5455
) -> Result<Parameters> {
5556
let mut parameter_named_types_with_self = vec![];
5657
let mut parameter_types_with_self = vec![];
@@ -66,10 +67,11 @@ fn parameter_types_and_values(
6667

6768
let parameter_named_types = parameter_named_types_with_self.join(", ");
6869

70+
let is_const = if !mutable { " const" } else { "" };
6971
// Insert the extra argument into the closure
7072
let self_ty = self_ty.cxx_qualified();
71-
parameter_named_types_with_self.insert(0, format!("{self_ty}& self"));
72-
parameter_types_with_self.insert(0, format!("{self_ty}&"));
73+
parameter_named_types_with_self.insert(0, format!("{self_ty}{is_const}& self"));
74+
parameter_types_with_self.insert(0, format!("{self_ty}{is_const}&"));
7375
parameter_values_with_self.insert(0, "self".to_owned());
7476

7577
Ok(Parameters {
@@ -109,7 +111,8 @@ pub fn generate_cpp_signal(
109111
let free_connect_ident_cpp = idents_helper.connect_name.cxx_unqualified();
110112

111113
// Retrieve the parameters for the signal
112-
let parameters = parameter_types_and_values(&signal.parameters, type_names, qobject_name)?;
114+
let parameters =
115+
parameter_types_and_values(&signal.parameters, type_names, qobject_name, signal.mutable)?;
113116
let parameters_named_types = parameters.named_types;
114117
let parameters_named_types_with_self = parameters.named_types_with_self;
115118
let parameter_types_with_self = parameters.types_with_self;
@@ -121,6 +124,8 @@ pub fn generate_cpp_signal(
121124
let signal_handler_call = idents_helper.function_call;
122125
let signal_handler_drop = idents_helper.function_drop;
123126
let namespace = idents_helper.namespace;
127+
let reference_type = if !signal.mutable { " const &" } else { "&" };
128+
let is_const = if !signal.mutable { " const" } else { "" };
124129

125130
let signal_handler_type = format!("SignalHandler<::{namespace}::{param_struct} *>");
126131

@@ -135,7 +140,7 @@ pub fn generate_cpp_signal(
135140
// Generate the Q_SIGNAL if this is not an existing signal
136141
if !signal.inherit {
137142
generated.methods.push(CppFragment::Header(format!(
138-
"Q_SIGNAL void {signal_ident}({parameters_named_types});"
143+
"Q_SIGNAL void {signal_ident}({parameters_named_types}){is_const};"
139144
)));
140145
}
141146

@@ -144,7 +149,7 @@ pub fn generate_cpp_signal(
144149
r#"
145150
namespace {namespace} {{
146151
::QMetaObject::Connection
147-
{free_connect_ident_cpp}({qobject_ident_namespaced}& self, {signal_handler_alias_namespaced} closure, ::Qt::ConnectionType type);
152+
{free_connect_ident_cpp}({qobject_ident_namespaced}{reference_type} self, {signal_handler_alias_namespaced} closure, ::Qt::ConnectionType type);
148153
}} // namespace {namespace}
149154
"#
150155
},
@@ -177,7 +182,7 @@ pub fn generate_cpp_signal(
177182
178183
namespace {namespace} {{
179184
::QMetaObject::Connection
180-
{free_connect_ident_cpp}({qobject_ident_namespaced}& self, {signal_handler_alias_namespaced} closure, ::Qt::ConnectionType type)
185+
{free_connect_ident_cpp}({qobject_ident_namespaced}{reference_type} self, {signal_handler_alias_namespaced} closure, ::Qt::ConnectionType type)
181186
{{
182187
return ::QObject::connect(
183188
&self,

crates/cxx-qt-gen/src/generator/rust/signals.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,10 @@ pub fn generate_rust_signal(
8585
let self_type_cxx = if signal.mutable {
8686
parse_quote_spanned! {span => Pin<&mut #qobject_name_rust> }
8787
} else {
88-
// CODECOV_EXCLUDE_START
89-
unreachable!("Signals cannot be immutable right now so this cannot be reached")
90-
// CODECOV_EXCLUDE_STOP
88+
// // CODECOV_EXCLUDE_START
89+
// unreachable!("Signals cannot be immutable right now so this cannot be reached")
90+
// // CODECOV_EXCLUDE_STOP
91+
parse_quote_spanned! {span => &#qobject_name_rust }
9192
};
9293
let self_type_qualified = syn_type_cxx_bridge_to_qualified(&self_type_cxx, type_names)?;
9394
let qualified_impl = qobject_name.rust_qualified();

crates/cxx-qt-gen/src/parser/signals.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,13 @@ impl ParsedSignal {
4242
let fields = MethodFields::parse(method, auto_case)?;
4343
let attrs = require_attributes(&fields.method.attrs, &Self::ALLOWED_ATTRS)?;
4444

45-
if !fields.mutable {
46-
return Err(Error::new(
47-
fields.method.span(),
48-
"signals must be mutable, use Pin<&mut T> instead of T for the self type",
49-
));
50-
}
45+
// TODO: add proper checks
46+
// if !fields.mutable {
47+
// return Err(Error::new(
48+
// fields.method.span(),
49+
// "signals must be mutable, use Pin<&mut T> instead of T for the self type",
50+
// ));
51+
// }
5152

5253
let inherit = attrs.contains_key("inherit");
5354

@@ -96,17 +97,13 @@ mod tests {
9697
assert_parse_errors! {
9798
|input| ParsedSignal::parse(input, CaseConversion::none()) =>
9899

99-
// No immutable signals
100-
{ fn ready(self: &MyObject); }
100+
// No namespaces
101101
{
102-
// No namespaces
103102
#[namespace = "disallowed_namespace"]
104103
fn ready(self: Pin<&mut MyObject>);
105104
}
106105
// Missing self
107106
{ fn ready(x: f64); }
108-
// Self needs to be receiver like self: &T instead of &self
109-
{ fn ready(&self); }
110107
}
111108
}
112109

examples/qml_features/cpp/external_qobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ class ExternalQObject : public QObject
2222
Q_SIGNALS:
2323
void triggered();
2424
void triggeredPrivateSignal(QPrivateSignal);
25+
void triggeredConstSignal() const;
2526
};

examples/qml_features/rust/src/externcxxqt.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ pub mod ffi {
2222
#[qsignal]
2323
fn triggered(self: Pin<&mut Self>);
2424

25+
/// const signal that is emitted when trigger is fired
26+
#[qsignal]
27+
#[rust_name = "triggered_const_signal"]
28+
fn triggeredConstSignal(&self);
29+
2530
/// Private signal that is emitted when trigger is fired
2631
#[qsignal]
2732
#[rust_name = "triggered_private_signal"]

0 commit comments

Comments
 (0)